198
Centro de Estudios de Postgrado UNIVERSIDAD DE JAÉN Centro de Estudios de Postgrado Trabajo Fin de Máster TECNICAS GEOMÁTICAS Y MODELADO PROCEDURAL PARA LA GENERACIÓN DE MODELOS URBANOS EN 3D Alumno/a: De la Torre Morales, Antonio Tutores: Prof. D. Jorge Delgado García Prof. D. Juan Roberto Jiménez Pérez Dpto: Centro de estudios de postgrado Diciembre, 2015

Diciembre , 2015 - tauja.ujaen.estauja.ujaen.es/bitstream/10953.1/2742/1/MemoriaTFM_AntonioDela... · 29 de octubre, por el que se establece la ordenación de las enseñanzas universitarias

  • Upload
    voquynh

  • View
    214

  • Download
    0

Embed Size (px)

Citation preview

Ce

ntr

o d

e E

stu

dio

s d

e P

ostg

rad

o

UNIVERSIDAD DE JAÉN Centro de Estudios de Postgrado

Trabajo Fin de Máster

TECNICAS GEOMÁTICAS

Y MODELADO

PROCEDURAL PARA LA

GENERACIÓN DE

MODELOS URBANOS EN

3D

Alumno/a: De la Torre Morales, Antonio Tutores: Prof. D. Jorge Delgado García Prof. D. Juan Roberto Jiménez Pérez Dpto: Centro de estudios de postgrado

Diciembre, 2015

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

2

Universidad de Jaén

Centro de Estudios de Postgrado

Don Jorge Delgado García y Don Juan Roberto Jiménez Pérez, tutores del Trabajo

de Fin de Master titulado: Técnicas Geomáticas y Modelado Procedural para la

Generación de Modelos Urbanos 3D, que presenta Antonio de la Torre Morales,

autorizan su presentación para defensa y evaluación en el Centro de Estudios de

Postgrado.

Jaén, Diciembre de 2015

El alumno: Los tutores:

Antonio de la Torre Morales Jorge Delgado García Juan Roberto Jiménez Pérez

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

3

Resumen

En el presente trabajo de fin de máster se abordan diferentes técnicas

geoespaciales que se emplean actualmente en la captura de información geográfica

así como su empleo junto al modelado procedural para generar modelos urbanos

inteligentes en 3D, los cuales tienen diversas aplicaciones y serán clave en el

desarrollo de las "Smart Cities".

Abstract

This Master´s dissertation board different geospatial technologies that are used

nowadays in the capture of geographical information as well as his employment

together with the procedural modelling to generate urban intelligent models in 3D,

which have diverse applications and they will be key in the development of the "Smart

Cities”.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

4

Índice 1. Introducción .................................................................................................................... 8

1.1. Justificación ............................................................................................................ 8

1.2. Objetivos ................................................................................................................10

1.3. Estructura ...............................................................................................................11

1.4. Antecedentes .........................................................................................................12

2. Metodología ..................................................................................................................17

2.1. Introducción ...........................................................................................................17

2.2. Obtención de los datos ...........................................................................................18

2.2.1. Mediante fotogrametría ...................................................................................18

2.2.2. Mediante LiDAR ..............................................................................................24

2.3. Preparación de los datos ........................................................................................35

2.4. Generación del modelo. Modelado procedural .......................................................41

2.5. Aplicación de los modelos urbanos 3D ...................................................................49

3. Aplicación de la Metodología .........................................................................................53

3.1. Zona de estudio .....................................................................................................53

3.2. Instrumentación y software empleado ....................................................................54

3.3. Desarrollo metodológico .........................................................................................55

3.3.1. Obtención de los datos ....................................................................................55

3.3.2. Preparación de los datos .................................................................................59

3.3.3. Modelado de la ciudad en 3D ..........................................................................75

3.3.4. Aplicación del Modelo. Análisis solar ...............................................................93

4. Conclusiones ............................................................................................................... 104

5. Bibliografía .................................................................................................................. 105

6. Anexos ........................................................................................................................ 107

6.1. Código empleado para generar los edificios ......................................................... 107

6.2. Código empleado para generar las calles ............................................................ 108

6.3. Código empleado para generar los árboles .......................................................... 178

6.4. Código empleado para generar el edificio nuevo .................................................. 191

7. Mapas ......................................................................................................................... 195

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

5

Índice de figuras

Figura 2-1. Método indirecto para obtener la ortofoto ...........................................................20

Figura 2-2. Proceso para llevar a cabo la rectificación..........................................................21

Figura 2-3. Escaneado de la superficie terrestre mediante lidar ...........................................24

Figura 2-4. Tiempo de viaje de láser ....................................................................................25

Figura 2-5. La amplitud del pulso recibido decrece ...............................................................25

Figura 2-6. Sistema de posicionamiento del Lidar ................................................................26

Figura 2-7. Componentes del sistema lidar ..........................................................................27

Figura 2-8. Recubrimientos en el vuelo lidar .........................................................................29

Figura 2-9. Pasadas del vuelo lidar ......................................................................................29

Figura 2-10. Trayectoria seguida ..........................................................................................30

Figura 2-11. Formato del archivo LAS ..................................................................................31

Figura 2-12. Clasificación estándar de los puntos ................................................................31

Figura 2-13. Ajuste de pasadas ............................................................................................32

Figura 2-14. Puntos de paso ................................................................................................33

Figura 2-15. División en bloques ..........................................................................................33

Figura 2-16. Modelo digital de superficie ..............................................................................34

Figura 2-17. Modelo digital del terreno .................................................................................35

Figura 2-18. Izq.: Ortoimagen convencional; Dcha.: Ortoimagen verdadera .........................36

Figura 2-19. Proyección ortogonal ........................................................................................37

Figura 2-20. Áreas ocultas en proyección ortogonal .............................................................38

Figura 2-21. Izquierda.- Ortofoto convencional (existen zonas ocultas). Centro - Paso

intermedio (se aprecia el efecto fantasma). Derecha - Orto verdadera ya corregida (áreas

ocultas rellenas con información de ortos adyacentes). ........................................................39

Figura 2-22. Pasos para la generación un modelo urbano ...................................................42

Figura 2-23. Reconstrucción del Eixample de Barcelona a partir de datos catastrales .........44

Figura 2-24. Modelo sintético de estructura urbana. Mapa de patrones con region radial,

orgánica y regular. Generación del modelo correspondiente. ...............................................45

Figura 2-25. Estructura urbana tipo Manhattan ....................................................................46

Figura 2-26. Estructura urbana tipo Barcelona .....................................................................46

Figura 2-27. Grafo que representa un conjunto de reglas procedurales y el resultado final del

edificio ..................................................................................................................................48

Figura 2-28. Edificio obtenido a partir de 3 edificios procedurales diferentes. .......................48

Figura 2-29. Modelo urbano procedural con nivel de detalle utilizando un criterio de distancia

a partir de la esfera roja ........................................................................................................49

Figura 2-30. Modelización de una fuente de emisión de ruido usando datos CityGML en 3D

.............................................................................................................................................50

Figura 2-31. Mapa de ruido generado a partir de datos CityGML .........................................51

Figura 2-32. Atlas económico de Berlín ................................................................................52

Figura 2-33. Atlas solar de Berlín ........................................................................................53

Figura 3-1. Zona elegida a modelar ......................................................................................54

Figura 3-2. Web del IGN .......................................................................................................56

Figura 3-3. Ortofoto PNOA ...................................................................................................57

Figura 3-4. Datos Lidar .........................................................................................................58

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

6

Figura 3-5. MDT del IGN ......................................................................................................58

Figura 3-6. Sede electrónica del catastro .............................................................................59

Figura 3-7. Herramienta clip .................................................................................................60

Figura 3-8. parámetros usados con la herramienta clip ........................................................61

Figura 3-9. Elementos, relaciones y tablas del esquema CIM ..............................................62

Figura 3-10. Cargando los elementos en el esquema ..........................................................63

Figura 3-11. Atributos de la capa Building dentro del esquema ............................................63

Figura 3-12. Nube de puntos lidar obtenida del IGN .............................................................66

Figura 3-13. Filtros para datos lidar en ArcGIS .....................................................................66

Figura 3-14. Puntos pertenecientes al terreno ......................................................................67

Figura 3-15. Herramienta para obtener el modelo digital del terreno ....................................67

Figura 3-16. Parámetros empleados para obtener el MDT ...................................................68

Figura 3-17. MDT obtenido a partir de datos LiDAR .............................................................69

Figura 3-18. Filtrado de puntos para obtener un MDS ..........................................................69

Figura 3-19. Parámetros empleados para obtener el MDS ...................................................70

Figura 3-20. MDS obtenido ..................................................................................................71

Figura 3-21. Eliminación de errores ......................................................................................72

Figura 3-22. Obtención del modelo de superficie normalizado .............................................73

Figura 3-23. Modelo de superficie normalizado obtenido ......................................................73

Figura 3-24. Parámetros para calcular la altura de los edificios ............................................74

Figura 3-25. Altura de los edificios (Total height) ..................................................................74

Figura 3-26. Herramienta para recortar el terreno ................................................................75

Figura 3-27. Nuevo proyecto CityEngine ..............................................................................75

Figura 3-28. Creación de una nueva escena .......................................................................76

Figura 3-29. Configuración de la escena ..............................................................................76

Figura 3-30. Parámetros de intensidad solar ........................................................................77

Figura 3-31. Importación del terreno.....................................................................................78

Figura 3-32. Terreno importado ............................................................................................78

Figura 3-33. Importación del modelo 3DCIM ........................................................................79

Figura 3-34. Capas no alineadas ..........................................................................................80

Figura 3-35. Alineación de la red de calles ...........................................................................81

Figura 3-36. Alineación del terreno .......................................................................................81

Figura 3-37. Parámetros para alinear el terreno ...................................................................82

Figura 3-38. Escena con todas las capas alineadas .............................................................82

Figura 3-39. Creación de una nueva regla CGA ...................................................................83

Figura 3-40. Subidivisiones del edificio .................................................................................84

Figura 3-41. Seleccionando todos los objetos dentro de una misma capa............................85

Figura 3-42. Asignando el fichero .cga .................................................................................86

Figura 3-43. Escena finalizada .............................................................................................87

Figura 3-44. Parámetros de las intersecciones .....................................................................88

Figura 3-45. Creación de marcadores ..................................................................................89

Figura 3-46. Exportando la escena web ...............................................................................89

Figura 3-47. Capas exportadas a la escena web ..................................................................90

Figura 3-48. Compartiendo la escena web ...........................................................................91

Figura 3-49. Escena web ......................................................................................................92

Figura 3-50. Edificio nuevo generado mediante métodos procedurales ................................92

Figura 3-51. Edificio España y Torre de Madrid ....................................................................93

Figura 3-52. Limpiando las formas .......................................................................................94

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

7

Figura 3-53. Tejados extraídos .............................................................................................95

Figura 3-54. Exportar como geodatabase.............................................................................95

Figura 3-55. Extracción de los muros ...................................................................................96

Figura 3-56. Datos de radiación global .................................................................................97

Figura 3-57. Parámetros del fichero de radiación global .......................................................98

Figura 3-58. Coordenadas para los datos de radiación ........................................................98

Figura 3-59. Valores D y T obtenidos ...................................................................................99

Figura 3-60. Parámetros introducidos en la calibración atmosférica .....................................99

Figura 3-61. Parámetros de calibración atmosférica ........................................................... 100

Figura 3-62. Valores D y T ................................................................................................. 100

Figura 3-63. Herramienta de radiación solar ....................................................................... 101

Figura 3-64. Raster obtenido con los datos de radiación .................................................... 101

Figura 3-65. Herramienta radiación en los tejados ............................................................. 102

Figura 3-66. Potencial solar ................................................................................................ 103

Figura 3-67. Idoneidad solar ............................................................................................... 103

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

8

1. Introducción

1.1. Justificación

El presente documento se corresponde a la asignatura Trabajo de Fin de Máster

del Máster en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del

Territorio impartido por la Universidad de Jaén. De acuerdo con el RD 1393/2007, de

29 de octubre, por el que se establece la ordenación de las enseñanzas universitarias

oficiales, los títulos oficiales de Máster deben concluir con la elaboración y defensa

pública de un Trabajo Fin de Máster, que tendrá entre 6 y 30 créditos (art.15.3), en el

caso concreto del título cursado la dedicación establecida para este es de 12 créditos.

Mi motivación al realizar este trabajo se debe al interés que tengo en un tema de

vital importancia para nuestra sociedad como son las distintas formas de representar

la realidad. Son numerosas las ciudades y empresas que demandan modelos virtuales

en 3D que representen fielmente su entorno para diferentes áreas de aplicación como

la planificación urbana, telecomunicaciones móviles, gestión de desastres, catastro

3D, el turismo, navegación, gestión de instalaciones y simulaciones ambientales.

Además, en la aplicación de la directiva europea sobre el ruido ambiental los modelos

de ciudades en 3D juegan un papel importante.

En los últimos años la mayoría de los modelos virtuales en 3D han sido definidos

como modelos puramente gráficos o visuales, descuidando los aspectos semánticos

y topológicos. Por lo tanto estos modelos se podían usar casi solamente para fines de

visualización, pero no para consultas temáticas, tareas de análisis o minería de datos

espacial y era necesario un nuevo enfoque para satisfacer las necesidades de

información de numerosos campos de aplicación. La inclusión de toda esa información

en un único modelo virtual de la ciudad puede será clave para el desarrollo de las

“Smart Cities”.

La cartografía urbana, sin duda, representa un elemento básico en el presente y

en el futuro del sector geomático. Es necesario tener en cuenta que un 72% de la

población europea vive en zonas urbanas o intermedias mientras que tan solo un 28%

vive en zonas rurales (Eurostat 5 de Octubre de 2015), siendo además las áreas en

las que se concentra una mayor actividad económica, e incluso cambios más rápidos

en la fisonomía y configuración del territorio. Este continuo cambio y crecimiento de la

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

9

población urbana implica un desafío para los gestores y las administraciones públicas

para proporcionar los servicios e infraestructuras que se demandan. El nuevo

concepto de ciudad inteligente (Smart City) implica la necesidad de que las decisiones

vengan avaladas por información objetiva que permitan una gestión sostenible de los

recursos y de las demandas de la población. Es evidente, que la tendencia actual

marca que asegurar que nuestras ciudades puedan soportar las demandas de la

población, debemos volverlas más inteligentes a través de un mejor empleo de los

recursos disponibles.

En este sentido se están desarrollando diversos proyectos en el sentido de

considerar a nuestras ciudades como elementos cambiantes, e incluso como

elementos vivos, ya que comparten las propias etapas que caracterizan a los seres

vivos (crecimiento, madurez y muerte –o decadencia-). Un ejemplo, claro de estas

iniciativas es el proyecto “European Smart City”, orientado al desarrollo de técnicas

integrales de la gestión de las ciudades, en base a las necesidades planteadas (tanto

presentes como futuras), los recursos disponibles y la información del propio territorio

(que debe incluir, logícamente, información de tipo geomático, pero también otros

elementos sociales, económicos, poblacionales. etc.).

La misión de una Smart City es mejorar el cómo nos movemos a través de

entornos cada vez más complejos y asegurar que nuestro entorno urbano es seguro

y confortable para los actuales y futuros ciudadanos. El desarrollo de estas ciudades

inteligentes también promete alcanzar nuevas oportunidades económicas y beneficios

sociales.

La raíz del pensamiento de la Smart City es ver la ciudad como un repositorio de

datos e información centrada en una ubicación geográfica específica. La geografía

enriquece el paisaje proporcionando un sendero a datos históricos, económicos y

sociales. Ciertamente, casi cualquier tipo de datos puede ser asignado a una

ubicación, y es la riqueza de tales datos integrados lo que convierte a una ciudad en

inteligente, más que la simple suma de cada una de sus partes.

Los avances en informática y la creciente accesibilidad de las nuevas

aplicaciones nos permiten recoger y visualizar una gran cantidad de información a

través de las tecnologías móviles. A su vez esto nos permite entender nuestro entorno

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

10

urbano con más detalle. La capacidad para llevar a cabo análisis de simulación multi-

dimensional usando datos procedentes de los productores de datos tradicionales

(gobierno, investigación e industria) y por los mismos ciudadanos está permitiendo

nuevas relaciones y percepciones que han de ser identificadas. También la habilidad

para presentar información geolocalizada a los ciudadanos y la difusión de datos en

2D y 3D a través de aplicaciones móviles y web ofrece nuevas y maneras de participar,

cambiar u optimizar el funcionamiento de nuestras ciudades.

La última generación de modelos de información urbana 3D interoperables (UIM

Urban Information Model), creada a partir de información geoespacial precisa a escala

urbana, pueden ser usados incluso para crear servicios web inteligentes basados en

información geométrica, semántica, morfológica y estructural.

Expuesto lo anterior, se puede decir que los modelos de información urbanos 3D

serán claves para desarrollar simulaciones para ilustrar como las ciudades inteligentes

pueden funcionar. Estas simulaciones servirán para asegurarse de que todo funciona

de forma correcta y como medio para probar los servicios delante de su público

objetivo, convirtiéndose en una herramienta esencial, para las administraciones

públicas, las empresas y para los ciudadanos.

1.2. Objetivos

A lo largo de este Trabajo de Fin de Máster se va a intentar incidir en la

construcción de modelos tridimensionales de ciudades que incorporen validez

geométrica y que puedan ser utilizados y colaborar al desarrollo de las “Smart Cities”

y en la la toma de decisiones.

Se pretende abordar las distintas técnicas que se emplean para obtener estos

modelos, así como mostrar diversas aplicaciones que tienen hoy en día. Se describirá

además el proceso que se lleva a cabo de principio a fin para obtener un modelo de

estas características mediante un ejemplo práctico empleando software compatible

con el estándar CityGML, y utilizando el modelado procedural para generar los

diferentes edificios y elementos de la ciudad a partir de la información que actualmente

ponen a disposición de los ciudadanos las diferentes administraciones, poniendo de

manifiesto la importancia de la difusión de la información geomática como generadora

de valor añadido a la misma.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

11

Por último se le dará alguna aplicación al modelo obtenido que sirva como

ejemplo del potencial que tienen, obteniendo algún producto que pueda ser difundido

a través de la red o mediante algún otro medio.

1.3. Estructura

Tal y como se muestra en la figura 1, la memoria de este Trabajo Fin de Máster

se estructura en los siguientes apartados:

Una Introducción donde se describen la motivación que ha llevado a

realizar este trabajo así como los objetivos que se persiguen y algunos

antecedentes donde se describe cómo ha ido evolucionando el modelado

3D de ciudades hasta hoy, así como la propia estructura de esta memoria.

Una segunda parte donde se describe la metodología, es decir, las

diferentes técnicas que se emplean para obtener los datos necesarios que

permitan representar un entorno urbano mediante un modelo 3D.

Un apartado llamado aplicación de la metodología donde se describe

como se ha llevado a cabo la aplicación práctica de las diferentes

metodologías y los productos y resultados que se han obtenido. Aquí se

describe el software empleado y el trabajo que se ha llevado a cabo en la

zona de estudio propuesta.

Unas conclusiones donde se analice el trabajo llevado a cabo que incluye

un análisis de grado de cumplimiento de los objetivos planteados para

este Trabajo Fin de Máster.

Un apartado final en el que se incluye información gráfica complementaria

y mapas derivados de la aplicación tras el análisis del modelo.

Por último, se incluyen varios Anexos en donde se proporciona al lector

información complementaria sobre los trabajos desarrollados así como

otra información que se considera de interés para el mismo.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

12

1.4. Antecedentes

Hasta hace pocos años los modelos 3D de ámbitos urbanos eran puramente

visuales y no presentaban valor añadido alguno más allá de la mera simulación. Estos

se caracterizaban por:

Ser meras representaciones

Ser modelos puramente gráficos

Carecer de una componente topológica y semántica

Uso restringido. Empleados en arquitectura básicamente

Sin embargo hoy en día y debido a aplicaciones tan populares como Google

Earth/Google Maps que permiten la visualización 3D de distintas ciudades y/o edificios

y a la rápida evolución de los sistemas de información geográfica desde entornos de

trabajo 2D a 3D, surge la necesidad de disponer de modelos urbanos 3D que cuenten

no solo con un componente geométrico sino que además estén enriquecidos con un

amplio componente semántico acorde a las necesidades de información que la

sociedad actual demanda. Surge la necesidad de poder emplear estos modelos en

análisis geoespaciales, existiendo un gran número de aplicaciones en urbanismo,

ordenación del territorio, mapas de ruido, estudios de eficiencia energética,

videojuegos, gestión de emergencias…

Introducción

Metodología

Aplicación de la metodología

Conclusiones

Anexos

Mapas

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

13

A medida que se han ido incrementando tanto las plataformas tecnológicas que

permitan generar, mantener y gestionar geoinformación 3D como el número de

modelos 3D que distintos usuarios tanto privados como públicos han venido

demandando, se han desarrollado distintos estándares internacionales con el objeto

de cubrir la necesidad de contar con un modelo de información común y abierto que

permita la representación 3D de objetos urbanos.

Uno de ellos es el conocido como CityGML, adoptado por el Open Geospatial

Consortium (OGC) como estándar oficial desde el año 2008. Dicho modelo define

detalladamente tanto las clases de objetos que participarán en un modelo urbano

como las relaciones a establecer entre ellos y que configuraran tanto sus propiedades

geométricas como topológicas, semánticas y de apariencia.

Además se caracteriza por contemplar 5 niveles de detalle con lo cual es posible

recrear un modelo desde un entorno básico 2D a un entorno 3D de gran complejidad.

Y dado que se trata de un formato basado en XML, en concreto desarrollado bajo el

estándar Geography Markup Language 3 (GML3), es completamente compatible con

cualquiera de los servicios web OGC actualmente en uso (WFS,WPS,WVS, W3DS,

…). Por todo ello CityGML se ha convertido en el estándar de referencia en el

modelado de entornos urbanos 3D dado su enorme potencial en este campo y el gran

número de proyectos y aplicaciones en los que es posible su utilización.

A continuación se detalla la cronología seguida en el desarrollo del estándar

CityGML desde sus inicios hasta el día de hoy:

Año 2002: Comienza el desarrollo del estándar CityGML por parte de los

miembros del denominado “Special Interest Group 3D (SIG 3D)”

perteneciente a la iniciativa “Geodata Infraestructure North-Rhine

Westphalia (GDI NRW)” radicada en Alemania. Dicho grupo SIG 3D es

una plataforma libre y de carácter internacional compuesta por más de 70

compañías, administraciones municipales e institutos de investigación

que trabajan en el desarrollo y explotación comercial de modelos 3D

interoperables así como en su geovisualización.

Año 2004: El estándar CityGML pasa a ser debatido en el seno de los

organismos internacionales como es el caso tanto del “European Spatial

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

14

Data Research (EuroSDR)” como el grupo de trabajo “3D Information

Management (3DIM) Working Group” del “Open Geospatial Consortium

(OGC)”.

Año 2006: Se desarrolla la versión beta CityGML 1.0 aprobándose por el

comité técnico del OGC en la especificación CityGML como documento

de debate. Durante este año se aborda su discusión desde distintos

grupos de trabajo del OGC como es el caso por ejemplo del “CAD/GIS

Interoperability Working Group”.

Año 2007: CityGML es evaluado y chequeado de forma exhaustiva y con

resultados muy positivos por parte del “OGC Web Services Testbed No.

4 (OWS-4)” lo que da lugar que el comité técnico del OGC considere este

estándar por primera como miembro oficial del OGC.

Año 2008: El 20 de Agosto los miembros del OGC aprueban la versión

1.0.0 del CityGML como estándar oficial del OGC.

Año 2009: Se comienza a trabajar en las futuras versiones del estándar

CityGML (1.1 y 2.0).

Año 2010: El OGC pone en marcha de forma oficial la revisión del

estándar CityGML con vistas a la aprobación de una futura nueva versión.

Año 2011: El grupo de trabajo del OGC destinado a promocionar y evaluar

el estándar CityGML da a conocer el borrador de la versión 1.1 con el fin

de que pueda ser revisado por el público en general y éste pueda aportar

las sugerencias que estime oportunas.

Año 2012: Se decide desechar la versión 1.1 prevista inicialmente y

realizar un cambio más significativo que dará lugar a la aparición de la

versión 2.0.0, aprobándose esta el 14 de Marzo como estándar oficial del

OGC.

En cuanto a los niveles de detalles, son los siguientes:

LoD 0: Representación 2.5D del terreno

mediante el empleo de un modelo digital

de elevaciones. Nivel de detalle

suficiente para la realización de modelos

a escalas globales o regionales.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

15

LoD 1: nivel de detalle a escala de

ciudad en el que los edificios son

representados únicamente mediante

bloques.

LoD 2: representación a escala de

ciudad donde los edificios tienen mayor

detalle, adquiriendo sus fachadas

diferentes texturas y distinguiendo

claramente los tejados y techos del resto

de estructuras propias del edificio. Se

definen algunas estructuras externas

como escaleras o balcones.

LoD 3: se define el exterior de los

edificios con mayor lujo de detalles

desde un punto de vista arquitectónico.

LoD 4: completa al nivel anterior

centrándose en el interior de los edificios

configurando la distribución de pisos y

habitaciones, escaleras, puertas…

En cuanto a las técnicas empleadas para modelizar ciudades, destacan 2 que

han ido evolucionando y ofreciendo buenos resultados en la línea de la automatización

de modelos urbanos. La primera se basa en el uso exclusivo de imágenes, tanto para

la reconstrucción del modelo geométrico como para el modelo de texturas. La segunda

emplea la tecnología LIDAR para la reconstrucción de formas y puede usar tanto la

misma tecnología como la fotografía para la reconstrucción de texturas.

1. 3DUM con fotogrametría aérea y terrestre.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

16

Hasta ahora la generación de un modelo urbano a partir de fotografías requería

de mucha intervención manual, tanto en la fase de aerotriangulación como en la de

modelado, siendo imprescindible combinar los resultados de imágenes aéreas con

imágenes terrestres.

Los procedimientos algorítmicos descritos en los últimos años se ciñen a la

mejora de algún aspecto particular dentro del amplio espectro de problemas que la

automatización de la extracción de un modelo tridimensional conlleva: calibración de

la cámara, registro, extracción de estructuras, estimación de texturas etc.

Se han ido desarrollando soluciones parciales, que imponen ciertas restricciones

en el uso o resultados. Algunos algoritmos asumen configuraciones especiales para

las cámaras o imágenes mientras que otros proponen sistemas que parten de un

modelo 3D aproximado que se refina mediante imágenes obtenidas por una cámara.

Estos procesos han ido automatizándose gracias a los algoritmos que buscan de

forma automática puntos homólogos en las imágenes, de forma que actualmente se

puede obtener cartografía urbana en un proceso semiautomático. Asimismo, en los

últimos años se está registrando una importante tendencia en el uso de cámaras

múltiples oblicuas que incorporan la posibilidad de realizar tomas inclinadas, a objeto

de poder capturas las propias fachadas de los edificios a fin de enriquecer los modelos

y poder extraer, bien de forma automática o manual, las texturas de dichas imágenes

con calidad métrica.

2. 3DUM con LIDAR

Sus principales ventajas con respecto a la fotografía son: determinación directa,

precisa y rápida de las distancias (y no indirecta en base a los resultados de una etapa

de correlación de imágenes) y, en segundo lugar, puede trabajar de noche puesto que

se trata de un sensor activo.

Es especialmente adecuado en zonas de alta densidad urbana. Ahora bien, es

necesario tener en cuenta que la elaboración de un modelo urbano requiere el

tratamiento de información almacenada en grandes volúmenes de nubes de puntos

tridimensionales, en las que habitualmente su calidad radiométrica se limita a la

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

17

reflectancia del objeto (salvo procedimientos de integración de información

proporcionada por cámaras auxiliares en el rango del visible). Esto implica la

necesidad de llevar a cabo procesos de filtrado y clasificación de la información, así

como la posterior extracción de los elementos que se deseen incorporar en el propio

modelo (conversión a modelos cartográficos vectoriales, con problemas asociados de

establecimiento de aristas de los edificios, a partir de nubes de datos distribuidas de

forma irregular).

Ambas técnicas, requieren de una planificación de vuelo, apoyo en campo y una

gran inversión de recursos. Actualmente existe una alternativa que consiste en el

empleo de datos abiertos que se pueden encontrar fácilmente en la red, de acuerdo

con lo planteado en la propia iniciativa INSPIRE sobre reutilización de la información

geográfica capturada con fines generales. En este sentido, uno de los objetivos

planteados en el proyecto es analizar la potencialidad de la información suministrada

para poder caracterizar elementos básicos en la modelización, como, por ejemplo, las

huellas de los edificios o red de calles, y a partir de ellos, obtener el modelo mediante

técnicas de modelado procedural, empleando software que utilice el estándar de

cityGML. Esta opción se plantea como una alternativa de gran interés, para diversas

aplicaciones, ya que suprime los problemas, las necesidades de infraestructuras y

equipamiento específico y costes y tiempos de ejecución ligados a las misiones de

vuelo fotogramétrico, sea de imagen o de LiDAR.

2. Metodología

2.1. Introducción

A la hora de modelar una ciudad lo principal es definir el ámbito sobre el cuál se

trabajará en función de la aplicación que se pretenda dar al modelo, y que datos serán

necesarios para ello. Algunos datos que suelen emplearse típicamente son:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

18

Ortofoto

MDT, MDS

LiDAR

Huellas de los edificios

Árboles

Calles

Elementos puntuales y lineales del mobiliario urbano tales como aceras,

o señales de tráfico.

El proceso general a seguir es el siguiente:

Figura 2. Esquema general de generación de un modelo 3D de ciudad

2.2. Obtención de los datos

Para obtener un conjuntos de datos que puedan ser empleados en la generación

de un modelo 3D urbano, se pueden emplear diversas metodologías basadas en

fotogrametría o LiDAR. Estas se describen brevemente a continuación.

2.2.1. Mediante fotogrametría

Concepto de fotogrametría

La fotogrametría es el arte, ciencia, y tecnología de obtener información fidedigna

a través de imágenes y otros sistemas de sensores sobre la Tierra y su entorno, así

como de otros objetos físicos o procesos a través de la captura, medida, análisis y

representación.

Obtención de los datos

Preparación de los datos

Obtención del modelo

Visualización y Analísis del

modelo

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

19

Como todas las técnicas relacionadas con la imagen, la fotogrametría ha

evolucionado de forma drástica desde las imágenes analógicas a las digitales. En el

campo de dicha técnica, se ha pasado en unos años desde las soluciones

opticomecánicas de tipo totalmente analógico a las analíticas, que significaban la

entrada de la informática (hardware + software) combinada con imágenes analógicas

pero la revolución real apareció de la mano de la imagen digital.

Las principales ventajas de las técnicas digitales son, por un lado la

automatización de los procesos –ya que desaparece la componente óptico-mecánica

+ electrónica que son sustituidos por software– y por la posibilidad de identificar puntos

homólogos en las imágenes, es decir de medir automáticamente, casi sin intervención

humana, mediante los restituidores fotogramétricos digitales. Potencia, por tanto las

herramientas matemáticas de la fotogrametría analítica y de los procesos digitales de

imágenes, abriendo la técnica a la generación de diferentes tipos de cartografías y

representaciones tanto en 2D como en 3D.

Obtención de la ortoimagen

Mediante la Fotogrametría se pueden obtener ortoimágenes, las cuales son un

producto de gran utilidad puesto que combina la calidad métrica de un mapa

(proyección ortográfica) con la calidad semántica de una imagen, corrigiendo las

distorsiones que presentan las imágenes originales como consecuencia de su toma

(fundamentalmente, desplazamiento debido al relieve y desplazamiento por

inclinación). Estas ortoimágenes (o mejor dicho, el mosaico de las mismas que da

lugar a un documento cartográfico continuo de imagen) puede usarse como capa base

a la hora de representar el terreno en un modelo 3D de ciudad, así como asignar

textura a los elementos que aparecen sobre el terreno (tejados, calles, etc.).

Para obtenerla se aplica un proceso de rectificación diferencial para el cual es

necesario disponer de un modelo digital de elevación (MDE), debiendo estar este

referido a un sistema de proyección de coordenadas que será en el que se obtenga la

imagen rectificada.

Con la rectificación diferencial se persigue asignar a cada elemento de la matriz

del modelo digital el nivel digital correspondiente. Para determinar ese nivel digital es

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

20

necesario transformar las coordenadas terreno de los puntos X, Y, Z en

fotocoordenadas x, y mediante la expresión de colinealidad:

𝑥´ = −𝑐 ∗𝑚11 ∗ (𝑋 − 𝑋0) + 𝑚12 ∗ (𝑌 − 𝑌0) + 𝑚13 ∗ (𝑍 − 𝑍0)

𝑚31 ∗ (𝑋 − 𝑋0) + 𝑚32 ∗ (𝑌 − 𝑌0) + 𝑚33 ∗ (𝑍 − 𝑍0)

𝑦´ = −𝑐 ∗𝑚21 ∗ (𝑋 − 𝑋0) + 𝑚22 ∗ (𝑌 − 𝑌0) + 𝑚23 ∗ (𝑍 − 𝑍0)

𝑚31 ∗ (𝑋 − 𝑋0) + 𝑚32 ∗ (𝑌 − 𝑌0) + 𝑚33 ∗ (𝑍 − 𝑍0)

Figura 2-1. Método indirecto para obtener la ortofoto

Para llevar a cabo la rectificación se sigue el siguiente proceso:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

21

Figura 2-2. Proceso para llevar a cabo la rectificación

El proceso fotogramétrico llevado a cabo para obtener una ortoimagen sería el

siguiente:

Planificación del vuelo. Red de puntos de apoyo

La escala es el factor clave para planificar el vuelo puesto que controla el coste

final del proyecto (que variará en función del número total de modelos necesarios para

cubrir una determinada zona).

Han de ser tenidas en cuenta por supuesto las condiciones ambientales:

Nubes altas y cerradas para conseguir iluminación uniforme

Ángulo de inclinación solar por encima de 30º

Fecha ideal: Marzo-Abril o Mayo-Octubre

Planificación del vuelo. Red de

puntos de apoyo

Orientación del bloque mediante ajuste simultáneo

Creación del MDE Ortorrectificación

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

22

La escala determinará la altura de vuelo y por tanto el tamaño del fotograma en

el terreno. En función del pliego de condiciones y del GSD requerido se procede a

calcular el número de pasadas y fotogramas necesarios para llevar a cabo el vuelo.

Los puntos de apoyo han de ser distribuidos uniformemente por el terreno,

adquiriendo sus coordenadas X, Y, Z antes de realizar el vuelo. Estos deben ser

puntos de buena calidad que sean fácilmente identificables en los fotogramas

posteriormente.

Tomadas las imágenes, se realiza una corrección radiométrica, así como un

control de calidad de los puntos de apoyo y las imágenes digitales.

Orientación del bloque mediante ajuste simultáneo

Se obtienen las expresiones que relacionan el sistema de coordenadas imagen

y el sistema de coordenadas terreno, mediante el proceso de orientación (interna y

externa).

Se ajusta el bloque mediante mínimos cuadrados utilizando constreñimientos

con pesos.

La orientación se basa en el empleo de aerotriangulación y ajuste simultáneo de

bloque mediante ajuste de haces.

Creación del MDE

Se captura automáticamente mediante procedimientos de matching. Este se

edita utilizando la superposición con el modelo estereoscópico y se almacena

posteriormente.

El aspecto clave aquí es el espaciado, que dependerá del terreno y de la relación

de escala. Se trata de un aspecto que se ha modificado en los últimos tiempos como

consecuencia de la aparición de los nuevos procedimientos de correlación de

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

23

imágenes y el incremento de potencia en los sistemas de generación y procesamiento

de los modelos. Así, frente a espaciados tradicionalmente empleados en la década de

los 1990 de 10 a 15 veces el GSD de la imagen, en la actualidad se pueden obtener

modelos (o al menos, conjuntos de puntos medidos de forma automática sobre la

imagen) con un espaciado equivalente al del propio GSD de la misma. Esto permite

una importante mejora en la caracterización de la morfología del territorio, en especial,

en entornos, como es el caso de las ciudades donde la presencia de elementos

antrópicos, lleva a que existen importantes discontinuidades.

Ortorrectificación

Se procede a la rectificación diferencial utilizando el MDE y los parámetros de

orientación obtenidos anteriormente.

El resultado es un mosaico de ortoimágenes.

Ajuste radiométrico

Es necesario dado que las fotografías aéreas presentan frecuentemente falta de

homogeneidad tanto a nivel local, como global, debido a los cambios de iluminación

entre los momentos de toma de las imágenes.

Generación del mosaico

Se realiza de manera automática. La única preocupación es conseguir un

producto con una buena apariencia final. Para ello es fundamental conseguir un buen

empalme, tanto geométrico como radiométrico.

A la hora de seleccionar las imágenes más apropiadas se suele emplear alguno

de los siguientes criterios:

Cercanía al nadir de la imagen

GSD de la imagen

Inclinación del rayo óptico sobre el terreno

Variación radiométrica

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

24

2.2.2. Mediante LiDAR

Concepto de lidar

Se trata de un sistema que integra a su vez a diferentes sensores, que permite

la medida rápida de puntos del terreno (XYZ) a partir del tiempo de vuelo de un pulso

láser emitido, del que se conoce su ángulo de inclinación, así como la posición y

orientación de la plataforma desde la cual el mismo fue emitido.

Figura 2-3. Escaneado de la superficie terrestre mediante lidar

Así el sensor láser emite un pulso de alta energía, enviado a la escena que lo

refleja y vuelve a ser registrado por el sensor. Al ser un sensor activo es posible

trabajar tanto de día como de noche (incluso es mejor de noche puesto que no hay

interferencias con el sol). También es posible medir áreas con poca textura e incluso

en zonas de sombra.

Trabaja a partir de las medidas del tiempo de vuelo (TOF-Time of Flight) y

también registran la intensidad.

La medida de la distancia es de tipo polar, midiendo distancia y ángulo desde la

fuente al objeto a medir.

La mayoría de ALS trabajan en infrarrojo por lo que están afectados por la

presencia de nubes, nieve, lluvia… No es por tanto dependiente de las condiciones

climáticas, a diferencia de los sensores radar.

Medida de la distancia

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

25

El principio del sistema LiDAR es similiar al empleado en la medida electrónica

de distancias (EDM), donde un láser (en formato de pulso o de onda continua) se

dispara desde un emisor y posteriormente registra la energía reflejada.

Mediante el cálculo del tiempo de vuelo (ToF) es posible calcular la distancia

entre el sensor y el objeto.

El objeto puede ser un elemento artificial (un prisma por ejemplo) o elementos

del propio terreno.

Figura 2-4. Tiempo de viaje de láser

Figura 2-5. La amplitud del pulso recibido decrece

𝑅 =𝑇𝐿

2∗ 𝑐

∆𝑅 =𝑐

2∗ ∆𝑅

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

26

𝑅𝑚𝑎𝑥 =𝑐

2∗ 𝑇𝐿𝑚𝑎𝑥

Donde:

R = distancia recorrida

TL= tiempo de vuelo

c = velocidad de la luz

Obtención de coordenadas terreno

Las coordenadas terreno (XYZ) se determinan mediante:

1. La determinación precisa de la posición del sensor en el espacio mediante el

empleo de DGPS.

2. La determinación de su orientación mediante un sistema inercial IMU.

3. La determinación de la inclinación del rayo láser.

4. La distancia entre el sensor y el objeto mediante el ToF.

Figura 2-6. Sistema de posicionamiento del Lidar

Una vez realizada la medición se obtiene una nube de puntos XYZ (no una

representación ráster).

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

27

Cada pulso láser emitido puede dar lugar a la medida de varios objetos del

terreno (vegetación y suelo por ejemplo) gracias al tratamiento de los ecos (o del pulso

continuo waveform).

Componentes del sistema

Los sistemas LiDAR se encuentran normalmente formados por:

Una unidad de medida: formada por un transmisor láser y un receptor.

Un mecanismo deflector del rayo: espejo, polígono…

Sistema de posicionamiento GPS/INS (es necesario conocer los vectores

y ángulos de desajuste entre el GPS/INS y la unidad láser). El GPS es de

doble frecuencia y trabaja en modo diferencial con las estaciones de

referencia cercanas.

Opcionalmente puede tener sensores de imagen para la generación de

ortoimágenes o para la depuración de datos.

Plataformas: Avionetas, helicópteros, UAV…

Figura 2-7. Componentes del sistema lidar

Planificación del vuelo

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

28

La planificación se realiza teniendo en cuenta en todo momento el pliego de

condiciones técnicas facilitado por el cliente que encarga el vuelo. Estas

especificaciones técnicas suelen ser:

Máximo FOV permitido

Frecuencia de escaneado mínima

Frecuencia de pulso

Densidad promedio de puntos de primer retorno por metro cuadrado

Sensor calibrado con una antigüedad menor a 12 meses

Recubrimiento transversal

Longitud máxima de las pasadas

Pasadas transversales de ajuste altimétrico

Precisión general altimétrica

Discrepancia altimétrica entre pasadas

Distancia a estaciones de referencia

Esta fase de planificación consiste en obtener las características del vuelo así

como el modo de operar del sensor para cumplir con las especificaciones indicadas

en el pliego.

Se ha de tener en cuenta:

La orografía del terreno a volar

Las características del sistema utilizado

La climatología

El pliego de condiciones técnicas

La posibilidad de realizar un vuelo fotogramétrico simultáneo

Es aconsejable realizar también un vuelo de calibración

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

29

Figura 2-8. Recubrimientos en el vuelo lidar

Figura 2-9. Pasadas del vuelo lidar

Procesado de los datos

Una vez ejecutado el vuelo, para obtener correctamente la nube de puntos final,

se tendrá que realizar un cálculo de la trayectoria del vuelo así como de la orientación

del sensor en cada instante de tiempo, que permita posteriormente darle coordenadas

absolutas a los puntos capturados.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

30

Una vez extraídos los datos del sistema inercial, y convertidos a formato legible

por el software de cálculo, se analiza la trayectoria diferencial de GPS obtenida,

teniendo en cuenta:

El número de satélites recibidos en la observación. Asegurándonos un

mínimo de dos bases de referencia, no se deberían procesar datos

cuando el número de satélites recibidos sea inferior a 5 durante el tiempo

de observación.

La precisión en coordenadas XYZ de cada uno de los puntos de la

trayectoria.

El cálculo de la trayectoria de vuelo concluye con un suavizado de la misma a

partir de los datos procedentes de la IMU (sistema inercial), que convertirán el cálculo

DGPS en un cálculo más preciso y riguroso.

Obtener el máximo de precisión en el cálculo de la trayectoria DGPS es el

concepto más importante en todo el proceso de obtención de datos LiDAR.

La precisión a obtener se cuantifica en función del número de satélites obtenidos

durante la observación y la fidelidad de las coordenadas de posición de las estaciones

base.

Figura 2-10. Trayectoria seguida

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

31

Realizado el cálculo de trayectorias GPS/INS, y con la nube de puntos en bruto,

se obtiene la nube de puntos final en formato .LAS.

Este formato se trata de un estándar para trabajar con datos LiDAR, permitiendo

el intercambio de ficheros que contienen información de una nube de puntos

tridimensional. Es un archivo binario que mantiene toda la información procedente del

sistema LiDAR, conservando la misma la propia naturaleza de los datos y del sistema

de captura.

Figura 2-11. Formato del archivo LAS

Figura 2-12. Clasificación estándar de los puntos

Una vez obtenidas las nubes de puntos correspondientes a cada pasada del

vuelo realizada, los datos han de ser procesados y preparados para la entrega y la

futura extracción de información.

Este procesado podría consistir en:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

32

Reorientación y ajuste entre pasadas por errores superiores a los

esperados

Obtención de bloques según pliego de condiciones técnicas.

Paso de alturas elipsoidales a cotas ortométricas.

Clasificación automática de la nube de puntos.

Edición de la clasificación automática con ortoimágenes o pares

estereoscópicos.

Obtención de productos derivados (curvados, MDT malla, etc..).

Extracción de información específica (Edificios, líneas eléctricas,

documentación forestal, etc.).

Figura 2-13. Ajuste de pasadas

En el ajuste de pasadas, el funcionamiento es similar al ajuste de modelos

independientes con parámetros de autocalibración.

Modelización de desplazamientos, derivas y otros errores sistemáticos

Medida de puntos de paso

Medida de puntos de control

Ajuste de pasadas de forma que: los puntos de paso homólogos se

transforman en el mismo punto terreno

los errores en los puntos de control son mínimos

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

33

Figura 2-14. Puntos de paso

Puesto que trabajar con todas y cada una de las pasadas es difícil debido a la

gran cantidad de información que contiene cada una, lo que se hace es trabajar por

bloques dividiendo toda la información en pequeños modelos con el fin de trabajar con

la información de forma más precisa y rápida.

Figura 2-15. División en bloques

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

34

Ya obtenidas las nubes de puntos, es necesario clasificarlas, diferenciando

primeramente entre aquellos puntos que pertenecen al terreno y los objetos situados

sobre éste. Posteriormente se clasificarían los distintos objetos en edificios, árboles,

vehículos, tendidos eléctrico etc.

En primer lugar este proceso de clasificación debe basarse en métodos

automáticos. Sin embargo, es complicado que esta clasificación sea exitosa al 100%

en todo el terreno debido a la variabilidad, características y orografía de la escena.

Esto obliga a realizar un proceso semiautomático puesto que establecer un

procedimiento y parámetros de clasificación automática para todas las zonas resulta

imposible.

Este proceso semiautomático se apoya en la edición manual y puede estar

ayudado por el uso de información adicional como puede ser el uso de ortoimágenes

de la zona (debiendo ser coetáneas a la información LiDAR).

Obtención de productos y extracción de información

Clasificada la nube de puntos, se obtienen el MDT y MDS.

Figura 2-16. Modelo digital de superficie

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

35

Figura 2-17. Modelo digital del terreno

2.3. Preparación de los datos

Edición cartográfica de la ortoimagen para obtener las huella de los edificios

(True-Ortho)

A partir de la ortoimagen se pueden digitalizar edificios y otros elementos

fácilmente, obteniendo de esta forma las huellas de los edificios, calles, árboles y

cualquier tipo de elemento que se pueda encontrar dentro de una ciudad. Sin

embargo, para ello es necesario que todos los elementos que aparecen en la imagen

estén adecuadamente rectificados, es decir, que para su rectificación diferencial se

haya utilizado un modelos digital de superficies que incluyan dichos elementos. En la

práctica, el producto habitual es el conocido como ground-ortho, es decir, una

ortofotografía que ha sido generada a partir de un modelo digital del terreno, en el que

sólo se considera los elementos naturales del terreno, estando el resto afectados por

los desplazamientos debido al relieve (en dirección radial con respecto al nadir). Este

hecho plantea algunos problemas para su uso en la generación de modelos 3D de

ciudades como:

1. Desplazamientos y ocultamientos que hacen difícil sobre imponer

información vectorial para propósitos de actualización de cartografía.

2. La ortorrectificación es parcialmente imprecisa geométricamente y/o

incompleta (los edificios se distorsionan y se mueven de su localización

verdadera debido a que no están modelados en el MDT).

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

36

Figura 2-18. Izq.: Ortoimagen convencional; Dcha.: Ortoimagen verdadera

Usando modelos digitales de superficie (MDS) y considerando áreas ocultas es

posible generar ortoimagen verdaderas que no tengan los problemas mencionados

anteriormente. Esto no quita que puedan surgir otros problemas:

a. Las ocultaciones que ocurren en las imágenes simples se tienen que

rellenar con la combinación de la información situada en varias ortos

adyacentes. Pero a menudo no todas las áreas se pueden completar

por falta de recubrimientos.

b. Los tejados tienen que ser modelados de la forma correcta, ya que

de otra forma están distorsionados en las ortoimágenes o se

muestran con bordes dentados. Modelar todo tipo de tejados con

precisión y en detalle, puede ser complicado si el cálculo es

automático o se dispone de poco tiempo.

La generación de ortoimágenes verdaderas tienen que considerar por tanto la

proyección ortogonal con un MDS, la detección de áreas ocultas y el relleno de las

mismas se hará tomando las partes de imagen perdidas de las ortos colindantes.

Lo importante por tanto es contar con un buen MDS para que los objetos sean

proyectados a su verdadera posición geométrica. En la siguiente imagen se puede ver

el esquema de la ortoproyección con un MDS, que es una proyección ortogonal.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

37

Figura 2-19. Proyección ortogonal

El problema es que las áreas ocultas por los objetos humanos no son visibles en

la imagen. En la siguiente figura se observa como el tejado del edificio cubre también

el área de ocultación en la imagen aérea original.

Los edificios también pueden obtenerse a partir de los datos LiDAR de primer

retorno. Se sabe que los tejados son superficies planas por lo que identificando estos

tejados, también se identifica la huella del edificio. Si estas áreas no son detectadas

por el software de rectificación la ortoproyección la rellenará exactamente con

contenido de la imagen, pero de la misma imagen. Esto crea el llamado “efecto

fantasma”.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

38

Figura 2-20. Áreas ocultas en proyección ortogonal

Combinando información de la imagen original con otra obtenida de varias

imágenes adyacentes, es posible rellenar áreas ocultas.

De esa forma, a partir de un MDS y utilizando imágenes con recubrimiento desde

diferentes vistas (por ejemplo, un bloque de imágenes aéreas) se pueden analizar en

el proceso de ortoproyección las posibles zonas ocultas y obtener la información

necesaria a partir de otras imágenes disponibles. Este proceso es una tarea compleja

ya que deben tenerse en cuenta, no sólo los criterios geométricos (posición de toma

de la imagen, inclinación del rayo, etc.) sino también otros elementos radiométricos a

fin de establecer las correspondientes líneas de mosaico (sean lines) incorporando

procedimientos de suavizado de dichas líneas y de compensación radiométrica de las

ortoimágenes generadas a ambos lados de la misma. De otra forma el mosaico

carecería de la continuidad geométrica y radiométrica requerida.

Esta ortoimagen que incorpora como fuente de información del terreno, un

modelo digital de superficie, y que en su proceso de generación incluye la detección

de áreas ocultas, escogiendo la información de otras imágenes disponibles, es

conocida como ortoimagen verdadera (true ortho). La denominación como “verdadera”

la recibe porque los objetos son verdaderamente proyectados en la dirección paralela

y perpendicular sobre el plano de la ortoimagen.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

39

De esta forma, en la siguiente figura se puede observar que los edificios se

representan con una proyección perfectamente ortogonal (no se ven sus fachadas ni

están distorsionados ni dejan áreas ocultas).

Figura 2-21. Izquierda.- Ortofoto convencional (existen zonas ocultas). Centro - Paso intermedio (se aprecia el efecto fantasma). Derecha - Orto verdadera ya corregida (áreas ocultas rellenas con

información de ortos adyacentes).

Debido al MDS, además de obtener la ortoimagen verdadera, también se puede

restituir directamente sobre el modelo de forma que se digitalicen los edificios, árboles

y cualquier elemento que sea de interés para modelizar las ciudades.

Obtención de MDT y MDS

Puesto que el MDS se genera a partir de los datos brutos, se describe a

continuación como se obtiene el MDT.

Para obtener el modelo digital del terreno es necesario aplicar una serie de filtros

a los datos LiDAR, puesto que en la captura de puntos no se lleva a cabo. Para ello

se deben clasificar los puntos en terreno y no terreno. Este problema se plantea como

sigue:

Dado un conjunto de puntos

𝑃{𝑝𝑖(𝑥, 𝑦, 𝑧, 𝑐), … }

𝐷𝑜𝑛𝑑𝑒: 𝑥, 𝑦 , 𝑧 𝑠𝑜𝑛 𝑙𝑎𝑠 𝑐𝑜𝑜𝑟𝑑𝑒𝑛𝑎𝑑𝑎𝑠 𝑒𝑛 𝑒𝑙 𝑒𝑠𝑝𝑎𝑐𝑖𝑜 3𝐷

𝑐 𝑢𝑛𝑎 𝑒𝑡𝑖𝑞𝑢𝑒𝑡𝑎 𝑑𝑒 𝑐𝑙𝑎𝑠𝑖𝑓𝑖𝑐𝑎𝑐𝑖ó𝑛 𝑖𝑛𝑑𝑖𝑣𝑖𝑑𝑢𝑎𝑙

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

40

Se ha de buscar una función de clasificación

𝑓: 𝑥, 𝑦, 𝑧 → 𝑐

𝐷𝑜𝑛𝑑𝑒: 𝑝𝑖 ∈ 𝑃

𝑐 ∈ 𝐶 {terreno, no terreno}

Para esta clasificación es muy útil emplear todos los puntos e información

disponibles. Al disponer de zonas donde se solapan dos o más pasadas aumenta la

probabilidad de penetración en la vegetación. También aumenta la redundancia y

permite rellenar zonas de sombra. La intensidad e información de ecos también es

información muy útil.

La obtención de un MDT empleando LiDAR debe estar basada en los puntos

correspondientes al último eco, aunque determinadas circunstancias hacen que esta

afirmación no pueda considerarse de manera tajante:

La reflexión de los rayos provoca que la posición del último eco se capture

erróneamente por debajo del terreno.

Cambios bruscos del terreno que producen varios ecos para un mismo

haz.

El último eco puede corresponderse a veces con vegetación o edificios ya

que el láser no puede atravesarlos.

Son varios los diferentes filtros que se pueden aplicar para clasificar los puntos,

funcionando bien la mayoría en zonas con baja complejidad (terreno suave, pequeños

edificios, vegetación aislada y escasa) y siempre que haya una densidad de puntos

adecuada. Destacan los siguientes:

Filtrado morfológico

Filtrado basado en densificación progresiva

Filtrado basado en la superficie

Filtrado basado en procesos de agrupación y segmentación

Otros métodos de filtrado, que generalmente combinan los anteriores

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

41

El comportamiento de estos filtros es sensiblemente diferente en paisajes más

complejos, identificando zonas problemáticas para todos los filtrados (terreno en

pendiente, bordes, pasos subterráneos…).

Se considera que los filtros basados en densificación progresiva y los filtros

basados en superficie obtienen en la mayoría de los casos los mejores resultados.

Tras aplicar el filtro deseado para obtener los puntos del terreno, se genera una

malla a partir de estos puntos que representa el terreno sobre el cual se desarrolla

nuestra urbe.

2.4. Generación del modelo. Modelado procedural

El modelado procedural se ha impuesto, a lo largo de la última década como una

herramienta indispensable para la reconstrucción, representación y visualización de

ciudades 3D, y por lo tanto en una herramienta que puede convertirse en clave

también para el mundo SIG. Actualmente el modelado urbano se utiliza en

aplicaciones como: reconstrucción de mapas y ciudades para herramientas de

navegación, contenido digital de ciudades para videojuegos o películas, modelos de

simulación para respuestas de emergencias y rutas de evacuación, así como

planificación urbana.

Los datos de entrada para este tipo de modelado, desde el punto de vista de las

aplicaciones SIG, pueden provenir de diversas fuentes como son los archivos de Open

Street Map (OSM). A partir de estos se puede obtener la red de calles y manzanas de

una ciudad, para luego dividirlos automáticamente en parcelas a partir de las cuales

se generan los volúmenes de edificios que serán procesados a continuación. Otro tipo

de datos son los datos catastrales, que contienen información volumétrica de cada

edificio de la zona estudiada. En ambos casos, se aplican algoritmos procedurales

que procesan una serie de reglas de manera iterativa que definen la estructura de las

fachadas de los edificios.

Estas reglas se pueden hacer manualmente mediante herramientas visuales o

extraerse a partir de información de los edificios reales, como por ejemplo fotografía

capturada desde el terreno o con una cámara oblicua (p.ej. Microsoft Osprey), datos

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

42

de un sistema de cartografía móvil (mobile mapping system) o láser escáner terrestre

(TLS). Una vez todos los edificios han sido procesados y su geometría generada, los

datos resultantes pueden utilizarse para su visualización directa, o para utilizarlos en

cálculos como los requeridos en los modelos de física urbana. Un problema a tener

en cuenta es la gran capacidad del modelado procedural para generar grandes

cantidades de geometría a partir de una entrada pequeña puede resultar en la

generación de una gran y excesiva cantidad de geometría. Para solucionarlo, pueden

emplearse métodos que controlen el nivel de detalle según las necesidades

específicas de cada problema.

El proceso de generación de un modelo urbano se puede resumir como muestra

la figura, donde se indica la secuencia de pasos y estructuras necesarias. El primer

paso consiste en transformar los datos cartográficos de entrada en una red

estructurada de calles, que delimitaran las manzanas o bloques. Estas manzanas son

divididas en parcelas, en las cuales se generan los modelos volumétricos de la

edificación. Finalmente, el modelado procedural añade los detalles mediante la

aplicación de reglas.

Figura 2-22. Pasos para la generación un modelo urbano

ENTRADA DE DATOS

Es importante tener en cuenta que la calidad y fidelidad del modelo 3D resultante,

estará muy influenciada por la calidad de la información contenida en las bases de

datos cartográficas de entrada. Mientras más información contengan estos datos, y

cuanto más precisa sea, menos algoritmos deberán de utilizarse, mejorando así la

calidad y fidelidad del modelo 3D resultante.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

43

OpenStreetMap

Se trata de una fuente de SIG libre, siendo uno de los inputs más usuales en

este tipo de procesamiento. Los archivos OSM de OpenStreetMap siguen el estándar

XML para la representación de datos. Para su correcta interpretación es necesario

escribir un algoritmo de lectura (parser) que tenga en cuenta los diferentes tipos de

datos que estos archivos pueden contener, conservando aquellos que sean relevantes

de cara al modelo que se pretende generar. Si por ejemplo solo se quiere un modelo

donde aparezcan los edificios, la capa de parada de autobús se puede desechar. En

cambio, si se busca una representación completa de la estructura urbana, es probable

que si se incluya este tipo de información, añadiendo probablemente un modelo 3D

que represente una parada de autobús, pero se ignoren otros elementos como áreas

comerciales o de parking por ejemplo. Eso implica un primer nivel de procesamiento

donde se filtran los datos que interesan para construir el modelo.

La estructura de estos archivos OSM es sencilla de procesar: se trata de una

lista con todos los nodos del mapa, seguida de una lista con todos los caminos del

mapa, donde un “camino” puede ser desde un edificio hasta una calle. Estos caminos

son polilíneas que no poseen nodos, sino que guardan referencias a los mismos. Esta

estructura es ventajosa para la representación visual pero es ineficiente para otro tipo

de cálculos como el cálculo de rutas o reconstrucción 3D. Es por esto que los datos

deben procesarse en estructuras secundarias. Para el caso de cálculo de rutas lo más

eficiente sería guardar para cada nodo la lista de calles que lo cruzan. Para el caso

de la reconstrucción 3D es necesario encontrar todos los ciclos mínimos del mapa,

que representan las áreas más pequeñas rodeadas por calles: las manzanas. Por lo

tanto y debido a esto, de cara a la reconstrucción 3D, el pre-proceso de un mapa

culmina con el cálculo de las manzanas, que son luego utilizadas en otras etapas del

proceso.

Datos catastrales

Son una importante fuente de información geográfica, sin embargo esta

información no siempre está bien estructurada, pudiéndonos encontrar un archivo SIG

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

44

con datos claramente incorrectos o introducidos con una codificación incorrecta lo que

puede producir un problema para su uso en reconstrucciones 3D. La solución

propuesta se basa en un algoritmo de reestructuración 2D semiautomático, que

corrige errores y ambigüedades que se presentan comúnmente en datos catastrales

corruptos. Es un problema complejo ya que es necesario para identificar elementos

imples del archivo de entrada y su conectividad y la estructura del mundo real. La

salida del algoritmo suele ser datos urbanos restructurados en una jerarquía de

bloques y edificios, de los cuales se puede obtener un modelo 3D realista mediante la

extrusión de cada edificio.

Figura 2-23. Reconstrucción del Eixample de Barcelona a partir de datos catastrales

Para la construcción de este modelo hace falta además utilizar el número del

piso para cada edificio dentro de los datos catastrales, reconstruyéndolo con un valor

estándar para la altura de las plantas. Dichos valores se obtienen como un promedio

de un estilo arquitectónico dado, dentro del contexto de una ciudad.

Otros tipos de entradas

En caso de no disponer de información precisa, se puede utilizar una síntesis

basada en parámetros de entrada. Para estos casos se suelen utilizar mapas que

guíen la reconstrucción (mapas de población, mapas zonales…) y que provean de

posibles indicaciones sobre la estructura urbana asociada.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

45

Un tipo de descripción muy popular consiste en utilizar un sistema basado en

regiones, cada una asociada a los diferentes patrones que típicamente se pueden

observar en una ciudad: patrón regular (grid), radial u orgánico. A partir de esta

información, el sistema procede a crear un conjunto de avenidas mayores, calles y

manzanas para continuar con la creación de la ciudad en 3D. La siguiente figura

muestra un ejemplo de generación de estructura urbana empleando este sistema.

Figura 2-24. Modelo sintético de estructura urbana. Mapa de patrones con region radial, orgánica y regular. Generación del modelo correspondiente.

GENERACIÓN DE BLOQUES Y PARCELAS

Una vez que se ha creado la red de avenidas y calles, y se determinan las

regiones edificadas, los bloques quedan completamente identificados. El siguiente

paso consiste en crear las parcelas. En la mayoría de casos es difícil acceder con

precisión a la distribución de las parcelas de acuerdo con los lotes, por lo que se

utilizan algoritmos de subdivisión automática. Existen para ello diferentes algoritmos

que buscan reflejar las divisiones que se pueden encontrar de forma natural en las

grandes ciudades. Dos ejemplos son la subdivisión recursiva, que busca recrear

ciudades como Nueva York o Buenos Aires; y la subdivisión llamada de tipo Barcelona

o París, que simula la típica estructura de una manzana en estas ciudades, donde

normalmente existe un patio interior que debe ser modelado para la correcta

representación de estas ciudades.

Generalmente para modelar ciudades como Nueva York o Seattle, se utiliza un

algoritmo que subdivide iterativamente las manzanas de forma regular, siempre

cortando de forma perpendicular a la dirección más larga de la manzana. Esto resulta

en la típica estructura rectangular de distribución de edificios de las ciudades

americanas, tal y como se muestra en la figura adjunta.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

46

Figura 2-25. Estructura urbana tipo Manhattan

Por otro lado, en otras ciudades como, por ejemplo, París o Barcelona, pueden

observarse otro tipo de manzanas que pueden obtenerse por un proceso de

contracción del entorno de la ciudad hasta una tolerancia pre-establecida, siempre

asegurando que no haya errores de auto-intersección de las formas. De esta manera

el patio interior suele tener una forma muy similar a la de la manzana, un patrón

frecuentemente observable en ciudades europeas. La figura 2-24 muestra el resultado

de una reconstrucción de este tipo en la ciudad de Barcelona.

Figura 2-26. Estructura urbana tipo Barcelona

GENERACIÓN DE EDIFICIOS PROCEDURALES

A partir de la información de las alturas correspondientes se pueden generar de

manera sencilla los volúmenes de las edificaciones mediante operaciones clásicas de

extrusión. Lo que se obtiene son los comúnmente llamados mass-models. Si se

disponen de imágenes ortográficas de las fachadas, se pueden emplear para obtener

un modelo texturizado, que en muchas ocasiones es el tipo de modelo que se emplea

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

47

para la visualización (ver figura anterior). Sin embargo este modelo carece de detalles

geométricos.

Para la generación completa de edificios, se suelen emplear reglas gramaticales.

La aplicación de las reglas se basa en su evaluación secuencial, tomando para cada

iteración las formas geométricas resultantes de la iteración anterior, siendo la iteración

inicial la que recibe el modelo volumétrico. Los principales comando que se pueden

emplear son:

Subdiv, que realiza una subdivisión de la forma actual en múltiples formas.

Repeat, que realiza subdivisiones de manera repetida de una forma

geométrica (se puede emplear por ejemplo para ir creando plantas con

una determinada altura dentro de un edificio hasta completar la altura

máxima de este último).

Component Split, que puede crear nuevos componentes (por ejemplo

caras de un poliedro o aristas) a partir de una forma geométrica. Es útil

para dividir los edificios en fachadas y tejados por ejemplo.

Insert, que reemplaza geometría predefinida en el predecesor

correspondiente.

El proceso de producción de un determinado conjunto de reglas se puede

considerar como un gráfico dirigido acíclico (DAG), donde cada nodo representa una

operación aplicada a su entrada de geometría, siendo los nodos de hoja los detalles

finales de la geometría a remplazar. La siguiente figura muestra un ejemplo de edificio

procedural representado como un grafo:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

48

Figura 2-27. Grafo que representa un conjunto de reglas procedurales y el resultado final del edificio

Una representación de grafos presenta la ventaja de que permite trabajar con

una interfaz visual más intuitiva, en contraste con la edición clásica textual de la

codificación de reglas.

Otra de las características es el uso de técnicas corriente de edición, como

pueden ser las típicas de copiar y pegar, aplicadas en este caso a los métodos

procedurales. El usuario puede generar un edificio nuevo o cambiar componentes de

uno ya existente, a partir de la reutilización de reglas ya configuradas que pueden

representar un estilo arquitectónico particular. En la siguiente figura se muestra un

ejemplo de un edificio generado a partir de 3 estilos completamente diferentes:

Figura 2-28. Edificio obtenido a partir de 3 edificios procedurales diferentes.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

49

RETOS ACTUALES

A pesar de que las técnicas procedurales permiten generar de manera eficiente

grandes modelos urbanos con buena cantidad de detalles, en función de la aplicación

que se le desee dar la modelo es aconsejable definir el nivel de detalle del mismo, y

los elementos geométricos que se incorporan. Así, normalmente se incorporan

simplificaciones, ya que para la mayor parte de las aplicaciones no es necesario el

nivel de detalle proporcionado por los sensores de captura de información actuales,

permitiendo un manejo más ágil de los modelos de grandes dimensiones.

Una solución clásica del modelado para los grandes modelos es introducir

técnicas de nivel de detalle, que utilizan parámetros de calidad para reducir la

complejidad. Los criterios empleados para simplificar pueden estar basados en la

distancia a puntos de interés del modelo o a estructuras semánticas de los edificios

de los que resulte de interés conservar. De esta forma se controla de forma

automática la generación de geometría, evitando una sobrecarga de datos.

Figura 2-29. Modelo urbano procedural con nivel de detalle utilizando un criterio de distancia a partir de la esfera roja

2.5. Aplicación de los modelos urbanos 3D

Los modelos urbanos hasta ahora descritos resultan ser de gran ayuda en

diversos ámbitos como son el planeamiento urbano, el diseño de infraestructuras y

edificios, la gestión de emergencias, estudios de eficiencia energética o la realización

de mapas de ruidos entre otros.

A continuación se muestran distintas iniciativas llevadas a cabo por diferentes

organismos y administraciones públicas que sirven como ejemplo para ilustrar las

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

50

múltiples aplicaciones que los modelos urbanos en tres dimensiones son capaces de

aportar cuando se construyen desde la perspectiva integradora, actuando como una

representación realista con una mayor capacidad de análisis.

Análisis de la contaminación por ruido en el estado de North Rhine –

Westphalia (Alemania). La directiva de Ruido Ambiental de la Unión

Europea 2002/49/EG obliga a los estados miembros a determinar cada 5

años la emisiones sonaras de las principales carreteras y vías férreas,

aeropuertos, lugares de actividad industrial y aglomeraciones urbanas,

además de documentas los resultados a mediante mapas de ruido. Esta

directiva plantea unos altos requisitos, como tener un gran número de

datos geográficos a nivel estatal, asó como datos georreferenciados y

temáticos en 3 dimensiones (terrenos, edificios, ferrocarriles, carreteras).

Para proporcionar esta considerable cantidad de datos 3D a nivel estatal,

el estado de North Rhine-Westphalia (NRW) sigue un concepto de

implementación moderno, el uso sostenible y ampliación de la

infraestructura de datos espacial GDI NRW. NRW proporciona por

primera vez datos geoespaciales en 3D a nivel estatal como elementos

en el estándar CityGML de OGC web features services (modelos de

edificios en 3D con un nivel de detalle LoD1, carreteras en 3D y datos de

ferrocarril) y un modelo digital del terreno con un paso de malla de 10 m

a través de OGC Web Coverage Service. http://www.ikg.uni-

bonn.de/uploads/tx_ikgpublication/071105_ec_gi_gis_fullpaper_czerwins

ki.pdf

Figura 2-30. Modelización de una fuente de emisión de ruido usando datos CityGML en 3D

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

51

Figura 2-31. Mapa de ruido generado a partir de datos CityGML

Creación de un modelo 3D de la ciudad de Berlín (Alemania) con

información semántica asociada correspondiente tanto a datos catastrales

como al potencial solar de los tejados de los edificios modelados

(posibilidad de instalar paneles fotovoltaicos, producción de electricidad

estimada, reducción de emisiones de CO2, inversión a realizar,…)

http://www.businesslocationcenter.de/en/berlin-economic-atlas

Desde esta página se puede explorar Berlín tanto en 2 como en 3

dimensiones. Berlín es la primera ciudad en Alemania de la que cualquier

usuario de Internet puede obtener un modelo realístico de gran escala. A

través de este esquema de atlas económico, el usuario puede examinar

mapas, mostrar edificios en 3D y obtener información detallada sobre el

entorno urbano de Berlín.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

52

Figura 2-32. Atlas económico de Berlín

Para crear el modelo, unos 540000 edificios en un área en torno a 890

km2 fueron medidos mediante fotogrametría aérea, siendo sus tejados

capturados mediante LIDAR. Adicionalmente también se crearon unos 80

modelos detallados de edificios emblemáticos, algunos de los cuales

pueden visitarse incluso en su interior (Olympic Stadium, Sony Center…).

Junto con esta información de carácter geométrico, el modelo ha sido

enriquecido al incorporarle información sobre la economía de Berlín y su

infraestructura. Es importante tener en cuenta que este modelo ha sido

creado con objetivo no comercial, sino de gestión de la ciudad, y para

posibilitar el desarrollo de nuevas aplicaciones que aporten valor añadido.

http://www.businesslocationcenter.de/en/berlin-economic-atlas/the-

project/project-examples/solar-atlas

Un ejemplo de aplicación lo constituye, por ejemplo, el atlas solar en el

que se muestra el potencial solar de cada edificio en la ciudad en

imágenes claras en 2D y 3D. Propietarios e inversores pueden utilizarlo

para saber si el tejado de un edificio es adecuado para una instalación

solar y si la inversión será amortizada. Este atlas proporciona información

clave a través de una ojeada como puede ser la energía potencial de

salida, reducciones en emisiones de CO2, y costes de inversión.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

53

Figura 2-33. Atlas solar de Berlín

3. Aplicación de la Metodología

3.1. Zona de estudio

La zona elegida para ser modelizada en 3D se trata de la Plaza de España y sus

alrededores, encontrándose situada en Madrid en las siguientes coordenadas UTM:

X=439589.500 m Y=4474971.320 m

A continuación se muestra una imagen de Google Earth donde puede ubicarse

la zona de trabajo, la cual está marcada mediante un polígono.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

54

Figura 3-1. Zona elegida a modelar

Destacan en los alrededores, por su altura, dos edificios de hormigón, la Torre

de Madrid (1957) y el Edificio de España (1953). De esta plaza salen las calles de

Gran Vía, Princesa y la Cuesta de San Vicente. Se encuentra también junto a la calle

de Bailén, lo que la sitúa junto al Palacio Real de Madrid.

3.2. Instrumentación y software empleado

En este apartado se describen los instrumentos y programas empleados para

realizar el presente trabajo.

A) Instrumentación

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

55

Ordenador portátil Acer V3-572G-70ES

- 8Gb de Ram

- Intel Core i7-4510U 2.0 GHz

- NVIDIA GeForce 840M

B) Software

ArcGIS: Es sin duda el referente internacional en el ámbito de los

Sistemas de Información Geográfica. Se trata de un software

comercial desarrollado y distribuido por ESRI. Sirve para

administrar datos, crear mapas y llevar a cabo análisis espaciales.

Permite el tratamiento de todo tipo de información geográfica, ya

sean imágenes, archivos vectoriales o raster, o nubes de puntos. El

software permite el obtener una versión de prueba gratuita con

limitaciones de uso en cuanto al tiempo, pero con funcionalidad

completa.

CityEngine: desarrollado también por ESRI, se caracteriza por el

empleo de reglas procedurales para la generación de entornos

urbanos. Con él se puede utilizar información geográfica en 2D para

generar modelos urbanos en 3D. Puede obtenerse una versión de

prueba desde su página web, la cuál ha sido empleada para realizar

este Trabajo de Fin de Máster.

3.3. Desarrollo metodológico

3.3.1. Obtención de los datos

Como ya se ha explicado en el apartado de metodología, se pueden emplear

técnicas geoespaciales como la Fotogrametría y LiDAR para obtener los datos

necesarios para modelizar una ciudad. El coste de planificar y llevar a cabo un vuelo

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

56

es excesivo para el fin que se persigue con este Trabajo de Fin de Máster por lo que

se ha decidido recurrir a datos que se encuentren disponibles para su descarga en la

red.

Estos datos pueden obtenerse desde diferentes fuentes. En la página web del

IGN se pueden obtener todo tipo de datos que se encuentran accesibles al público

previo registro para poder acceder a su centro de descargas. También se encuentran

disponibles sus metadatos, de manera que podamos saber en qué fecha se obtuvieron

y de qué forma, además de hacernos una idea de la precisión que tienen estos.

Figura 3-2. Web del IGN

En concreto se han obtenido de esta página los siguientes datos:

Ortofoto PNOA de máxima actualidad: en formato ECW, y sistema

geodésico de referencia ETRS89 y proyección UTM 30 N. Su unidad de

distribución es y descarga es la hoja del MTN50 (Mapa Topográfico

Nacional 1:50000), resultado de componer un mosaico con las ortofotos

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

57

correspondientes a cada hoja del MTN50. La hoja correspondiente a la

zona elegida es la 0559. En el archivo xml de metadados podemos ver

algunos datos interesantes como:

- Fecha de toma: 09-03-2015

- Resolución espacial: 0.25 m

- Ortofotos con las que se ha formado el mosaico

Figura 3-3. Ortofoto PNOA

LiDAR: en formato LAZ (formato de compresión de ficheros LAS). Se

distribuye en ficheros digitales con información altimétrica de 2x2 km de

extensión. Las nubes de puntos han sido capturadas mediante vuelos con

sensor LiDAR con una densidad de 0,5 puntos/m2, y posteriormente

clasificadas de manera automática y coloreadas mediante RGB obtenido

a partir de ortofotos del PNOA con tamaño de pixel de 25 o 50 cm. Los

archivos descargados se encuentran en el sistema de referencia ETRS89

y en la proyección UTM 30 N. Las alturas de los puntos son ortométricas.

A partir del filtrado de la nube de puntos LiDAR clasificada se puede

obtener un modelo digital del terreno.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

58

Figura 3-4. Datos Lidar

MDT05: en formato ASCII. Se trata de un modelo digital del terreno con

paso de malla de 5 metros y con la misma distribución de hojas que el

MTN50. El sistema de referencia de estos datos es el ETRS89, proyección

UTM huso 30 N. Según la hoja de que se trate, este MDT se ha obtenido

de una de las dos siguientes formas: por estereocorrelación automática

de vuelos fotogramétricos del PNOA con resolución de 25 a 50cm/pixel,

revisada e interpolada con líneas de ruptura donde fuera viable, o bien por

interpolación a partir de la clase terreno de vuelos LiDAR del PNOA.

Figura 3-5. MDT del IGN

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

59

La sede electrónica del catastro dispone de un servicio de descarga de

cartografía vectorial en formato shape, a través del cual se puede acceder a la

siguiente información dentro de una población:

Elementos puntuales (árboles, señales…)

Elementos lineales

Huellas de los edificios

Calles

Para acceder a esta información es necesario un certificado o DNI electrónico.

Figura 3-6. Sede electrónica del catastro

3.3.2. Preparación de los datos

Antes de empezar a trabajar con CityEngine es necesario preparar los datos.

Para ello hay que crear una geodatabase, la cual es una colección de datos

geográficos de varios tipos y sirve como marco de administración y almacenamiento

de datos nativo para ArcGIS. Proporciona un sistema de almacenamiento de datos

escalable y un sistema de administración con mejor integridad, carga, recuperación y

seguridad de datos.

CityEngine se basa en 3 ingredientes: la geometría de los elementos, los

atributos de los elementos, y reglas procedurales. Mientras más detalle tenga cada

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

60

elemento, mayor será la complejidad y precisión con respecto al mundo real del

contenido 3D generado.

Este programa utiliza el fichero de base de datos geoespacial de Esri como su

formato de almacenamiento nativo. Esto significa que se puede emplear cualquier

dato de tipo vector geo-espacial, tal como parcelas, huellas de edificios, y redes de

calles. El modelo 3D de ciudades provee un esquema personalizado para la base de

datos geo-espacial que coge elementos existentes en 2D y usa superficies derivadas

de LiDAR de forma que se convierten en 3D para poder realizar visualizaciones y

análisis.

En primer lugar, el proceso se inicia con la creación de un proyecto nuevo en

ArcMap y se ha creado una base geo-espacial nueva, renombrándola como

“PuertadeEspaña” y estableciéndola como la base geo-espacial por defecto. Esta

localización es usada en caso de añadir nuevos datos y para guardar los datos

resultantes creados tras la edición y operaciones de geoprocesamiento. La base de

datos geo-espacial por defecto se sincroniza con el espacio de trabajo actual, de modo

que todas las salidas de las herramientas y modelos que se empleen son guardadas

en esta localización por defecto.

Para agilizar el procesado de los datos, se puede dibujar una pequeña zona de

interés mediante un polígono, recortando el resto de capas de manera que se ajusten

a esta zona. La herramienta clip es válida para esta tarea y se encuentra en la caja de

herramientas de análisis tal y como se ve en la imagen:

Figura 3-7. Herramienta clip

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

61

Como elemento de recorte se puede introducir una capa con un polígono que

dibujado que recubra toda la zona de interés.

Figura 3-8. parámetros usados con la herramienta clip

Se ha empleado la herramienta clip con todas las demás capas (ortoimagenes,

árboles, calles, parcelas, huellas de edificios…) para ajustarse a la zona de interés.

El siguiente paso es importar el esquema CIM (City Information Model), que

creará todas las clases de elementos, relaciones y tablas. Este fichero CIM es el

estándar con el que trabaja CityEngine y está basado en CityGML. Puede exportarse

posteriormente a CityGML sin problema.

Se ha creado una nueva base de datos geo-espacial, llamándola “Madrid_final”.

Haciendo clic derecho sobre ella, se pulsa en importar y se selecciona “XML

workspace document”, seleccionando importar el esquema 3DCITYINFOMODEL.xml

solamente. Este fichero XML puede obtenerse en la página web de CityEngine.

En la ventana de catálogo se pueden observar las nuevas clases de elementos,

relación y tablas creadas:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

62

Figura 3-9. Elementos, relaciones y tablas del esquema CIM

Esta base de datos geo-espacial almacena elementos y sus relaciones para

modelizar datos de ciudad a múltiples escalas y dentro de 3 principales temas:

Entorno de construcción: huellas de los edificios, modelos de edificios,

elementos interiores, instalaciones…

Entorno legal: propiedad del suelo

Entorno natural: usos del suelo

Este modelo de información de ciudad 3D es compatible como CityGML, siendo

fácil de rellenar con nuestros datos.

Para rellenar este modelo, hay que cargar los datos elegidos en cada clase de

elementos de la base de datos Madrid_final, haciendo clic con el botón derecho sobre

ellas y pulsando “Load data”.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

63

Figura 3-10. Cargando los elementos en el esquema

En la siguiente tabla aparecen los atributos del esquema 3DCIM. Algunos de

estos son rellenados automáticamente con los atributos de nuestra capa. Los

señalados como “none” podemos indicarlos nosotros mismos.

Figura 3-11. Atributos de la capa Building dentro del esquema

Dependiendo de los datos, unos campos estarán rellenados y otros no. Estos

campos listados dentro del 3DCIM están ahí para crear ciertos productos. Es posible

también que nuestros contengan más información que la que presenta el esquema.

En ese caso habría que añadir aquellos campos que fueran necesarios al esquema

antes de importar nuestros propios datos.

Este proceso ha de llevarse a cabo con las capas de árboles, calles y edificios.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

64

Una componente esencial de cualquier mapa 3D es un modelo detallado del

terreno. Este provee de una “textura” para el escenario de la ciudad, pero también

determina el emplazamiento vertical de todos los datos GIS basados en el terreno:

edificios, cobertura del suelo, mobiliario urbano, y otras instalaciones. Para obtener el

nivel de precisión requerido para un modelado del terreno realístico, es necesario

tener datos LiDAR clasificados de alta resolución.

Para el propósito de modelar el terreno y extraer elementos, hay 3 tipos de

superficies básicas usadas en los modelos 3D de ciudad. Estas superficies raster se

crean basándose en diferentes clasificaciones del retorno en los datos LiDAR.

1. Modelo Digital del Terreno (MDT). Se trata de una superficie raster que

representa la elevación del terreno desnudo, sin estructuras ni vegetación.

Se utiliza como superficie de elevación base en las escenas 3D. Se utiliza el

retorno del suelo de los puntos (último retorno) en su creación.

2. Modelo Digital de Superficie (MDS). Es una superficie raster que representa

la elevación de todas las estructuras y elementos naturales en el terreno. Es

el mismo tipo de superficie que obtendríamos si “envolviéramos” el paisaje.

Se usan los puntos de primer retorno en su obtención.

3. Modelo Digital de Superficie Normalizado (MDSn). Esta superficie se usa

para modelar la altura de las estructuras y vegetación sobre la superficie del

terreno. Es la diferencia entre el MDT y el MDS.

𝑀𝐷𝑆𝑛 = 𝑀𝐷𝑆 − 𝑀𝐷𝑇

Como ya se ha comentado anteriormente, estas superficies pueden extraerse

fácilmente a partir de los datos lidar. Para ello se sigue el siguiente proceso:

Importar los datos LiDAR

Crear el MDT a partir

de los puntos de

ultimo retorno

Crear el MDS a partir de puntos de

primer retorno

Obtener la elevación de los edificios

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

65

Importar los datos

LiDAR es una tecnología de sensor remoto

relativamente nueva que nos permite recoger muestras

muy densas de puntos de elementos en 3D. Esta ha

evolucionado hasta convertirse en una fuente común de

datos en los sistemas de información geográfica. Estas

enormes colecciones de puntos del mundo real son

típicamente almacenadas en ficheros LAS. Cada punto

LiDAR puede tener atributos adicionales como intensidad,

códigos de clase, y valores de color RGB de los que se

puede hacer uso en diferente software

LAS es el formato nativo que emplea ArcGIS. Puesto

que los ficheros LiDAR descargados del IGN se encuentran

en formato LAZ, es necesario descomprimir estos primero.

Para ello se puede emplearse el programa LASTOOLS, en

concreto la herramienta laszip.exe.

Una vez descomprimidos pueden ser importados en

ArcGIS sin ningún problema, siendo buena idea crear un

fichero LASd que recoja todos los ficheros LAS que

interese utilizar en uno solo para mayor comodidad.

La nube de puntos se muestra tal y como se ve en la imagen:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

66

Figura 3-12. Nube de puntos lidar obtenida del IGN

Para trabajar con estos datos en ArcMap es necesario activar primero las

extensiones 3D Analyst y Spatial Analyst, así como activar la barra de herramientas

LAS Dataset.

Dentro de la barra herramientas se pueden aplicar diversos filtros:

Figura 3-13. Filtros para datos lidar en ArcGIS

Aplicando un filtro para seleccionar los puntos perteneciente al terreno nos queda

lo siguiente:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

67

Figura 3-14. Puntos pertenecientes al terreno

Con estos puntos se puede obtener el modelo digital del terreno empleando la

siguiente herramienta de conversión:

Figura 3-15. Herramienta para obtener el modelo digital del terreno

Se han establecido los siguientes parámetros:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

68

Figura 3-16. Parámetros empleados para obtener el MDT

En el campo valor se indica que atributo de los datos LiDAR será utilizado para

generar el raster. En este caso nos interesa la elevación, aunque también podrían

utilizarse con otros fines la intensidad o el valor RGB.

En cuanto al tipo de interpolación se opta por la triangulación. Esta interpolación

consiste en determinar el valor de cada celda del raster de salida. El método de

triangulación utiliza una aproximación basada en TIN permitiendo acelerar el tiempo

de procesado mediante la reducción de los datos usando la técnica de la ventana de

muestreo. En este caso se opta por interpolar con el vecino más próximo.

En la siguiente imagen se muestra el MDT obtenido:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

69

Figura 3-17. MDT obtenido a partir de datos LiDAR

Para crear el modelo de superficie solamente hay que cambiar el tipo de filtrado

de los puntos LiDAR iniciales, seleccionando aquellos que son de primer retorno:

Figura 3-18. Filtrado de puntos para obtener un MDS

Los parámetros utilizados en la herramienta LAS Dataset to Raster son algo

diferentes en esta ocasión:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

70

Figura 3-19. Parámetros empleados para obtener el MDS

El enfoque binning proporciona un método de asignación para la determinación

de cada celda de salida utilizando los puntos que caen dentro de su alcance, junto con

un método relleno de huecos para determinar el valor de las celdas que no contienen

ningún punto.

Con estos parámetros se busca el punto de máxima elevación dentro de cada

celda, y si rellenan los huecos interpolando con el vecino más próximo.

El MDS obtenido se muestra a continuación, pudiendo apreciarse claramente las

zonas edificadas.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

71

Figura 3-20. MDS obtenido

Al crear el MDS, puede haber algunos elementos creados debido a problemas

del sensor y otros errores en el procesado. Idealmente los datos LiDAR no contienen

este tipo de errores. En caso de haberlos, la herramienta “Focal statistics” puede quitar

valores de elevación erróneos.

Los parámetros empleados son los siguientes:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

72

Figura 3-21. Eliminación de errores

Esta herramienta calcula una estadística de valores dentro de una vecindad

especificada alrededor de la celda de entrada. Se ha empleado un rectángulo de

dimensiones 3x3, un buscando el mínimo valor.

Tras estos pasos seguidos se obtiene el modelo de la superficie desnuda y de

los elementos sobre la superficie. El siguiente paso es crear una superficie

normalizada con las alturas absolutas de los elementos sobre el terreno estableciendo

la elevación de este último a un estándar de cero. Para hacer esto hay que sustraer

el MDT del MDS.

La herramienta “minus” es la que nos permite hacer esto, seleccionando el MDS

como superficie 1 y el MDT como superficie 2.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

73

Figura 3-22. Obtención del modelo de superficie normalizado

El resultado obtenido es:

Figura 3-23. Modelo de superficie normalizado obtenido

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

74

A partir de este MDSn, se pueden determinar las alturas de los edificios. Para

ello se ha creado una herramienta que utiliza las huellas de los edificios para

determinar su altura basándose en el modelo digital de superficie normalizado.

Figura 3-24. Parámetros para calcular la altura de los edificios

Al abrir ahora la tabla de atributos de la capa Building, se puede observar que el

campo altura total ha sido rellenado.

Figura 3-25. Altura de los edificios (Total height)

Realizado este último paso, los datos ya están listos para ser importados en

CityEngine.

Este programa puede leer los siguientes formatos: .tif, .jpeg, .png, y .img. Para

importar el terreno hay que convertir el MDT a formato TIFF y ajustarlo al área de

interés. Este MDT será utilizado como mapa de alturas al crear el terreno en

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

75

CityEngine. También se puede hacer lo mismo con la ortofoto descargada desde el

IGN y usarla como textura para el terreno.

Para ello se puede utilizar la versión raster de la herramienta clip:

Data Management tools > Raster > Raster Processing

Figura 3-26. Herramienta para recortar el terreno

De esta manera se obtienen el MDT y la ortofoto en formato tif.

3.3.3. Modelado de la ciudad en 3D

Para modelizar nuestra ciudad en 3D a partir datos geográficos se ha utilizado el

programa CityEngine. La principal componente de este programa es el proyecto. Cada

proyecto contiene un conjunto de carpetas que contienen todos los datos, reglas,

modelos y otra información.

Lo primera tarea a realizar por tanto con el programa es crear un nuevo proyecto.

En este caso Madrid_Puerta de España:

File > New > CityEngine Project

Figura 3-27. Nuevo proyecto CityEngine

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

76

Creado el proyecto, el siguiente paso es crear una nueva escena

Figura 3-28. Creación de una nueva escena

Se le asignará un nombre y por supuesto el sistema de coordenadas de los

datos empleados.

Figura 3-29. Configuración de la escena

En esta nueva escena se pueden cambiar tanto la cámara como los parámetros

de intensidad solar y ambiental.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

77

Figura 3-30. Parámetros de intensidad solar

Para añadir el terreno a la escena a partir de los datos que han sido preparados

anteriormente, se añade el MDT y la ortoimagen recortadas a la carpeta maps del

proyecto. Arrastrando el fichero MDT a la ventana de vista de escena aparece la

siguiente ventana donde se asigna la ortoimagen como textura para el terreno. Como

se puede observar el fichero esta georreferenciado.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

78

Figura 3-31. Importación del terreno

Añadido el fichero, la ventana de vista queda de la siguiente manera:

Figura 3-32. Terreno importado

A continuación, el siguiente paso sería añadir la información geográfica que

anteriormente fue guardada en una base de datos siguiendo el esquema 3DCIM. Para

ello se guarda la base de datos en la carpeta “Data” del proyecto, y se arrastra esta

hasta la ventana de vista. Aparece un menú para importar los datos donde se pueden

seleccionar las capas a importar:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

79

Figura 3-33. Importación del modelo 3DCIM

Siendo las capas de edificios, árboles y calles las que interesan para crear el

modelo urbano. Al importar los datos se observa un problema, y es que las capas no

están alineadas puesto que los datos importados no tienen información de elevación.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

80

Figura 3-34. Capas no alineadas

Para solucionar esto es necesario alinear las capas al terreno. La capa de calles

se alinea mediante la opción Align graph to terrain, eligiendo como mapa de alturas el

MDT importado anteriormente.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

81

Figura 3-35. Alineación de la red de calles

Hecho esto, se puede emplear la herramienta “Cleanup Graph” para limpiar la

red de vectores de calles de posibles errores, arreglando las intersecciones.

Para alinear los árboles se emplea la opción “Align shapes to terrain”, y se dejan

los parámetros igual que en el caso anterior. Los edificios se alinean con la misma

herramienta que los árboles, pero indicando en la función de alineación que las formas

sean trasladadas a la media.

Por último se emplea la función “Align terrain to shapes” de forma que los objetos

se impriman correctamente en el terreno, o el terreno se adapte a los objetos. Para

ello se seleccionan las 3 capas.

Figura 3-36. Alineación del terreno

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

82

Figura 3-37. Parámetros para alinear el terreno

Finalmente todas las capas quedan alineadas

Figura 3-38. Escena con todas las capas alineadas

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

83

Cuando el modelo 3D está correctamente importado, es el momento de empezar

a aplicar reglas procedurales para generar los edificios, calles y vegetación.

Estas reglas pueden ser importadas desde otros proyectos o crearse desde cero.

En el caso de los edificios se ha creado una nueva regla.

Figura 3-39. Creación de una nueva regla CGA

Normalmente los atributos de los edificios son definidos al principio del fichero

de regla (aunque pueden ponerse en cualquier parte). Estos atributos son usados a

través de todo el conjunto de reglas del fichero y pueden modificarse además fuera

de este desde el inspector. Atributos típicos pueden ser la altura total del edificio y la

altura de cada planta.

attr totalHeight = 10

attr floorheight = rand(4,5)

La primera regla suele llamarse lot, y se emplea para extruir la huella del edificio.

Lot-->

extrude(totalHeight) Mass

A continuación lo ideal es dividir el modelo extruido en sus distintas fachadas

aplicando la componente Split.

Mass -->

# divide el edificio en tejado y caras laterales

comp(f){top : Roof | side : Facade}

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

84

El resultado de aplicar esta regla es un edificio dividido en diferentes caras.

También se podría introducir una fachada frontal que fuera diferente de las laterales,

y donde hubiera una entrada.

Las fachadas y tejado también pueden modelarse. Para modelar una fachada se

procede de la siguiente forma: primero, la fachada puede descomponerse en pisos. A

continuación, los pisos pueden ser divididos en compartimentos (subdivisiones del

piso que pueden corresponderse con habitaciones por ejemplo). Un compartimento

típico puede consistir en un muro y ventanas.

Figura 3-40. Subidivisiones del edificio

Habría que definir a continuación las reglas “floor” y “Tile”. Para simplificar, se

puede utilizar una textura que se repita a lo largo de toda la fachada en función del

número de pisos.

Facade -->

setupProjection(0, scope.xy, 8*actualTileWidth, 8*actualFloorHeight)

texture(randomFacadeTexture)

projectUV(0)

Las texturas se declaran al comienzo del fichero, en este caso mediante una

constante que coge una textura aleatoria dentro de una carpeta donde tenemos todas.

const randomFacadeTexture = fileRandom("*facade_textures/f*.tif")

Por último se añade la regla del tejado. Con esta regla se pretende asignar a los

tejados una textura desde la ortofoto.

Roof --> Rooftex

Rooftex -->

setupProjection(0, world.xz, mapdimension_x, mapdimension_z)

set(material.colormap, "Orto_JPG.jpg")

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

85

projectUV(0)

translateUV(0, -mapoffset_x/mapdimension_x, -mapoffset_z/mapdimension_z)

scaleUV(0,1,-1)

Este fichero puede consultarse en el apartado de anexos, así como las reglas

empleadas para generar las calles y los árboles.

Una vez creadas o importadas estas reglas, solo hay que asignarlas. Para ello

se han de seleccionar todos los elementos de una misma capa para a continuación

asignarles el fichero .cga.

Figura 3-41. Seleccionando todos los objetos dentro de una misma capa

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

86

Figura 3-42. Asignando el fichero .cga

Una vez asignados todos los ficheros de reglas, el resultado obtenido es el

siguiente:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

87

Figura 3-43. Escena finalizada

Un modelo 3D de ciudad que conforma una base de datos con numerosos

atributos como el nombre de la calle, o el tipo de acceso o pavimento. Se pueden

cambiar diversos parámetros gracias a los ficheros de reglas generados como son el

número de farolas en las calles, o el tipo de intersección (glorietas, cruces…).

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

88

Figura 3-44. Parámetros de las intersecciones

Creación de la escena web

Esta representación visual en 3D puede compartirse a través de la red mediante

una escena web, la cual se trata de un formato optimizado que puede visualizarse a

través de CityEngine o de ArcGIS Online.

Se pueden mostrar fácilmente localizaciones específicas en la escena que

queremos que el observador vea mediante la creación de marcadores.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

89

Figura 3-45. Creación de marcadores

Cuando el observador observe la escena web irá desplazándose de un marcador

a otro, o libremente si lo desea.

Para crear la escena se seleccionan todos los objetos y se exportan al formato

escena web de CityEngine.

Figura 3-46. Exportando la escena web

Se puede observar como el modelo puede exportarse en otros formatos muy

conocidos como Wavefront OBJ o Autodesk FBX. El modelo exportado en estos

formatos se incluye en el cd proporcionado con el presente trabajo.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

90

Figura 3-47. Capas exportadas a la escena web

Ya creada la escena web, esta puede compartirse a través de ArcGIS Online,

siendo necesario tener una cuenta registrada donde subir el contenido creado con el

programa.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

91

Figura 3-48. Compartiendo la escena web

La escena web obtenida puede visualizarse mediante el siguiente enlace:

http://arcg.is/1lPmrXz

En ella pueden consultarse los atributos que posee cada elemento de la escena

así como activar o desactivar las diferentes capas.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

92

Figura 3-49. Escena web

Puede observarse como quedaría el nuevo edificio de oficinas (el edificio blanco)

que se ha modelado a través de código en CityEngine, y podría llegar a realizarse

incluso un estudio de sombras para ver la sombra que proyecta sobre el parque

(importante para saber cuanta luz recibe la vegetación) o un análisis de visibilidad para

ver como afecta al resto de edificios de alrededor.

Figura 3-50. Edificio nuevo generado mediante métodos procedurales

También pueden observarse algunos edificios emblemáticos como la Torre de

Madrid o el Edificio España.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

93

Figura 3-51. Edificio España y Torre de Madrid

3.3.4. Aplicación del Modelo. Análisis solar

Una de las aplicaciones que se le pueden dar al modelo obtenido, es el análisis

solar en edificios. Para ello es necesario separar los tejados en una capa aparte de

las paredes. Partiendo del proyecto anterior se puede asignar una nueva regla

procedural a los edificios donde se haga esta separación.

El primer paso es seleccionar todos los edificios y limpiar las formas para corregir

posibles errores. Seguidamente se usa la función Shapes > Separate Faces de

manera que los bloques queden divididos en caras.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

94

Figura 3-52. Limpiando las formas

Tras esto se ha creado una nueva regla procedural la cual se ha asignado a los

edificios:

attr GetTheRoofs = true

attr totalHeight = 10

GetRoofs -->

extrude(totalHeight)

alignScopeToAxes()

comp(f){ vertical: Rest | all : Roofs}

Roofs -->

case GetTheRoofs:

texture("")

color(1,1,0)

Roofs.

else:

NIL

Al pulsar el botón de ocultar/mostrar formas solo quedan visibles

los tejados en color amarillo.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

95

Figura 3-53. Tejados extraídos

Estos tejados pueden ser exportados a una nueva base de datos, la cual se

utilizará posteriormente en ArcGIS para hacer el análisis. File > export models

Figura 3-54. Exportar como geodatabase

Los muros también pueden ser extraídos. Activando las formas de nuevo y

cambiando el parámetro GetRoofs de verdadero a falso.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

96

Figura 3-55. Extracción de los muros

Estos muros son exportados al igual que los tejados como una capa individual.

Ahora que ya están separados los muros de los tejados, el siguiente paso es

calcular la radiación solar. Para llevar a cabo este análisis, son necesarios los

parámetros de proporción dispersa (D) (fracción de radiación solar recibida

indirectamente a través de su dispersión en las nubes) y transmitividad (fracción de

radiación solar directa que pasa a través de la atmósfera). Debido a la complejidad de

la variación atmosférica, se emplean valores estimados basados en tendencias

históricas para una región. El proceso explicado a continuación se basa en métodos

desarrollados por el Dr.James M. Dyer, Profesor de Geografía en la Universidad de

Ohio.

Para calibrar estos parámetros atmosféricos se siguen los siguientes pasos:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

97

Las estimaciones de radiación se pueden obtener desde diversas fuentes,

habiendo elegido en este caso la siguiente página web: http://www.soda-

is.com/eng/services/services_radiation_free_eng.php

En esta página se encuentra disponibles varios datos de manera gratuita. En

este ejemplo se han elegido los datos HC1month de la columna plano horizontal

(radiación global).

Figura 3-56. Datos de radiación global

Obtener estimaciones de radiación

Crear entradas para la herramienta de radiación solar en nuestra zona de estudio

Determinar los valores de proporción difusa y transmitividad

Ejecutar la herramienta de raciación solar

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

98

Estos ficheros contienen los siguientes parámetros:

Figura 3-57. Parámetros del fichero de radiación global

Los últimos datos disponibles datan del año 2005, y se han introducido las

coordenadas de la zona de trabajo.

Figura 3-58. Coordenadas para los datos de radiación

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

99

Se obtiene un fichero que puede ser abierto con Excel para consultar los datos.

Lo interesante para este caso es la columna Monthly sum donde se encuentran los

valores GHI. Estos valores se han introducido en una hoja de excell que calcula los

mejores valores D y T:

Figura 3-59. Valores D y T obtenidos

Tras realizar esta operación, es necesario crear un elemento de tipo punto para

el lugar donde se realizará el análisis de radiación solar. Esto se realiza con la

herramienta ArcCatalog, haciendo click derecho sobre la base de datos creada New

> Feature Class, y estableciendo el tipo de elemento como punto y el sistema de

referencia como ETRS89 UTM zona 30 N.

Dentro de esta capa se crea un nuevo punto introduciendo las coordenadas

latitud y longitud de la zona elegida en grados decimales.

A continuación se pueden calcular las condiciones atmosféricas mediante una

herramienta previamente creada en Arcgis, introduciendo el punto de radiación solar

y el MDT.

Figura 3-60. Parámetros introducidos en la calibración atmosférica

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

100

Se obtiene un fichero .dbf. Al abrirlo en Excel aparecen los valores calculados

por la herramienta, los cuáles han de pegarse en la hoja Excel anterior de la siguiente

manera:

Figura 3-61. Parámetros de calibración atmosférica

Al final de la hoja de cálculo los valores D y T son calculados automáticamente

para cada mes:

Figura 3-62. Valores D y T

Estos datos se leen de la siguiente forma: D4T6 = proporción difusa de 0.4 y

transmitividad de 0.6.

Después de calcular estos valores, es cuando se ejecuta la herramienta de

radiación solar, donde se introducen los edificios y los árboles, así como el MDT. Se

puede observar cómo se han introducido los valores D y T correspondientes a cada

mes.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

101

Figura 3-63. Herramienta de radiación solar

Se obtiene el siguiente resultado en el cual se observa que los valores de

radiación más altos (color anaranjado) están asignados a la parte alta de los edificios

y las copas de los árboles, mientras que los valores bajos (color azul) son asignados

a las zonas de sombra.

Figura 3-64. Raster obtenido con los datos de radiación

Estos valores obtenidos en la representación raster, se asignarán a continuación

a los tejados.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

102

Para ello se emplea la herramienta SolarRadiationRoofZones usando los

siguientes parámetros, donde se introducen el fichero raster de radiación generado

anteriormente así como los tejados y muros extraídos en CityEngine.

Figura 3-65. Herramienta radiación en los tejados

Los nuevos edificios 3D generados tienen los valores de radiación asignados.

El modelo añade los siguientes nuevos campos a los edificios:

Radiación solar: son los valores promedio anuales de la radiación solar

para cada techo (en kilovatios-hora por metro cuadrado por día o

kWh/m2/día).

Idoneidad solar: idoneidad de cada techo para la generación de energía

solar (en kilovatios-hora por metro cuadrado por día o kWh/m2/día).

o Idoneidad >= 1.72 kWh/m2/dia

o No idoneidad < 1.72 kWh/m2/dia

Potencial solar: potencial de generación solar basado en la radiación

entrante para cada techo (en kilovatios-hora por metro cuadrado por día

o kWh/m2/día).

o Excelente: > 2.11 kWh/m2/dia

o Bueno: 1.72 - 2.11 kWh/m2/dia

o Pobre: 1.42 – 1.72 kWh/m2/dia

o No idoneidad: < 1.42 kWh/m2/dia

El resultado es el siguiente:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

103

Figura 3-66. Potencial solar

Figura 3-67. Idoneidad solar

Estos datos de radiación obtenidos pueden utilizarse para realizar mapas o

incluirse directamente en una nueva capa para ser integrados en nuestro modelo

urbano 3D. Esta última opción sería la ideal, contribuyendo a la creación de un modelo

inteligente de la ciudad donde los inversores o compradores podrían ver si merece la

pena realizar una inversión en paneles solares, o cuántos de estos pueden colocar

según la superficie del tejado.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

104

4. Conclusiones

La información geoespacial se encuentra bastante accesible hoy en día y puede

aprovecharse en nuestro beneficio. Con datos abiertos y disponibles en la red se ha

conseguido obtener un modelo urbano 3D con un nivel de detalle LoD 2 según el

estándar CityGML. Este último no ha sido empleado en este trabajo puesto que

CityEngine tiene el suyo propio (3DCIM) el cual está basado y es totalmente

compatible con CityGML.

Este nivel de detalle puede incrementarse añadiendo texturas reales a los

edificios, y detalles como balcones o las formas de los tejados. Mayor detalle

conllevará más tiempo de trabajo y es por ello que hay que tener en cuenta cual es el

fin del modelo a generar. Para planificar no es necesario tener un detalle excesivo, en

cambio si quieren utilizar estos modelos con fines más visuales, como la industria

cinematógrafica por ejemplo puede que sea necesario obtener un nivel de detalle

mayor.

Para obtener este nivel de detalle sería interesante emplear otras técnicas

geomáticas como son el láser escáner, de forma que se puedan obtener los edificios

tal y como son en la realidad, lo cual también conllevaría un mayor tiempo de

procesamiento para el ordenador y para el técnico encargado de llevar a cabo el

trabajo.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

105

Una solución posible es establecer niveles de detalle según la cercanía a un

punto, o por zonas. También se pueden modelizar con mayor detalle solo los edificios

más emblemáticos cuando se tengan fines visuales.

Las aplicaciones de estos modelos son muy variadas tal y como se ha visto, por

lo que ideal sería tener un modelo en 4D donde se puedan consultar diferentes capas

de información, las cuales vayan actualizándose continuamente en el tiempo.

En cuanto a la difusión de estos modelos, se pretende que estén disponibles

para todo el mundo a través de servicios web, de manera que los ciudadanos puedan

beneficiarse de esto, contribuyendo de esta forma al desarrollo de unas ciudades más

inteligentes donde la información sea accesible para todo el mundo.

5. Bibliografía

AMELIBIA HERNANDO, I. (2013) CityGML: modelado urbano 3D. Jornadas

Ibericas de Infraestructuras de Datos Espaciales IV.

BALSAVIAS, E.P. (2000). Geometric transformations and registration of images,

orthoimage generation and mosaicing. Institude of Geodesy and Photogrammetry,

ETHZ Zurich.

BESUIEVSKY, G.; PATOW, G. (2014) GIS & Modelado Procedural. Grupo de

Geometría y Gráficos, Universitat de Girona.

CZERWINSKI, A.; SANDMANN, S.; STÖCKER-MEIER, E.; PLÜMER, L. (2007)

Sustanaible SDI for EU noise mapping in NRW – best practice for INSPIRE.

International Journal for Spatial Data Infrastructure Research.

DÖLLNER, J.; BAUMANN, K.; BUCHHOLZ, H. (2006) Virtual 3D City Models as

Foundation of Complex Urban Information Spaces. University of Potsdam, Hasso-

Plattner-Institut.

ERAN SADEK SAID B. MD SADEK; SAYED JAMALUDIN B. S. ALI & MOHD.

ROSDI B. MD. KADZIM. The Design and Development of a Virtual 3D City Model.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

106

Department of Surveying Science and Geomatics Faculty of Architecture, Planning

and Surveying

FORD, M.; CADZOW, S.; WILSON, D.; PARSLOW, P.; PRANDI, F.; DE AMACIS,

R. (2013). Using 3D Urban Models to Aid Simulation, Analysis and Visualisation of

Data for Smart City Web Services (i-SCOPE). Proceedings of the Workshop

"Environmental Information Systems and Services - Infrastructures and Platforms

2013 - with Citizens Observatories, Linked Open Data and SEIS/SDI Best

Practices" co-located with the International Symposium on Environmental Software

Systems 2013.

GRÖGER G.; H. KOLVE T.; NAGEL C.; HÄFELE K.H. (2012). OGC City

Geographic Markup Language (CityGML) Encoding Standard. Open Geospatial

Consortium.

PALÀ, V.; CORBERA, J. (2003). Necesidades y técnicas de obtención de un

modelo urbano 3D verdadero: una solución y soporte para la navegación y

localización en ciudades. Institut Cartogràfic de Catalunya. Instituto de Navegación

de España.

PÉREZ GARCÍA, J.L.; DELGADO GARCÍA, J. (2014). Apuntes de la asignatura

de Sistemas Lidar y MMS. Máster en Tecnologías Geoespaciales aplicadas a la

gestión inteligente del territorio (No publicado).Universidad de Jaén.

PÉREZ GARCÍA, J.L.; DELGADO GARCÍA, J. (2014). Apuntes de la asignatura

de Tratamiento, Análisis e Integración de MDT y MDS. Máster en Tecnologías

Geosespaciales aplicadas a la Gestión Inteligente del Territorio (No publicado).

Universidad de Jaén.

PÉREZ GARCÍA, J.L.; DELGADO GARCÍA, J.; CARDENAL ESCARCENA, F.J.

(2013). Apuntes de fotogrametría y teledetección 3. Grado en Ingeniería

Geomática y Topografía. (No publicado) Universidad de Jaén.

PRIETO, I.; IZAKARA, J.L.; EGUSKIZA, A. (2013). Modelo de Información

Multiescala Urbana 3D para la gestión integral sostenible de la ciudad.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

107

SANTOS PÉREZ, L.J. (2005). Ortofoto verdadera (True-Ortho) y Lídar, el posible

futuro de la cartografía catastral urbana. D.G. del Catastro. Madrid.

SEGURA SÁNCHEZ, R.J.; JIMÉNEZ PÉREZ, J.R. (2014). Apuntes de la

asignatura de Realidad Virtual y Aumentada. Modelización 3D. Máster en

Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio. (No

publicado) Universidad de Jaén.

PÁGINAS WEB

3D Cities [http://desktop.arcgis.com/en/3d/3d-cities/]

Introducción a City Engine

[https://desktop.arcgis.com/en/cityengine/latest/tutorials/introduction-to-the-

cityengine-tutorials.htm]

6. Anexos

6.1. Código empleado para generar los edificios

/**

* File: imagen_satelite_tejados.cga

* Created: 21 Oct 2015 10:49:20 GMT

* Author: antonio

*/

version "2015.1"

attr totalHeight = 10

attr floorheight = rand(4,5)

actualFloorHeight =

case scope.sy >= floorheight : scope.sy/rint(scope.sy/floorheight)

else : scope.sy

actualTileWidth =

case scope.sx >= 2 : scope.sx/rint(scope.sx/4)

else : scope.sx

const randomFacadeTexture = fileRandom("*facade_textures/f*.tif")

# dimension of the satellite map

const mapdimension_x = 593 #change this to satellite image details

const mapdimension_z = 502 #change this to satellite image details

# offset of the satellite map

const mapoffset_x = 439338.2501 #change this to satellite image details

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

108

const mapoffset_z = -4475346.250 #change this to satellite image details

Lot-->

extrude(totalHeight) Mass

Mass -->

# split building mass into roof and side faces

comp(f){top : Roof | side : Facade}

Facade -->

setupProjection(0, scope.xy, 8*actualTileWidth, 8*actualFloorHeight)

texture(randomFacadeTexture)

projectUV(0)

Roof --> Rooftex

Rooftex -->

setupProjection(0, world.xz, mapdimension_x, mapdimension_z)

set(material.colormap, "Orto_JPG.jpg") #change this

projectUV(0)

translateUV(0, -mapoffset_x/mapdimension_x, -mapoffset_z/mapdimension_z)

scaleUV(0,1,-1)

6.2. Código empleado para generar las calles

/**

* File: Complete Street.cga

* Created: 1/26/2015 Jan 2015

* Author: Esri Redlands (based on work by Esri R&D Center Zurich)

*/

# Differences to Street Construction Simple:

# This ruleset can also generate stop markings and crosswalks (by using the

# objects attributes) and generates more detailed roundabouts

# Differences to Street Construction Standard:

# More informed by MUTCD/AASHTO/NACTO Street Guidelines, but used

approximations.

# Can create Bus lanes, bike lanes (of different colors), parking lanes

(with parklets),

# medians (with alternative planting configurations), boulevards(double

medians), and even

# highways with HOV lanes, bridge supports, and shoulders (in center type

and bicycle buffer).

#

#Sources for Reports and Descriptions:

#1.http://www.fhwa.dot.gov/publications/research/safety/09039/03.cfm

#2.http://mutcd.fhwa.dot.gov/index.htm

#3.http://www.qcode.us/codes/southpasadena/view.php?topic=36-3-36_310-

36_310_080

#4.http://nacto.org/usdg/

#5.http://nacto.org/cities-for-cycling/design-guide/

#6.https://bookstore.transportation.org/collection_detail.aspx?ID=110

#7.http://transweb.sjsu.edu/project/1005.html

#8.http://onlinepubs.trb.org/onlinepubs/nchrp/nchrp_rpt_504.pdf

#Useful Numbers:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

109

#13 feet ==3.9624 Meters

#12 feet ==3.6576 Meters

#11 feet ==3.3528 Meters

#10 feet ==3.048 Meters

#9 feet ==2.7432 Meters

#8 feet ==2.1336 Meters

#7 feet ==1.8288 Meters

#6 feet ==1.524 Meters

#4 feet ==1.2192 Meters

#3 feet ==.9144 Meters

#2 feet ==.6096 Meters

#1 feet ==.3048 Meters

#1/2 feet ==.1524 Meters

#1 inch ==.0254 Meters

version "2014.1"

###################################################

# Control Attributes-INSPECTOR

#

@Group("DISPLAY OPTIONS",0) @Order(1)@Description("When true, textures are

on display, when false textures are removed. If true it deletes an unused

UVset (see comments for details).")

attr Display_Textures = true

@Group("DISPLAY OPTIONS") @Order(2) @Description("Visually colors the

entire street model based on the attributes of a street. Usage thematic

looks best when textures are turned off.")

@Range("Thematics Off", "Solid Color", "Peak Runoff/Permeability","Bike

Stress","Pedestrian Stress","Auto Stress","Transit Stress","Usage")

attr Display_Thematics = "Thematics Off"

@Group("DISPLAY OPTIONS") @Order(3) @Description("When the Solid Color

thematic is used for highlighting certain streets, this chooses the color

that is utilized by the thematic.")

attr Solid_Color = "#FFFFFF"

@Group("DISPLAY OPTIONS") @Order(4)@Description("When this attribute is

true, any time there is unallocated drainage space that is wider than 1/3

the current lane width (usually 3-4 feet), it will flag them as red. It

helps find errant streets.")

attr Flag_Empty_Space = false

@Group("DISPLAY OPTIONS") @Range("High","Low") @Order(5)@Description("This

attribute controls the level of detail of the selected textures and OBJs.

Typically a lower LOD will decrease the polygon count and texture image

resolution.")

attr LOD_Setting ="High"

texturingOn = Display_Textures # Shorthand.

thematicsOn = Display_Thematics != "Thematics Off"

coloringOn = !thematicsOn && texturingOn # Shorthand.

const peakRunoffDisplayOn = Display_Thematics == "Peak Runoff/Permeability"

const Low_LOD = case LOD_Setting=="Low":"Low" else:""

const High_LOD = case LOD_Setting=="High":"High" else:""

@Order(1)@Group("ROAD LAYOUT","Basic Components",1) @Range(0,1)

@Description("Represents the fraction of the lanes allocated to the *Right

Lanes*. If 1 or 0, they become 1 way streets.")

attr Lane_Distribution = _getInitialLaneDistribution

@Order(2)@Range(2.7,3.9624)@Description("Determines the widths of the main

travel lanes. Typically, Freeways are about 12 feet (3.6 m), Arterials 11-

12 feet (3.3-3.6 m), Collectors 10-12 feet (3.0-3.6 m), and Local roads 9-

12 feet (2.7-3.6 m).")

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

110

attr Lane_Width = (laneWidth-.2)

@Order(3) @Range("yellow","white","none") @Description("Choses color for

the centerline if there is a center line. This attribute does nothing to

other center types.")

attr Centerline_Color = _getInitialCenterline

@Order(4) @Range("right-hand","left-hand")@Description("Orients the road

for right vs. left traffic. Please note that some aspects of the rule do

not *flip* when this is changed such as the median.")

attr Traffic_Direction = "right-hand"

@Order(5) @Range(0,80) @Description("A descriptive attribute that feeds

into reporting. If >= 40 mph, Design Speed is calculated as Speed_Limit

+7.5, if less than 40, design speed is assumed equal to the Speed_Limit

(see comments for details). 1 MPH==1.6093 KPH.")

attr Speed_Limit_in_MPH = _InititalSpeedLimit

@Group("ROAD LAYOUT","Stop Markings",2)

@Order(1) @Range("none","line only","with stop marking","arrows on all

lanes","arrows on side lanes","arrows for right turn") @Description("The

initial stop markings do not take into account the topology of the

intersection i.e. they need to be set manually")

attr Stop_Begin =

_getInitialStop(connectionStart,nLanesLeft+_Lt_Transit_Lane_Count)

@Order(2) @Range("none","line only","with stop marking","arrows on all

lanes","arrows on side lanes","arrows for right turn") @Description("The

initial stop markings do not take into account the topology of the

intersection i.e. they need to be set manually")

attr Stop_End = _getInitialStop(connectionEnd,

_Distribute_Right_Lanes+_Rt_Transit_Lane_Count)

@Group("ROAD LAYOUT","Crosswalk Markings",3)

@Order(1)

@Range("none","continental","ladder","transverse","dashed","solid","custom"

,"ladder custom") @Description("NACTO-High­-visibility ladder, zebra, and

continental crosswalk markings are preferable to standard parallel or

dashed pavement markings. These are more visible to approaching vehicles

and have been shown to improve yielding behavior.")

# TODO "solid","dashed","ladder"

attr Crosswalk_Begin = _getInitialCrosswalk(connectionStart)

@Order(2)

@Range("none","continental","ladder","transverse","dashed","solid","custom"

,"ladder custom")@Description("NACTO-High­-visibility ladder, zebra, and

continental crosswalk markings are preferable to standard parallel or

dashed pavement markings. These are more visible to approaching vehicles

and have been shown to improve yielding behavior.")

attr Crosswalk_End =

_getInitialCrosswalk(connectionEnd)

@Order(3) @Range(0,10) @Description("Crosswalk to Stop Bar Distance. If the

Crosswalk UV is clipping geometry, adjust this to set it back more on

angled streets. If used, stop and yield lines should be placed a minimum of

4 ft (1.2 m) from the Crosswalk-MUTCD. NACTO suggests a minimum of 8 ft

(2.44 m) in urban areas.")

attr Begin_Crosswalk_To_Stop_Bar= _getInitialGap(connectionStart)

@Order(4) @Range(0,10) @Description("Crosswalk to Stop Bar Distance. If the

Crosswalk UV is clipping geometry, adjust this to set it back more on

angled streets. If used, stop and yield lines should be placed a minimum of

4 ft (1.2 m) from the Crosswalk-MUTCD. NACTO suggests a minimum of 8 ft

(2.44 m) in urban areas.")

attr End_Crosswalk_To_Stop_Bar = _getInitialGap(connectionEnd)

@Order(5) @Range("white","yellow") @Description("Determines the color of

painted crosswalks.")

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

111

attr Crosswalk_Color = "white"

@Order(6)

@File("tif","jpg","png","tiff","gif","jpeg","psp","jsl","sgi","tga","bmp","

dds")@Description("Creates a 2 m by 2 m tile of the image selected on the

crosswalk. Keep in mind that if another painted tile is chosen, the paint

area will not appear in reporting. Defer to Crosswalk Area Reports.")

attr Custom_Crosswalk_Texture = SidewalkFolder+"/Paver Brick Red Basket

Weave.jpg"

@Order(7) @Range(0,10)@Description("This attribrute overrides the default

Crosswalk Width. NACTO- Stripe the crosswalk as wide as or wider than the

walkway it connects to.")

attr Crosswalk_Width = _crosswalkWidth

@Group("ROAD LAYOUT","On-Street Parking",5)

@Order(1)@Range("None","Parallel","Angled Nose In","Angled Back In")

@Description("Will create parking of that type with default lengths and

widths. Keep in mind, adjusting the length/width will make it lock onto

that value. To reset it to automatic default, set the Attribute Connection

Editor back to rule-defined value.")

attr Right_Parking_Type = "None"

@Order(2)@Range(0,5)@Description("Good default is 8 feet (2.4384 m) with a

minimum of 7 feet (2.1336 m) for low turn over locations for parallel

parking. Angled parking varies on angle, but a 30-45 degree depth

suggestion is 19 feet (5.7912 m). Design guideance on width varies with

conditions. ")

attr Right_Parking_Width = _ParkingWidth("Right")

@Order(3)@Range(0,10)@Description("For Parallel Parking 6.1 to 7.5 meters

long is suggested, for Angled Parking 2.4 to 3 m is suggested.")

attr Right_Parking_Length = _ParkingLength("Right")

@Order(4)@Range("None","Parallel","Angled Nose In","Angled Back

In")@Description("Will create parking of that type with default lengths and

widths. Keep in mind, adjusting the length/width will make it lock onto

that value. To reset it to automatic default, set the Attribute Connection

Editor back to rule-defined value.")

attr Left_Parking_Type = "None"

@Order(5)@Range(0,5) @Description("Good default is 8 feet (2.4384 m) with a

minimum of 7 feet (2.1336 m) for low turn over locations for parallel

parking. Angled parking varies on angle, but a 30-45 degree depth

suggestion is 19 feet (5.7912 m). Design guideance on width varies with

conditions.")

attr Left_Parking_Width = _ParkingWidth("Left")

@Order(6)@Range(0,10)@Description("For Parallel Parking 6.1 to 7.5 meters

long is suggested, for Angled Parking 2.4 to 3 m is suggested.")

attr Left_Parking_Length = _ParkingLength("Left")

@Order(7)@Range(0,100) @Description("Will create Parklets in Parking

spaces, it is best if the parking spaces are contiguous to the sidewalk.

The default OBJ does not have bollards or curb stops suggested by NACTO.")

attr Parklet_Percentage = 0

@Order(8)@Range(0,10) @Hidden @Description("This hidden attribute controls

the spacing the parking areas have before the current directions stopbar.")

attr Front_Parking_Spacing = 0

@Order(9)@Range(0,10) @Hidden @Description("This hidden attribute controls

the spacing the parking areas have after the crosswalk at the start of the

street in the current direction.")

attr Rear_Parking_Spacing = 0

@Group("CENTER SECTION LAYOUT","Basic Attributes", 2)

@Order(1) @Range("None","Median", "Boulevard", "Barrier","Barrier &

Shoulder","Center Turn Lane")@Description("This attribute is key to picking

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

112

a center type. If none, it is a centerline, but each choice creates

different center section layouts.")

attr Center_Type = "None"

@Order(2) @Range(0,40) @Description("Is the combined center section width

regardless of type. Does nothing for the barrier selection.")

attr Center_Width = 0

@Order(3) @Range(0,4) @Description("Is the width of the walkways created by

Median. They will override the planting width, and keep in mind there are

two walkways for Plant:Walk:Plant.")

attr WalkWay_Width = 0

@Order(4)

@Range("Walk:Plant:Walk","Walk:Plant","Plant:Walk","Plant:Walk:Plant")

@Description("Lays out the median/boulevard walkway configurations. In the

case of Plant:Walk:Plant-the walkway rule is used twice so adjust walkway

width accordingly.")

attr Planting_and_Walkway_Layout ="Walk:Plant:Walk"

@Order(5) @Range(0,10)@Description("In the case of a boulevard, this is the

combined width for the lanes and center between the walkways. Each lane set

gets half allocated space. Keep in mind this means there is forced symmetry

in lanes.")

attr Boulevard_Inside_Width = 7.1

@Order(6) @Range("Normal Lanes","Bus Lanes", "Open Space","Cycle Path")

@Description("Determines the general configurations of the inside of the

boulevard. Normal lanes will be equal to the general Lane_Width, and any

left over is filled with drainage filler.")

attr Boulevard_Configuration = "Normal Lanes"

@Order(7) @Range("Center Line","Median","Curb Buffer","Chain Link Fence",

"Gate Fence","Tubular Markers")@Description("Will create the exact center

of the lanes in the boulevard. To remove it set the width ==0.")

attr Boulevard_Center_Type = "Center Line"

@Order(8)@Range(0,10)@Description("Determines the width of the center of

the Boulevard lanes.")

attr Boulevard_Center_Width = case

Boulevard_Configuration=="Normal Lanes": PaintLineWidth*4 else: 0

@Group("CENTER SECTION LAYOUT","Median Plantings",3)@Order(1)

@Description("Chooses the grass texture for the planting locations within

the Median.")@Range ("None","Random", "Standard Grass", "Lawn 1", "Lawn 2",

"Park", "Bermuda 1", "Bermuda 2", "Bermuda Dark", "Bluegrass 1", "Bluegrass

2", "Grass Short", "Grass Thick", "St Augustine 1", "St Augustine 2",

"Light Rye") @Order(2)

attr Median_Ground_Cover = "Standard Grass"

#@Range("Random", "Conifer", "Desert", "Eudicot", "Monocot")

@Order(4)@Range(0,10) @Description("Is the approximate length of the green

space accomodating trees, it can be used to space out trees more without

walkway spacing.")

attr Median_Planting_Length = 4

@Order(5) @Range(0,15) @Description("Creates a walkway spacing between

created trees.")

attr Median_Tree_Spacing = 3

@Order(6)@Description("Determines the species of the tree/plant selected

for Tree 1. Random picks from 5 common tree types and is a good

default.")@Range("Random","Alder Buckthorn","Amazon Sword Plant","American

Chestnut","American Sycamore","Apricot","Australian

Pine","Baldcypress","Balsam Fir","Bamboo","Banana Tree","Basswood","Bay

Laurel","Black Locust","Blue Gum Eucalyptus","Boxwood","Cabbage Palm

Fern","California Bay","California Incense Cedar","California

Palm","California Redwood","California Walnut","Coconut Palm","Common

Hawthorn","Common Whitebeam","Conker Tree","Date Palm","Desert

Willow","Douglas Fir","European Beech","European Larch","Ficus","Field

Elm","Flannelbush","Flowering Dogwood","Giant Sequoia","Hedgehog

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

113

Agave","Japanese Angelica Tree","Lacy Tree Philodendron","Leyland

Cypress","Lily of the Valley","Lodgepole Pine","Mediterranean

Buckthorn","Mexican Palmetto","Mountain Mahogany","Northern Red

Oak","Norway Maple","Norway Spruce","Orange Tree","Orchid","Oval-leaved

Privet","Palm Lily","Palo Verde","Paper Birch","Parlour Palm","Prickly Pear

Cactus","Red Alder","Red Hickory","Rhododendron Azaleas","Rose","Ruffle

Palm","Saguaro Cactus","Sassafras","Scots Pine","Sea Islands

Yucca","Shadbush","Snake Plant","Southern Magnolia","Spanish

Broom","Strawberry Tree","Sugar Maple","Sunflower","Sweetgum","Umbrella

Acacia","Western Juniper","White Ash","White Oak","White Poplar","White

Willow","Witch

Hazel","","_____________________________","GENERICS","","Generic Dead

Tree","Generic Stump","Generic

Unknown","","_____________________________","PROXIES","","Algarrobo","Ameri

can Elderberry","American Pepper","American Silverberry","Athel

Tamarisk","Avocado","Black Tupelo","Buttonbush","Canada

Buffaloberry","Chinaberry Tree","Chinese Tallow Tree","Common

Hackberry","Common Holly","Common Persimmon","Desert Bitterbrush","European

Hornbeam","Giant Chinquapin","Honey Locust","Hophornbeam","Huckleberry

Shrub","Japanese Hemlock","Japanese Nutmeg","Judas Tree","Lawson

Cypress","Loblolly Bay","Mexican Buckeye","Necklacepod","Northern

Bilberry","Northern White Cedar","Octopus Tree","Osage Orange","Paper Bark

Tree","Pawpaw","Persian Silk Tree","Princess Tree","Smooth

Sumac","Sourwood","Southern Wax Myrtle","Tanoak","Tree of Heaven","Turkish

Hazel","Western Soapberry","White Mulberry","Yellow Poplar","Yew")

attr Median_Tree_1_Type = "Random"

@Order(7) @Range(0,1) @Description("Reduces the probability of Tree 1

appearing in a typical designated location.")

attr Median_Tree_1_Percentage = 1

@Order(8)@Description("Determines the species of the tree/plant selected

for secondary tree for more variation. If this is not None, Tree 2 will

appear if Tree 1 does not fire with the current percentage. This does mean

that you cannot drop tree density if you alternate

trees.")@Range("None","Random","Alder Buckthorn","Amazon Sword

Plant","American Chestnut","American Sycamore","Apricot","Australian

Pine","Baldcypress","Balsam Fir","Bamboo","Banana Tree","Basswood","Bay

Laurel","Black Locust","Blue Gum Eucalyptus","Boxwood","Cabbage Palm

Fern","California Bay","California Incense Cedar","California

Palm","California Redwood","California Walnut","Coconut Palm","Common

Hawthorn","Common Whitebeam","Conker Tree","Date Palm","Desert

Willow","Douglas Fir","European Beech","European Larch","Ficus","Field

Elm","Flannelbush","Flowering Dogwood","Giant Sequoia","Hedgehog

Agave","Japanese Angelica Tree","Lacy Tree Philodendron","Leyland

Cypress","Lily of the Valley","Lodgepole Pine","Mediterranean

Buckthorn","Mexican Palmetto","Mountain Mahogany","Northern Red

Oak","Norway Maple","Norway Spruce","Orange Tree","Orchid","Oval-leaved

Privet","Palm Lily","Palo Verde","Paper Birch","Parlour Palm","Prickly Pear

Cactus","Red Alder","Red Hickory","Rhododendron Azaleas","Rose","Ruffle

Palm","Saguaro Cactus","Sassafras","Scots Pine","Sea Islands

Yucca","Shadbush","Snake Plant","Southern Magnolia","Spanish

Broom","Strawberry Tree","Sugar Maple","Sunflower","Sweetgum","Umbrella

Acacia","Western Juniper","White Ash","White Oak","White Poplar","White

Willow","Witch

Hazel","","_____________________________","GENERICS","","Generic Dead

Tree","Generic Stump","Generic

Unknown","","_____________________________","PROXIES","","Algarrobo","Ameri

can Elderberry","American Pepper","American Silverberry","Athel

Tamarisk","Avocado","Black Tupelo","Buttonbush","Canada

Buffaloberry","Chinaberry Tree","Chinese Tallow Tree","Common

Hackberry","Common Holly","Common Persimmon","Desert Bitterbrush","European

Hornbeam","Giant Chinquapin","Honey Locust","Hophornbeam","Huckleberry

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

114

Shrub","Japanese Hemlock","Japanese Nutmeg","Judas Tree","Lawson

Cypress","Loblolly Bay","Mexican Buckeye","Necklacepod","Northern

Bilberry","Northern White Cedar","Octopus Tree","Osage Orange","Paper Bark

Tree","Pawpaw","Persian Silk Tree","Princess Tree","Smooth

Sumac","Sourwood","Southern Wax Myrtle","Tanoak","Tree of Heaven","Turkish

Hazel","Western Soapberry","White Mulberry","Yellow Poplar","Yew")

attr Median_Tree_2_Type = "None"

@Group("CENTER SECTION LAYOUT","Basic Components", 4)

@Order(5)@Range("None","Both","Right","Left") @Description("Determines

whether an object is placed and what side of the street or walkways

relevant objects are placed.")

attr Median_Bus_Stop ="None"

@Order(6) @Range("Far-side", "Mid-Block", "Near-side")@Description("Locates

bus stop in the appropriate location. Far-side is right after the last

intersection, Mid-Block is in the middle of the street, and Near-side is

near to the next intersection.")

attr Median_Bus_Stop_Location = "Far-side"

@Order(7)@Description("Will create 2 bike racks near a bus stop.")

attr Median_Bike_Rack = false

@Order(8)@Description("Will create a WayFinder near a bus stop.")

attr Median_Way_Finder = false

@Order(9)@Range("None","Both","Right","Left") @Description("Creates benches

on the edges of the walkways of the Median.")

attr Median_Benches ="None"

@Order(10)@Range(0,50) @Description("Determines the spacing between each

Bench. No shape is created in the sections in between objects.")

attr Median_Bench_Spacing =10

@Order(11)@Range("None","Both","Right","Left")@Description("Determines

whether an object is placed and what side of the street or walkways

relevant objects are placed.")

attr Median_Street_Lamps ="Both"

@Order(12)@Range(0,50) @Description("Determines the spacing between each

Street Lamp. No shape is created in the sections in between objects.")

attr Median_Street_Lamp_Spacing =10

@Group("MULTIMODAL LANES LAYOUT", "Bus and HOV

Lanes",4)@Order(1)@Range("None","Bus Lane","HOV Lane")@Description("The

controls for the bus lane also control the HOV lane. They are grouped

together because they are both considered :High Capacity Lanes:")

attr Transit_Lane ="None"

@Order(2)@Range("Right", "Left", "Both")@Description("Determines side of

street preferential lanes are allocated.")

attr Transit_Lane_Sides =_Initital_Transit_Lane_Sides # If

the street is oneway, will make initial bus lane side change accordingly

@Order(3) @Range(3,5) @Description("Determines the lane width of transit

lanes that are not Dedicated Median Bus Lanes. NACTO suggested width is 11

feet (3.3528 m) minimum for Curb side and Median bus lanes, but allows for

10 feet (3.048 m) on Off-set bus lanes.")

attr Transit_Lane_Width = 3.3528

@Order(3)@Range("Sidewalk Side","Right Most Lane","Left Most

Lane")@Description("Inserts a transit lane at the location specified. Keep

in mind this is an insertion not a lane reallocation.")

attr Transit_Lane_Position ="Right Most Lane"

@Order(4)@Range(1,304.8)@Description("MUTCD- Preferential Lanes: Markings

spaced as close as 80 feet(~24.5 m) apart might be appropriate on city

streets, while markings spaced as far as 1,000 feet (304.8 m) apart might

be appropriate for freeways.")

attr Transit_Symbol_Spacing =24.5

@Order(6)@Range("red","black") @Description("NACTO-Red colored paint should

be applied to emphasize the lane and to deter drivers from using it. Red

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

115

paint has higher installation and maintenance costs, but has been shown to

deter both unauthorized driving and parking in the bus lane.")

attr Bus_Lane_Color ="red"

@Order(7)@Range("Both","Right", "Left", "None")@Description("Controls the

white lines on the sides of preferential lanes.")

attr Transit_Paint_Line_Sides = "Both"

@Group("MULTIMODAL LANES LAYOUT", "Bike Lanes",5)@Order(2)@Range(0,6)

@Description("Desirable bike lane width adjacent to a curbface is 6 feet

(1.8288m), but rideable surface adjacent to a steet edge is 4 feet

(1.2192m) with minimum of 3 feet (0.9144m). In areas where illegal parking

is an issue, at least 5 feet (1.524m) is suggested.")

attr Right_Bike_Lane_Width =0

@Order(2)@Range(0,6)@Description("Desirable bike lane width adjacent to a

curbface is 6 feet (1.8288m), but rideable surface adjacent to a steet

edge is 4 feet (1.2192m) with minimum of 3 feet (0.9144m). In areas where

illegal parking is an issue, at least 5 feet (1.524m) is suggested.")

attr Left_Bike_Lane_Width =0

@Order(3)@Range("One-way","Two-way")@Description("The oneway option uses

the full lanewidth for each lane, while the two-way option will allocate

half of the width to each sub-lane.")

attr Bike_Lane_Type ="One-way"

@Order(4)@Range(0,6)@Description("Bicycle Buffers have desired minimums of

about 3 feet, but should be at least 18 inches wide because it is

impractical to mark a zone narrower than that.")

attr Right_Buffer_Width = 0

@Order(5)@Range(0,6)@Description("Bicycle Buffers have desired minimums of

about 3 feet, but should be at least 18 inches wide because it is

impractical to mark a zone narrower than that.")

attr Left_Buffer_Width = 0

@Order(6)@Description("If on/true, buffer is closer to the through lane,

and bicycle lane is protected from through traffic.")

attr Buffer_Protection = true

@Order(7)@Description("If on/true, parking lane is closer to the through

lane, and bicycle lane is protected from through traffic. Keep in mind how

the door zone influences bicycle lane placement.")

attr Parking_Protection = true

@Order(8)@Range("Painted Stripes","Curb Buffer","Curb Buffer with

Plantings","Curb Buffer with Trees","Solid White","Cycle Track With

Planters","Cycle Track With Tubular

Markers","Asphalt","Shoulder")@Description("This attribute controls the

bicycle buffer type and form, but also can become plain asphalt or a

shoulder.")

attr Buffer_Type ="Painted Stripes"

@Order(9)@Range(0,10)@Description("Controls the buffers spacing of objects

such as tubular markers, planters, and tree/plantings (Trees/Plants match

Sidewalk Plantings if selected).")

attr Buffer_Object_Spacing =_Default_Buffer_Object_Spacing

@Order(10)@Range(1,304.8)@Description("MUTCD- Preferential Lanes: Markings

spaced as close as 80 feet (~24.5 m) apart might be appropriate on city

streets, while markings spaced as far as 1,000 feet (304.8 m) apart might

be appropriate for freeways.")

attr Bike_Symbol_Spacing = 24.5

@Order(11)@Range(0,20) @Description("Creates conflict spacing made up by

asphalt gaps in the bike lane for approaching interesections.")

attr Bike_Conflict_Spacing = 0

@Order(12)@Range("green","black","red","blue") @Description("Determines the

color of the bike lane and bike box. Paint reporting costs adjust based on

color choices.")

attr Bike_Lane_Color ="green"

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

116

@Order(13)@Range("Both","Right", "Left", "None")@Description("Controls the

white lines on the sides of preferential lanes.")

attr Bike_Paint_Line_Sides ="Both"

@Order(14)@Range("Rare","Moderate","Frequent")@Description("Is a

descriptive attribute relating to the probability that a bike lane might be

blocked due to unloading or double parking that feeds into Thematic")

attr Level_of_Blockage ="Rare"

@Group("MULTIMODAL LANES LAYOUT","Bike Box",6)

@Order(1) @Description("Right Side Bike Box: NACTO-A bike box is a

designated area at the head of a traffic lane at a signalized intersection

that provides bicyclists with a safe and visible way to get ahead of

queuing traffic during the red signal phase. Works best if bike lane is

adjacent to sidewalk.")

attr Right_Bike_Box = false

@Order(2) @Description("Left Side Bike Box: NACTO-A bike box is a

designated area at the head of a traffic lane at a signalized intersection

that provides bicyclists with a safe and visible way to get ahead of

queuing traffic during the red signal phase. Works best if bike lane is

adjacent to sidewalk.")

attr Left_Bike_Box = false

@Order(3)@Range(1,10) @Description("Is the best fit spacing between the

bicycle symbols on the bike box. Can be increased to reduce the number of

symbols created.")

attr Bike_Box_Symbol_Spacing = 5

@Order(4)@Range(0,5.3768)@Description("NACTO-A box formed by transverse

lines shall be used to hold queuing bicyclists, typically 10-16 feet deep

(3.048-4.8768 M). Deeper boxes show less encroachment by motor vehicles.")

attr Bike_Box_Length =4.26

@Order(12)@Range("green","black","red","blue") @Description("By default,

the Bike Box will match the color of the bike lane, but this attribute can

be adjusted to override that choice. Paint reporting costs adjust based on

color choices.")

attr Bike_Box_Color_Override = Bike_Lane_Color

@Group("SIDEWALK LAYOUT","Sidewalk Attributes",7)@Description("Provides a

file picker for the texture choice. This attribute also controls the curb

buffer and median walkway textures.")

@Order(2)@File

("tif","jpg","png","tiff","gif","jpeg","psp","jsl","sgi","tga","bmp","dds")

attr Sidewalk_Texture = Default_Pavement

@Order(3) @Range(0.1,10)@Description("Adjust the scale of the sidewalk

texture.This attribute also controls the curb buffer and median walkway

textures.")

attr Sidewalk_Texture_Scale = 1

@Order(4) @Range(0,360)@Description("Adjust the angle of the sidewalk

texture. This attribute also controls the curb buffer and median walkway

textures.")

attr Sidewalk_Texture_Rotation = 0

@Order(5) @Range(0,0.4)@Description("Determines the height of the sidewalk.

Default is 4 inches tall. This attribute also controls the curb buffer and

median walkway textures.")

attr Sidewalk_Height = 0.102 # height

of sidewalk of curbs(4 inch is standard thickness) curb depth is 1.5 times

sidewalk height

@Group("SIDEWALK LAYOUT", "Sidewalk Plantings",8)

@Description("Chooses the grass texture for the planting locations on the

Sidewalk or Center Island. Bus Stops and trees will not generate if this is

set to None.")@Range ("None","Random", "Standard Grass", "Lawn 1", "Lawn

2", "Park", "Bermuda 1", "Bermuda 2", "Bermuda Dark", "Bluegrass 1",

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

117

"Bluegrass 2", "Grass Short", "Grass Thick", "St Augustine 1", "St

Augustine 2", "Light Rye") @Order(2)

attr Sidewalk_Ground_Cover = "None"

@Order(2)@Range(0,10)@Description("Controls the width of sidewalk planting

space, and the setback of the bus stop.")

attr Sidewalk_Planting_Width = 1.5

@Order(3)@Range(0,10) @Description("Is the approximate length of the green

space accomodating trees, it can be used to space out trees more without

walkway spacing.")

attr Sidewalk_Planting_Length = 5

@Order(4)@Range(0,20)@Description("Creates a walkway spacing between

created trees. Keep in mind that the benches are placed in this spacing and

must be an appropriate size to accomodate them.")

attr Sidewalk_Planting_Spacing = 5

@Order(6)@Description("Determines the species of the tree/plant selected

for Tree 1. Random picks from 5 common tree types and is a good

default.")@Range("Random","Alder Buckthorn","Amazon Sword Plant","American

Chestnut","American Sycamore","Apricot","Australian

Pine","Baldcypress","Balsam Fir","Bamboo","Banana Tree","Basswood","Bay

Laurel","Black Locust","Blue Gum Eucalyptus","Boxwood","Cabbage Palm

Fern","California Bay","California Incense Cedar","California

Palm","California Redwood","California Walnut","Coconut Palm","Common

Hawthorn","Common Whitebeam","Conker Tree","Date Palm","Desert

Willow","Douglas Fir","European Beech","European Larch","Ficus","Field

Elm","Flannelbush","Flowering Dogwood","Giant Sequoia","Hedgehog

Agave","Japanese Angelica Tree","Lacy Tree Philodendron","Leyland

Cypress","Lily of the Valley","Lodgepole Pine","Mediterranean

Buckthorn","Mexican Palmetto","Mountain Mahogany","Northern Red

Oak","Norway Maple","Norway Spruce","Orange Tree","Orchid","Oval-leaved

Privet","Palm Lily","Palo Verde","Paper Birch","Parlour Palm","Prickly Pear

Cactus","Red Alder","Red Hickory","Rhododendron Azaleas","Rose","Ruffle

Palm","Saguaro Cactus","Sassafras","Scots Pine","Sea Islands

Yucca","Shadbush","Snake Plant","Southern Magnolia","Spanish

Broom","Strawberry Tree","Sugar Maple","Sunflower","Sweetgum","Umbrella

Acacia","Western Juniper","White Ash","White Oak","White Poplar","White

Willow","Witch

Hazel","","_____________________________","GENERICS","","Generic Dead

Tree","Generic Stump","Generic

Unknown","","_____________________________","PROXIES","","Algarrobo","Ameri

can Elderberry","American Pepper","American Silverberry","Athel

Tamarisk","Avocado","Black Tupelo","Buttonbush","Canada

Buffaloberry","Chinaberry Tree","Chinese Tallow Tree","Common

Hackberry","Common Holly","Common Persimmon","Desert Bitterbrush","European

Hornbeam","Giant Chinquapin","Honey Locust","Hophornbeam","Huckleberry

Shrub","Japanese Hemlock","Japanese Nutmeg","Judas Tree","Lawson

Cypress","Loblolly Bay","Mexican Buckeye","Necklacepod","Northern

Bilberry","Northern White Cedar","Octopus Tree","Osage Orange","Paper Bark

Tree","Pawpaw","Persian Silk Tree","Princess Tree","Smooth

Sumac","Sourwood","Southern Wax Myrtle","Tanoak","Tree of Heaven","Turkish

Hazel","Western Soapberry","White Mulberry","Yellow Poplar","Yew")

attr Sidewalk_Tree_1_Type = "Random"

@Order(7) @Range(0,1)@Description("Reduces the probability of Tree 1

appearing in a typical designated location, but also controls the Tree

quantity at round abouts.")

attr Sidewalk_Tree_1_Percentage = 1

@Order(8)@Description("Determines the species of the tree/plant selected

for secondary tree for more variation. If this is not None, Tree 2 will

appear if Tree 1 does not fire with the current percentage. This does mean

that you cannot drop tree density if you alternate

trees.")@Range("None","Random","Alder Buckthorn","Amazon Sword

Plant","American Chestnut","American Sycamore","Apricot","Australian

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

118

Pine","Baldcypress","Balsam Fir","Bamboo","Banana Tree","Basswood","Bay

Laurel","Black Locust","Blue Gum Eucalyptus","Boxwood","Cabbage Palm

Fern","California Bay","California Incense Cedar","California

Palm","California Redwood","California Walnut","Coconut Palm","Common

Hawthorn","Common Whitebeam","Conker Tree","Date Palm","Desert

Willow","Douglas Fir","European Beech","European Larch","Ficus","Field

Elm","Flannelbush","Flowering Dogwood","Giant Sequoia","Hedgehog

Agave","Japanese Angelica Tree","Lacy Tree Philodendron","Leyland

Cypress","Lily of the Valley","Lodgepole Pine","Mediterranean

Buckthorn","Mexican Palmetto","Mountain Mahogany","Northern Red

Oak","Norway Maple","Norway Spruce","Orange Tree","Orchid","Oval-leaved

Privet","Palm Lily","Palo Verde","Paper Birch","Parlour Palm","Prickly Pear

Cactus","Red Alder","Red Hickory","Rhododendron Azaleas","Rose","Ruffle

Palm","Saguaro Cactus","Sassafras","Scots Pine","Sea Islands

Yucca","Shadbush","Snake Plant","Southern Magnolia","Spanish

Broom","Strawberry Tree","Sugar Maple","Sunflower","Sweetgum","Umbrella

Acacia","Western Juniper","White Ash","White Oak","White Poplar","White

Willow","Witch

Hazel","","_____________________________","GENERICS","","Generic Dead

Tree","Generic Stump","Generic

Unknown","","_____________________________","PROXIES","","Algarrobo","Ameri

can Elderberry","American Pepper","American Silverberry","Athel

Tamarisk","Avocado","Black Tupelo","Buttonbush","Canada

Buffaloberry","Chinaberry Tree","Chinese Tallow Tree","Common

Hackberry","Common Holly","Common Persimmon","Desert Bitterbrush","European

Hornbeam","Giant Chinquapin","Honey Locust","Hophornbeam","Huckleberry

Shrub","Japanese Hemlock","Japanese Nutmeg","Judas Tree","Lawson

Cypress","Loblolly Bay","Mexican Buckeye","Necklacepod","Northern

Bilberry","Northern White Cedar","Octopus Tree","Osage Orange","Paper Bark

Tree","Pawpaw","Persian Silk Tree","Princess Tree","Smooth

Sumac","Sourwood","Southern Wax Myrtle","Tanoak","Tree of Heaven","Turkish

Hazel","Western Soapberry","White Mulberry","Yellow Poplar","Yew")

attr Sidewalk_Tree_2_Type = "None"

@Group("SIDEWALK LAYOUT","Sidewalk Components",9)@Order(1)

@Order(1)@Range("None","Both","Right","Left")@Description("Determines

whether an object is placed and what side of the street or walkways

relevant objects are placed.")

attr Sidewalk_Bus_Stop ="None"

@Order(2) @Range("Far-side", "Mid-Block", "Near-side")@Description("Locates

bus stop in the appropriate location. Far-side is right after the last

intersection, Mid-Block is in the middle of the street, and Near-side is

near to the next intersection.")

attr Sidewalk_Bus_Stop_Location = "Far-side"

@Order(3) @Range(-4,4)@Description("As it stands, the Bus Stop will be as

far back as the Planting Width, if more adjustment is required, this

attribute can be used to set back the Bus Stop further back or move it

closer to the curb.")

attr Sidewalk_Bus_Stop_Setback = 1

@Order(4)@Range("None","Both","Right","Left")@Description("Will place

benches in between the spacing between Trees on the sidewalk side chosen.")

attr Sidewalk_Benches ="None"

@Order(5)@Range("None","Both","Right","Left")@Description("Determines

whether an object is placed and what side of the street or walkways

relevant objects are placed.")

attr Parking_Meters ="None"

@Order(6)@Range(0,20) @Description("Determines the spacing between each

parking meter. No shape is created in the sections in between objects.")

attr Parking_Meters_Spacing = 6.1

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

119

@Order(7) @Range(0,20) @Description("This attribute provides a way to

adjust the starting location for parking meters so that they align with on-

street parking.")

attr Parking_Meter_Setback = 9 #pushes or pulls parking

meters away

@Order(8)@Range("None","Both","Right","Left")@Description("Determines

whether an object is placed and what side of the street or walkways

relevant objects are placed.")

attr Sidewalk_Street_Lamps ="None"

@Order(9)@Range(0,50) @Description("Determines the spacing between each

Street Lamp. No shape is created in the sections in between objects.")

attr Sidewalk_Street_Lamp_Spacing =10

@Order(10)@Range("None","Both","Right","Left")@Description("Determines

whether an object is placed and what side of the street or walkways

relevant objects are placed.")

attr Traffic_Lights = "None"

@Order(11) @Description("Will create a WayFinder near a bus stop.")

attr Sidewalk_Way_Finder =false

@Order(12) @Description("Will create 2 bike racks near a bus stop.")

attr Sidewalk_Bike_Rack =false

@Group("POPULATION",80) @Range(0,300) @Order(1)

@Description("Determines the number of vehicles per KM of road length

loaded onto main throughways.")

attr Vehicles_Per_KM = 0

@Range(0,1) @Order(2)@Description("Determines the approximate percentage of

vehicles that are buses on main throughways.")

attr Mixed_Traffic_Bus_Percentage = Default_Mix_Bus

@Range(0,1) @Order(3)@Description("Determines the approximate percentage of

vehicles that are taxis on main throughways.")

attr Taxi_Percentage = 0.2

@Range(0,300) @Order(4)@Description("Determines the number of buses per KM

of road length loaded onto bus lanes only.")

attr Bus_Lane_Buses_Per_KM = 0

@Order(5) @Range(0,1) @Description("Higher the percentage, the higher the

number of people loaded onto sidewalks.")

attr People_Percentage = 0

@Order(6) @Range(0,100)@Description("Determines the number of bicyclists

per KM of road length loaded onto bike lanes only.")

attr Bicycles_Per_KM = 0

@Order(7)@Range(0,1) @Description("Higher the percentage, the higher the

parking occupancy.")

attr Parked_Car_Percentage = 0.3

@Order(8)@Hidden @Range(0,360) @Description("When parking is angled, this

determines the angle of the vehicles placed in each right side angled

parking spot.")

attr Right_Parked_Car_Angle = _Right_Car_Angle

@Order(9)@Hidden @Range(0,360)@Description("When parking is angled, this

determines the angle of the vehicles placed in each left side angled

parking spot.")

attr Left_Parked_Car_Angle = _Left_Car_Angle

@Group("CUSTOM OBJECTS",90)

@Order(1)@File("dae","dxf","gdb","kml","kmz","obj","osm","shp")@Description

("Make sure object/3D files are aligned so that UP is aligned to the Y

Axis. Keep in mind objs were inserted assuming a standard alignment.")

attr Street_Lamp_Object =Default_Lamp

@Order(2)@File("dae","dxf","gdb","kml","kmz","obj","osm","shp")@Description

("Make sure object/3D files are aligned so that UP is aligned to the Y

Axis. Keep in mind objs were inserted assuming a standard alignment.")

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

120

attr Parking_Meter_Object =Default_Parking_Meter

@Order(3)@File("dae","dxf","gdb","kml","kmz","obj","osm","shp")@Description

("Make sure object/3D files are aligned so that UP is aligned to the Y

Axis. Keep in mind objs were inserted assuming a standard alignment.")

attr Traffic_Light_Object =Default_Traffic_Light

@Order(4)@File("dae","dxf","gdb","kml","kmz","obj","osm","shp")@Description

("Make sure object/3D files are aligned so that UP is aligned to the Y

Axis. Keep in mind objs were inserted assuming a standard alignment.")

attr Wayfinder_Object =Default_WayFinder

@Order(4)@File("dae","dxf","gdb","kml","kmz","obj","osm","shp")@Description

("Make sure object/3D files are aligned so that UP is aligned to the Y

Axis. Keep in mind objs were inserted assuming a standard alignment.")

attr Bench_Object =Default_Bench

@Order(5)@File("dae","dxf","gdb","kml","kmz","obj","osm","shp")@Description

("Make sure object/3D files are aligned so that UP is aligned to the Y

Axis. Keep in mind objs were inserted assuming a standard alignment.")

attr Bike_Rack_Object =Default_Bike_Rack

@Order(6)@File("dae","dxf","gdb","kml","kmz","obj","osm","shp")@Description

("Make sure object/3D files are aligned so that UP is aligned to the Y

Axis. Keep in mind objs were inserted assuming a standard alignment.")

attr Parklet_Object =Default_Parklet

@Order(6)@File("dae","dxf","gdb","kml","kmz","obj","osm","shp")@Description

("Make sure object/3D files are aligned so that UP is aligned to the Y

Axis. Keep in mind objs were inserted assuming a standard alignment.")

attr Bus_Stop_Object =Default_BusStop

@Group("REPORTING ATTRIBUTES","Paint Reports",100)

#Default values taken from NACTO Urban Bike Design Guide, 2nd edition see

comments for details. Costs can become dated due to inflation, change as

needed.-DJW

#Paint- pigment and binder, low durability (6 months-2 years based on

conditions), low traffic

##Material cost: $.06 Sq. Ft. raw material/ $1.20-$1.60 Sq.Ft. installed.

#Epoxy- epoxy/resin, moderate durability impacted by pavement quality( 3-5

years), moderate traffic

##Material cost: $1-$3 Sq. Ft. raw material/ $8-$11 Sq.Ft. installed.

#MMA- acrylic based resin, moderate durability impacted by pavement quality

(3-6 years), moderate traffic

##Material cost: $3-$4 Sq. Ft. raw material/ $8-$11 Sq.Ft. installed.

#Thermoplastic- polymer resin, pigment, beads, filler- moderate-high

durability (5 years or longer)

##Material cost: $3-$6 Sq. Ft. raw material/ $10-$14 Sq.Ft. installed.

#Colored Pavement- bituminous pitch, sand/gravel/pigment-very durable, last

as long as typical asphalt depending on conditions

##Material cost: Pigmented asphalt typically costs 30-50% more than non

colored structural asphalt, thin overlay applications have varying costs.

@Order(1)@Range(0,20)@Description("Useful Installed costs/sq.ft.: Paint

$1.6, Epoxy/MMA: $8-11, Thermoplastic $10-14, Colored pavement: Varies. See

comments for details-(Cntr+F NACTO Urban Bike Design Guide). Costs can

become dated due to inflation, change as needed.")

attr Green_Paint_Cost_Per_Square_FT = 1.6

@Order(2)@Range(0,20)@Description("Useful Installed costs/sq.ft.: Paint

$1.6, Epoxy/MMA: $8-11, Thermoplastic $10-14, Colored pavement: Varies. See

comments for details-(Cntr+F NACTO Urban Bike Design Guide). Costs can

become dated due to inflation, change as needed.")

attr White_Paint_Cost_Per_Square_FT = 1.6

@Order(3)@Range(0,20)@Description("Useful Installed costs/sq.ft.: Paint

$1.6, Epoxy/MMA: $8-11, Thermoplastic $10-14, Colored pavement: Varies. See

comments for details-(Cntr+F NACTO Urban Bike Design Guide). Costs can

become dated due to inflation, change as needed.")

attr Yellow_Paint_Cost_Per_Square_FT =1.6

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

121

@Order(4)@Range(0,20)@Description("Useful Installed costs/sq.ft.: Paint

$1.6, Epoxy/MMA: $8-11, Thermoplastic $10-14, Colored pavement: Varies. See

comments for details-(Cntr+F NACTO Urban Bike Design Guide). Costs can

become dated due to inflation, change as needed.")

attr Red_Paint_Cost_Per_Square_FT =1.6

@Order(5)@Range(0,20)@Description("Useful Installed costs/sq.ft.: Paint

$1.6, Epoxy/MMA: $8-11, Thermoplastic $10-14, Colored pavement: Varies. See

comments for details-(Cntr+F NACTO Urban Bike Design Guide). Costs can

become dated due to inflation, change as needed.")

attr Other_Paint_Cost_Per_Square_FT =1.6

######################################################

#Bridge Attributes #

######################################################

@Group("BRIDGES",110) @Order(1) @Description("Determines the various

conditions by which the bridge rule will turn on. Occulsion functions are

used in the bridge rule and might have some errant behavior.")

@Range("Off","Concrete Extrusion Only","On, By Elevation","On,

Regardless","On, Show All Piers", "On, Flag Occlusions")

attr Bridge_Display = "Off"

@Group("BRIDGES") @Order(20) @Description("Determines the threshold

distance above the standard elevation for the bridge rule to trigger based

on Elevation.")

attr Bridge_Starts_At = 3

@Group("BRIDGES") @Order(30) @Description("Determines how thick the

supporting cement structure of the bridge is.")

attr Bridge_Thickness = 1

@Group("BRIDGES") @Order(40) @Description("Determines the distance between

Piers.")

attr Pier_Distance = 23

@Group("BRIDGES") @Order(50) @Description("Determines the width of the

Piers.")

attr Pier_Width = 2.3

# Mapped Attributes (comming from graph)

#@Group("LINK TO OBJECT ATTRIBUTES",99)

@Hidden @Order(5)@Description("For internal use and reporting, must be set

to 'Source=Object'.")

attr connectionEnd = "STREET" # built in value

attributes, needs to be sourced as Object (parent)

@Hidden @Order(6)@Description("For internal use and reporting, must be set

to 'Source=Object'.")

attr connectionStart = "STREET" # built in value

attributes, needs to be sourced as Object (parent)

@Hidden @Order(7)@Description("For internal use and

rep_getInitialCrosswalk(connectionStart)orting, must be set to

'Source=Object'.")

attr valency = 0

@Hidden @Order(8)@Description("For internal use and reporting, must be set

to 'Source=Object'.")//If these two do not connect, crosswalks with have no

default width-they must be connected.

attr sidewalkWidthLeft = rint(geometry.dv(0,unitSpace))

@Hidden @Order(9)@Description("For internal use and reporting, must be set

to 'Source=Object'.")//If these two do not connect, crosswalks with have no

default width-they must be connected.

attr sidewalkWidthRight = rint(geometry.dv(0,unitSpace))

@Hidden @Order(10) @Description("For internal use and reporting, must be

set to 'Source=Object'.")

attr SidewalkWidth = 0

@Hidden @Order(11) @Description("For internal use and reporting, must be

set to 'Source=Object'.")

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

122

attr SidewalkLength = 0

@Order(12) @Hidden @Description("For internal use and reporting, must be

set to 'Source=Object'.")

attr sidewalkSide = "Error"

@Hidden @Order(13) @Description("For internal use and reporting, must be

set to 'Source=Object'.")

attr Thematics = _Thematic

@Order(14) @Hidden @Description("For internal use and reporting, must be

set to 'Source=Object'.")

attr elevation = 0 # built in value attributes, needs to be

sourced as Object (parent)

##################

# User constants #

##################

#Folder Constants

const StreetTextureFolder = "Complete_Streets"

const LanesFolder = StreetTextureFolder+"/Lanes"

const SidewalkFolder = StreetTextureFolder+"/Sidewalks"

const ObjectFolder =

StreetTextureFolder+"/Street_Furniture_and_Objects"

const GrassFolder =

StreetTextureFolder+"/Sidewalks/Grass"

const TrafficControlFolder = ObjectFolder

+"/Dir_Traffic_controls"

const TrafficSignFolder = ObjectFolder

+"/Dir_Traffic_signs"

const LampsFolder = ObjectFolder+"/Dir_Lamps"

const MiscFolder = StreetTextureFolder+"/Misc"

#Paint Constants

const ThickPaintLineWidth = 0.5

const PaintLineWidth = 0.1016 #uvSpace 36/256

const Rumble_Strip_Len = 1.5 #FWHA 7 in wide per bump

with 5 in ashpalt spacing

const Rumble_Strip_Wid = .355 #FWHA-typically 12-16 in

wide

#SideWalk and Median Constants

const Bench_Threshold_Width = .9

const Bench_Adjuster =.5

const Default_Pavement = SidewalkFolder+"/Concrete Clean

Light.jpg"

const Planting_Threshold_Width = 2

const Median_Stop_Adjuster =-1

const CurbtoPlantingGap =.2

const Curb_Depth = 0.1524

const BusStop_Length = 12.192

const Parklet_Shift = case Parking_Protection &&

_Minof(Left_Buffer_Width+Left_Bike_Lane_Width,Right_Buffer_Width+Right_Bike

_Lane_Width)>0:0 else:-_EmptySpace #if parking protection is on a shift

will lead to geometric collision, but it will choose to collide if oneside

does not have a bikelane/buffer (check later).

const Max_Sidewalk_Gap = 5.4 #change this if you want a

smaller or larger gap between first tree splits and crosswalks

#Bike Constants

const Buffer_StartGap =.2

const Bike_Lane_Twoway_Distribution =.5

const BikeBox_Fraction =.75

const Buffer_Stripe_Length = 3.048 #Not used, but can be.

const Center_Tube_Marker_Dist =.1

const _Default_Buffer_Object_Spacing= case Buffer_Type=="Curb Buffer with

Trees":8 case Buffer_Type=="Cycle Track With Planters":2.5 else:1.5

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

123

const BikeBoxGeometryThreshold = Lane_Width

*BikeBox_Fraction+_Maxof(Right_Bike_Lane_Width,Left_Bike_Lane_Width)-.1

#Vegetation Constants

const Random_Grass =(fileRandom(GrassFolder +

"/*.jpg"))

#Parking Constants

const Angled_Gap =5

#Object Model Constants

const Default_Lamp = (LampsFolder

+"/lamp.04.single.lod0.obj")

const Default_Parking_Meter = (ObjectFolder+

"/parkingMeter.obj")

const Default_Traffic_Light = (TrafficControlFolder+

"/traffic_light.02.big_with_lamp_and_sign.lod1.obj")

const Default_WayFinder = (ObjectFolder+ "/WayFinder.obj")

const Default_Bench = (ObjectFolder+

"/Bench.obj")

const Default_Bike_Rack = (ObjectFolder+ "/Bike_Rack.obj")

const Default_Parklet = (ObjectFolder+

"/Parklet_"+LOD_Setting+"_LOD.obj")

const Default_BusStop = (ObjectFolder+ "/Bus_Stop.obj")

const Default_Median_End = (ObjectFolder+

"/Median_End.obj")

#####Reporting Constants#####

#Reporting fractions are based on the pixel counts of the images in

question. If you change the texture, and want to recalculate the fraction-

Download GIMP, and use the histogram tool on a selection.

const BikeSym_WhiteFraction = 0.2178

const BusSym_WhiteFraction = 0.1373

const BikeSymNoArr_WhiteFraction = 0.2570

const Buffer_WhiteFraction = 0.1934

const AngledPark_WhiteFraction = 0.0256

const ParallelPark_WhiteFraction = 0.0049

const Center_Line_Paint_Fraction = 0.55

const CenterLane_YellowFraction = 0.1194

const CenterTurnLane_YellowFraction = 0.1194#surprisingly this fraction is

almost the same as the transitions...used it

const CenterTurnLane_WhiteFraction = 0.0632#surprisingly this the avg

arrow fraction is almost the same as the transitions...used it

const Marking_Stop_WhiteFraction = 0.0796

const Marking_AvgArrow_WhiteFraction= 0.0666 #Is the average of the arrow

textures, all of them were within 2% of each other error created by using

an average is marginal

const Marking_AvgPlain_WhiteFraction= 0.03

const Crosswalk_PaintFraction = .5

const HOV_Diamond_WhiteFraction = 0.0230

const MainLane_WhiteFraction = 0.0121

#Stop Distance Reporting Constants

#AASHTO Numbers of interest: Brake reaction time: 2.5 seconds (capabilities

of most drivers), 90 percent deceleration rate: 11.2 ft/s^2- reports assume

at grade-future iterations will adapt to percent max slope.

const Break_Reaction_Time = 2.5 #s

const Deceleration_Rate = 11.2 #ft/s^2

const Design_Speed = case

Speed_Limit_in_MPH>=40:Speed_Limit_in_MPH+7.5 else: Speed_Limit_in_MPH #

see Below- value chosen is on a much lower end. Please adjust as seen fit.

Decision basis below.

# Source 8: TRB study on Design vs Speed limits: (Discussion informed by

research

#"Factors used to select design speed are functional classification, rural

versus urban,

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

124

#and terrain (used by AASHTO); AASHTO Green Book procedure, legal speed

limit,

#legal speed limit plus a value (e.g., 5 or 10 mph [8.1 to 16.1 km/h]),

anticipated volume,

#anticipated operating speed, development, costs, and consistency (state

DOTs);

#and anticipated operating speed and feedback loop (international

practices)."

#...

#While the profession has a goal to set posted speed limits near the 85th

percentile

#speed (and surveys say that 85th percentile speed is used to set speed

limits), in reality,

#most sites are set at less than the measured 85th percentile speed.

#NACTO has different design philosophy.

# "To counteract these gruesome and unnecessary injuries and fatalities,

cities should utilize

#speed control mechanisms that influence behavior, lower speeds, and in

turn, reduce injuries

#and fatalities. Embracing a proactive design approach on new and existing

streets with the goal

#of reducing speeds “may be the single most consequential intervention in

reducing pedestrian injury and fatality."1"

#Thus they put forward: "Proactive Urban Street Design: Target Speed =

Design Speed = Posted Speed"

#As a result of existing research relating to traffic speed and crash risk,

and the fact that for the most part this

#rule is designed for urban streets, if the speed limit is greater than or

equal to 40 mph (5 above NACTO suggested speed),

#The design speed is assumed to be Speed_Limit +7.5 other wise it is the

Speed_Limit- a decision between the two philosophies.

#This is a simple way to have "context sensitive" design speed, and more

complex methods maybe considered down the line.

const Brake_Reaction_Dist =

1.47*Design_Speed*Break_Reaction_Time

const Braking_Dist =

1.075*((Design_Speed*Design_Speed)/Deceleration_Rate)# Time spent actually

braking

const Stopping_Sight_Dist = Brake_Reaction_Dist+Braking_Dist

#Unit Conversion- in terms of number of unit per meter,meter^2, or meter^3-

convert by unit *conversion factor==new unit

const SquareFeet =10.7639 #per meter ^2

const Feet =3.28084 #per meter ^1

const Miles =0.00062137 #per meter ^1

const Inches =39.3701 #per meter ^1

const CubicFeet =35.3147 #per meter ^3

#Thematic Constants

const Brightness="#d7d7d7"

#Lane Constants:

const Default_Mix_Bus= case Transit_Lane=="Bus Lane":.05 else: .2

#####################

#Tree.Generateed Rules #

#####################

import Tree : "/ESRI.lib/rules/Plants/Plant_Loader.cga" # Taken from

ESRI.lib and uses its assets. Keep this in mind when using rule.

###################################################

# Initial attribute settings

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

125

# (to get a diversified default appeareance depending on initial shape,

connection object attributes and randomness)

#

_Distribute_Right_Lanes =

rint(Lane_Distribution*nLanesTotal)+_Transit_Lane_Dist_Adj #The

Transit Lane Distribution adjuster only is active if the bus lane is put on

the right to correct the bias from rounding up when transit lanes are

present

_getInitialLaneDistribution =

case initialShape.startRule=="Roundabout": 1

case (streetWidth/ Lane_Width )>=2.2 : .5

case p(0.5) : 1

else : 0

_Initital_Transit_Lane_Sides=

case Lane_Distribution==1:

"Right"

case Lane_Distribution==0:

"Left"

else:

"Both"

_getInitialCenterline =

case oneWay || initialShape.startRule=="Junction": "none" #

one way does not need centerline, neither do junctions nor roundabouts

case _through :

"yellow" # to be consistent always yellow for through traffic (= a

street/junction/freeway without stop markings at least on one side)

else :

"yellow" # Else a white centerline

_getInitialStop(connection,nLanes) =

case _hasStop(connection) && (streetLength>30):

case connection=="ROUNDABOUT": 60%: "with stop marking" else:

"arrows for right turn"

case nLanes>2 : 25%: "line only" 25%:

"with stop marking" 15%: "arrows on all lanes" 12%: "arrows on side lanes"

17%: "arrows for right turn" else: "line only"

else : 35%: "line only" 45%:

"with stop marking" 10%: "arrows on all lanes" 10%: "arrows on side lanes"

else: "line only"

else: "none"

_InititalSpeedLimit=

case nLanesTotal>5:

_Minof((nLanesTotal*10),75)

else:

35

_getInitialCrosswalk(connection) =

case _hasStop(connection) && streetLength>10 && _PedRank>.5:

"continental"

case _hasStop(connection) && streetLength>10: 85%: "continental" 5%:

"ladder custom" 5%: "transverse" else: "none"

else: "none"

_getInitialGap(connection)=

case _hasStop(connection):

2.4

else:

-2

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

126

_ParkingWidth(side) =

case side=="Right":

case Right_Parking_Type=="None":

0

case Right_Parking_Type=="Parallel":

2.44 #Door zone should have another 1-1.5 ft if parking

is on inside

else:

6.1

else:

case Left_Parking_Type=="None":

0

case Left_Parking_Type=="Parallel":

2.44 #Door zone should have another 1-1.5 ft if parking

is on inside

else:

6.1

_ParkingLength(side) =

case side=="Right":

case Right_Parking_Type=="None":

0

case Right_Parking_Type=="Parallel":

6.1

else:

2.6

else:

case Left_Parking_Type=="None":

0

case Left_Parking_Type=="Parallel":

6.1

else:

2.6

_Right_Car_Angle =

case Right_Parking_Type =="Parallel":

0

case leftHandTraffic:

120

else:

60

_Left_Car_Angle =

case Left_Parking_Type =="Parallel":

0

case leftHandTraffic:

120

else:

60

_Front_Parking_Spacing(Parking_Type) =

case Front_Parking_Spacing!=0:

Front_Parking_Spacing

else:

case Parking_Type=="Parallel":

3

case Parking_Type=="Angled Nose In":

6

case Parking_Type=="Angled Back In":

6

else:

1

_Rear_Parking_Spacing(Parking_Type) =

case Rear_Parking_Spacing!=0:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

127

Rear_Parking_Spacing

else:

case Parking_Type=="Parallel":

1

case Parking_Type=="Angled Nose In":

3

case Parking_Type=="Angled Back In":

3

else:

1

###################################################

# Internal utilities

#

#Street Length and Lanes

@Hidden @Order(1) @Range(0,30)

attr streetWidth = geometry.dv(0,unitSpace)

# REALWORLD-distance in V-direction corresponds to width of

street (in case the geometry does not contain rounded entry geometry)

@Hidden @Order(2) @Range(0,30)

attr Main_streetWidth =streetWidth-

(_LeftSplitSum+_RightSplitSum+_centerWidth+_Transit_Lane_Widths)

@Hidden @Order(3) @Range(1,6)

attr laneWidth = geometry.dv(0,unitSpace) # note

that TEXTURE-distance in V-direction corresponds to number of lanes (as

generated by CityEngine)

@Hidden @Order(4)#Only applies when rule is first set to determine if a

median/centerlane is put in place.

attr Initial_streetWidth = streetWidth-

(_LeftSplitSum+_RightSplitSum+ PaintLineWidth*4)

const streetLength = geometry.du(0,unitSpace) #

REALWORLD-distance in U-direction corresponds to length of street

const nLanesTotal = case rint(Main_streetWidth/Lane_Width

)>0:floor(Main_streetWidth/ Lane_Width ) case floor(Main_streetWidth/

Lane_Width )<=0:0 else: 1

const nLanesLeft = floor(nLanesTotal- _Distribute_Right_Lanes )

###########################################################################

############################################

#Directional

const rightHandTraffic = Traffic_Direction =="right-hand"

const leftHandTraffic = !rightHandTraffic

const oneWay = Lane_Distribution <=0 ||

Lane_Distribution>=1 #Used to be:_Distribute_Right_Lanes <=0 ||

nLanesLeft<=0

const DirectionalFlip = case rightHandTraffic:1 else:-1

# This is used to mirror UVs when right hand traffic is false

const DirectionalRotation = case rightHandTraffic:0 else:180

#Other

const _oneWayForward = (rightHandTraffic && Lane_Distribution>=1)

|| (leftHandTraffic && Lane_Distribution<=0) # in direction of graph

segment?

const _oneWayReverse = oneWay && !_oneWayForward

const _stopBegin = case Stop_Begin =="none" || _oneWayForward:

0 else: 1

const _stopEnd = case Stop_End =="none" ||

_oneWayReverse: 0 else: 1

const _neighborBegin = case _hasStop(connectionStart):1 else: 0

const _neighborEnd = case _hasStop(connectionEnd):1 else: 0

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

128

const _crosswalkWidth = case

_Maxof(sidewalkWidthLeft,sidewalkWidthRight)==0:3

else:(_Maxof(sidewalkWidthLeft,sidewalkWidthRight)+0.05)//changed to match

width of largest sidewalk +0.05 (2 inches), if 0 default is 2.

const _crosswalkBeginWidth = case Crosswalk_Begin =="none": 0 else:

(Crosswalk_Width)

const _crosswalkEndWidth = case Crosswalk_End =="none" : 0 else:

(Crosswalk_Width)

const _centerWidth = case oneWay: 0

case Center_Type=="Barrier":.98

case Center_Type=="Barrier &

Shoulder":Center_Width

case Center_Type != "None":

Center_Width

else:PaintLineWidth*4

const _Texture_Switch = case Display_Textures: 4 else: 0 # This

switch will delete the opacity map UV if texturing is on- transparencys

mess with the tree transparencies anyway. If you want UVset 4 you can

change the 4 to a 999 and it should work...but only through an unhandled

exception

const _isnotCenterline = case Center_Type != "None":0 else:1

const _Bike_Paint_Adjuster = case

Bike_Paint_Line_Sides=="Right"||Bike_Paint_Line_Sides=="None":1 else:2

const _EmptySpace =(streetWidth-(nLanesTotal* Lane_Width

+_LeftSplitSum +_RightSplitSum+_centerWidth+_Transit_Lane_Widths))/2 # is

Per Side-so combined is this *2

#Transit Lane Constants

const _Transit_Lane_Widths = case Transit_Lane=="None":0 case

Transit_Lane_Sides=="Both": 2*Transit_Lane_Width else:Transit_Lane_Width#

Is the combined width of transit lanes not in Center

const _Rt_Transit_Lane_Width= case Transit_Lane=="None":0 case

Transit_Lane_Sides=="Right" ||

Transit_Lane_Sides=="Both":Transit_Lane_Width else: 0

const _Lt_Transit_Lane_Width= case Transit_Lane=="None":0 case

Transit_Lane_Sides=="Left" || Transit_Lane_Sides=="Both":Transit_Lane_Width

else: 0

const _Transit_Lane_Dist_Adj= case Transit_Lane=="None":0 case oneWay:0

case Transit_Lane_Sides=="Right":-1 else:0 #all this constant does is

adjust the lane distribution so that transit lanes do not overly interfere

with lane distribution calculations for right transit lanes (we want it to

count as a "Lane")

const _Transit_Lane_Count = case Transit_Lane=="None":0 case

Transit_Lane_Sides=="Both":2 else:1

const _Rt_Transit_Lane_Count= case

Transit_Lane=="None"||Transit_Lane=="Left":0 else:1

const _Lt_Transit_Lane_Count= case

Transit_Lane=="None"||Transit_Lane=="Right":0 else:1

#To keep the units exact, we do not distribute the lanes, we fill empty

space with concrete (drainage).

const _through = connectionEnd=="STREET" || connectionStart=="STREET" ||

connectionEnd=="JUNCTION" || connectionStart=="JUNCTION" ||

connectionEnd=="FREEWAY" || connectionStart=="FREEWAY"

# Vegetation and Hardscape costs -------------------------------

const TreeCostAverage = 750

const GrassSurfaceCostAverage = 10 # In square meters

const HardscapePaverCost = 25 # In square meters

###################################################

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

129

#Functions #

###################################################

#Split Based and Misc Functions

_RightSplitSum=

Right_Bike_Lane_Width + Right_Parking_Width + Right_Buffer_Width

#Generates right road side features that need to be

fractions of lanewidths

_LeftSplitSum=

Left_Bike_Lane_Width + Left_Parking_Width + Left_Buffer_Width

#Generates right road side features that need to be

fractions of lanewidths

_Bike_Box_Gap(street_side)=

case street_side=="Begin" && Left_Bike_Box:Bike_Box_Length/2

case street_side=="End" && Right_Bike_Box:Bike_Box_Length/2

else:0

_MaxSplitSum=

case _RightSplitSum>=_LeftSplitSum:

_RightSplitSum

else:

_LeftSplitSum

_Orientation_Modified_SplitSum=

_MaxSplitSum-_BikeSense_Modifier

_MaxParkingSum=

case _MaxSplitSum==_RightSplitSum:

Right_Parking_Width

else:

Left_Parking_Width

_MaxBufferSum=

case _MaxSplitSum==_RightSplitSum:

Right_Buffer_Width

else:

Left_Buffer_Width

_Transit_Lane_Width_Switch(dir,Location)=

case Transit_Lane=="None":

0

case dir==0 && (Transit_Lane_Sides=="Both" ||

Transit_Lane_Sides=="Right"):

case Location==Transit_Lane_Position: # Each call of this

function has a string defining its location.

Transit_Lane_Width

else:

0

case dir==2 && (Transit_Lane_Sides=="Both" ||

Transit_Lane_Sides=="Left"):

case Location==Transit_Lane_Position: # Each call of this

function has a string defining its location.

Transit_Lane_Width

else:

0

else:

0

_tooShort(length,goal_len)= # This function will be equal to 0 (making a

split length 0 via *) if the length of a segment is less than a goal

length).

case length<goal_len: 0 else: 1

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

130

#Stop Tex Functions

_hasStop(neighbor) = neighbor=="CROSSING" || neighbor=="ROUNDABOUT" ||

neighbor=="JUNCTION_ENTRY"||neighbor=="JUNCTION"

_stopTex(stopType,lanenumber,lanestotal) =

case stopType == "with stop marking" :

case rightHandTraffic: "_stop_word" else: "_stop_word_mirrored"

case stopType == "arrows on all lanes" :

"_stop_arrows_all_"+str((case lanenumber+1>5:5 else:lanenumber+1))

case stopType == "arrows on side lanes" :

"_stop_arrows_sides_"+str((case lanenumber+1==1:1 case

lanenumber+1==lanestotal:4 else:3))

case stopType == "arrows for right turn":

"_stop_arrows_right_"+str((case lanenumber+1>4:4 else:lanenumber+1))

else

: "_stop_strip"

_stopTexPaintFractions(markings,lanenumber) =

case markings=="_stop_word"|| markings==

"_stop_word_mirrored": Marking_Stop_WhiteFraction

case

markings=="_stop_arrows_all_*":Marking_AvgArrow_WhiteFraction

case markings=="_stop_arrows_sides_1"||

markings=="_stop_arrows_sides_4":Marking_AvgArrow_WhiteFraction

case markings=="_stop_arrows_right_1"||

markings=="_stop_arrows_right_4":Marking_AvgArrow_WhiteFraction

else: Marking_AvgPlain_WhiteFraction

#Paintcontrol and Bus Furniture functions

_PaintLineControl(side,Control_String)=

case side=="Left":

case Control_String=="Both": 1

case Control_String=="Right": 0

case Control_String=="Left": 1

else: 0

else:

case Control_String=="Both": 1

case Control_String=="Right": 1

case Control_String=="Left": 0

else: 0

_Bus_Furniture_Base(Center_Section,Location,Facing_Side)=

case Median_Bus_Stop=="None":#2

0

case Location=="Far and Near Side" && Median_Bus_Stop_Location!="Mid-

Block":

case Facing_Side==0:

case Median_Bus_Stop=="Left"||Median_Bus_Stop=="Both":

BusStop_Length

else:

0

else:

case Median_Bus_Stop=="Right"||Median_Bus_Stop=="Both":

BusStop_Length

else:

0

case Median_Bus_Stop_Location=="Mid-Block" && Facing_Side==1:

BusStop_Length

#This works for the Mid_Block Section, right and left are

handled in another

#function (below) for mid-block because they occupy the same

shape.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

131

case Facing_Side==0:#2

case Median_Bus_Stop=="Right"||Median_Bus_Stop=="Both":#3

case Median_Bus_Stop_Location==Location:#4

BusStop_Length

else:#4

0

else:0#3

case Facing_Side==2:#2

case Median_Bus_Stop=="Left" ||Median_Bus_Stop=="Both":#3

case Median_Bus_Stop_Location==Location:#4

BusStop_Length

else:#4

0

else:0#3

else:#2

0

_Bus_Sidewalk_Base(Location)=

case Sidewalk_Bus_Stop=="None":

0

case sidewalkSide==Sidewalk_Bus_Stop || Sidewalk_Bus_Stop=="Both":

case Sidewalk_Bus_Stop_Location==Location:

BusStop_Length

else:

0

else:#

0

_Median_Midblock_Switch(Side,Pad_Type)=

case Pad_Type=="WalkWay":

case Median_Bus_Stop=="Both":

0

case Median_Bus_Stop=="Right":

case Side==0:

0

else:

.5

case Median_Bus_Stop=="Left":

case Side==2:

0

else:

.5

else:

0

else:

case Median_Bus_Stop=="Both":

.5

case Median_Bus_Stop=="Right":

case Side==0:

.5

else:

0

case Median_Bus_Stop=="Left":

case Side==2:

.5

else:

0

else:

0

_Bus_Alloc(Location) =.5 #Allows user to adjust

by location if customized.

_Bike_Rack_Alloc(Location) =

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

132

case Location== "Median" || Location=="Boulevard":

case Median_Bike_Rack: .2

else: 0

else:

case Sidewalk_Bike_Rack:.2

else: 0

_WayFinder_Alloc(Location) =

case Location== "Median" || Location=="Boulevard":

case Median_Way_Finder: .3

else: 0

else:

case Sidewalk_Way_Finder:.2

else: 0

_Sidewalk_CrossStop_Gap(Dir,Begin)= #Limits the amount of gap to 5.4 meters

(3 m sidewalk+2.4 crosswalkgap) Keep trees out of crosswalk/clear view for

drivers at intersections.

case Dir==0:

case Begin=="Begin":

_Minof(_crosswalkEndWidth+

End_Crosswalk_To_Stop_Bar,Max_Sidewalk_Gap)

else:

_Minof(_crosswalkBeginWidth+

Begin_Crosswalk_To_Stop_Bar,Max_Sidewalk_Gap)

else:

case Begin=="Begin":

_Minof(_crosswalkBeginWidth+

Begin_Crosswalk_To_Stop_Bar,Max_Sidewalk_Gap)

else:

_Minof(_crosswalkEndWidth+

End_Crosswalk_To_Stop_Bar,Max_Sidewalk_Gap)

_uScale = case geometry.du(0,unitSpace)>10: 1

case geometry.du(0,unitSpace)>4 : 1/2 # in case the street

is too short, we only use half of the texture

else : 1/6 # if

even shorter, we use only the start of the texture (i.e. centerline only)

#Parking Functions:

_ParParkedFacing(Side) = case Side=="Right":# This makes the park car

facing adapt to whether the street is one way etc.

case Lane_Distribution<=0:

2

case Lane_Distribution>=1:

0

else:

0

else: #Only other option is Left

case Lane_Distribution<=0:

2

case Lane_Distribution>=1:

0

else:

2

_Parklet_OneWay_Shift(Rotation)= # This function serves to make sure the

parklet is not colliding with cars on oneway streets-it modifies the

adjustment based on parking length

case Lane_Distribution==1:

case Rotation==180:

-1

else:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

133

1

case Lane_Distribution==0:

case Rotation==180:

1

else:

-1

else:

1

#Misc Functions

#_isEven(number) = (rint(abs(number))%2) == 0 #Make number positive,

round to nearest integer just in case of 6 being 5.99999999999999, or

6.000000000000001.

#_isOdd(number) = !_isEven(number)

_Maxof(num1,num2)= #Finds the max of two numbers

case num1>=num2:

num1

else:

num2

_Minof(num1,num2)= #Finds the min of two numbers

case num1<=num2:

num1

else:

num2

_PaintCost(paintColor)=

case paintColor=="green":

Green_Paint_Cost_Per_Square_FT

case paintColor=="white":

White_Paint_Cost_Per_Square_FT

case paintColor=="yellow":

Yellow_Paint_Cost_Per_Square_FT

case paintColor=="red":

Red_Paint_Cost_Per_Square_FT

else:

Other_Paint_Cost_Per_Square_FT

################################################

#Thematic Functions

_Usage(Usage) =

case Display_Thematics=="Usage":

#Please construct your own usage zones if the current ones are not

sufficient-Colors based on NACTO illustrations

case Usage=="Pedestrian":

"#FFFFFF"

case Usage=="Conflict Zones":

"#F9ECB7"

case Usage=="Bikeways":

"#6AAA70"

case Usage=="Auto":

"#C3C2C0"

case Usage=="Transit":

"#AF4E57"

case Usage=="Plantings":

"#B5DC98"

else:

"#000000"

else:

Thematics #Attribute that diverts to _Thematic

_Thematic =

case Display_Thematics=="Thematics Off":

Brightness # Started as: "#d7d7d7" as constant

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

134

case Display_Thematics=="Solid Color":

Solid_Color

case Display_Thematics=="Bike Stress":

getHexColorString(1-_BikeRank, _BikeRank, 0)

case Display_Thematics=="Auto Stress":

getHexColorString(1-_AutoRank,_AutoRank,0)

case Display_Thematics=="Transit Stress":

getHexColorString(1-_TransitRank,_TransitRank,0)

case peakRunoffDisplayOn:

"#FFFFFF"

case Display_Thematics=="Pedestrian Stress":

getHexColorString(1-_PedRank,_PedRank,0)

else:

Brightness

_BikeSense_Modifier =#changes combined "bike protection"

width based orientation-with splitsum creates distance from through lane

case ! Buffer_Protection && Parking_Protection :

(_MaxBufferSum)

case Buffer_Protection && ! Parking_Protection :

(_MaxParkingSum)

case Buffer_Protection && Parking_Protection :

0

else:

(_MaxParkingSum + _MaxBufferSum)

###########################

#Stress Metrics Rankings- Create your own or edit the existing

###########################

#Transit_Lane_Count adjusts the lane total based on the presence of one

(+1) or two (+2) bus lanes. Only matters for reporting.

_BikeRank =#Adapted from MTI Report 11-19 # Does not

take into account Boulevard Cycle Paths

case Parking_Protection && _MaxParkingSum>1 &&

(Right_Bike_Lane_Width>0 || Left_Bike_Lane_Width>0) :

case floor(((nLanesTotal/2)+(_Transit_Lane_Count/2)))<=1 &&

Speed_Limit_in_MPH<=25 && Level_of_Blockage=="Rare"

&&_Orientation_Modified_SplitSum>=4.572:

1 #LTS 1-

case

(Speed_Limit_in_MPH<25)||(floor(((nLanesTotal/2)+(_Transit_Lane_Count/2)))<

=2 && Speed_Limit_in_MPH<=30 && Level_of_Blockage=="Rare"

&&_Orientation_Modified_SplitSum>=4.2672):

.66 #LTS 2

case (floor(((nLanesTotal/2)+(_Transit_Lane_Count/2)))<=2 &&

Speed_Limit_in_MPH<=35 && Level_of_Blockage!="Frequent"

&&_Orientation_Modified_SplitSum>=4.1148):

.33 #LTS 3

else:

0 #LTS 4

case (Right_Bike_Lane_Width>0 || Left_Bike_Lane_Width>0)

&&_MaxParkingSum<=1: # Bike Lanes not along parking lane

case floor(((nLanesTotal/2)+(_Transit_Lane_Count/2)))<=1 &&

Speed_Limit_in_MPH<=30 && Level_of_Blockage=="Rare" &&

_Orientation_Modified_SplitSum>=1.8288:

1 #LTS 1

case (Speed_Limit_in_MPH<25)|| (Speed_Limit_in_MPH<=35

&&(floor(((nLanesTotal/2)+(_Transit_Lane_Count/2)))<=(case Center_Type

=="Median":2 else: 1)&& Level_of_Blockage=="Rare" &&

_Orientation_Modified_SplitSum<1.8288)):

.66 #LTS 2-speed limit has no effect so it jumps to next

highest speed limit

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

135

case (Speed_Limit_in_MPH<=35 && Level_of_Blockage!="Frequent"):

.33 #LTS 3

else:

0 #LTS 4

else:

case (((nLanesTotal)+_Transit_Lane_Count)<=3 &&

Speed_Limit_in_MPH<=25):

1 #LTS 1

case (((nLanesTotal)+_Transit_Lane_Count)<=3 &&

Speed_Limit_in_MPH<=30):

.66 #LTS 2

case (((nLanesTotal)+_Transit_Lane_Count)<=4 &&

Speed_Limit_in_MPH<=30):

.33 #LTS 3

else:

0 #LTS 4

_PedRank =#Rule creator criteria-a road with low speed

limits and less lanes is good OR a road with good separation between cars

and pedestrians and a wider sidewalk is better

case (rint((nLanesTotal/2)+(_Transit_Lane_Count/2))<=1 &&

Speed_Limit_in_MPH<=20 && _centerWidth<=7) || (_MaxSplitSum>=5 &&

_Maxof(sidewalkWidthLeft,sidewalkWidthRight)>=3.3 &&

Speed_Limit_in_MPH<=30):

1

case (rint((nLanesTotal/2)+(_Transit_Lane_Count/2))<=2 &&

Speed_Limit_in_MPH<=25) || (_MaxSplitSum>=3 &&

_Maxof(sidewalkWidthLeft,sidewalkWidthRight)>=2.5 &&

Speed_Limit_in_MPH<=35):

.8

case (rint((nLanesTotal/2)+(_Transit_Lane_Count/2))<=2 &&

Speed_Limit_in_MPH<=30) || (_MaxSplitSum>=2 &&

_Maxof(sidewalkWidthLeft,sidewalkWidthRight)>=1.8 &&

Speed_Limit_in_MPH<=40):

.6

case (rint((nLanesTotal/2)+(_Transit_Lane_Count/2))<=3 &&

Speed_Limit_in_MPH<=35)

&&(_Maxof(sidewalkWidthLeft,sidewalkWidthRight)>=1.8):

.4

case (rint(((nLanesTotal/2)+(_Transit_Lane_Count/2)))<=4 &&

Speed_Limit_in_MPH<=40) &&

(_Maxof(sidewalkWidthLeft,sidewalkWidthRight)>=1.524):

.2

else:

0

_AutoRank = #Criteria is simply based on lanewidths, on-

street parking presence,lane number (does it enable passing?), and

reduction of turning conflicts (is there a center turn lane). The top rank

is practically high way conditions with a shoulder (shoulders reduce driver

stress about accidents /reduce variance is highway performance by providing

vehicle storage).

case ((rint((nLanesTotal/2)+(_Transit_Lane_Count/2)))>=3 &&

Lane_Width >=3.6576 && _Maxof(Left_Parking_Width,Right_Parking_Width)==0)

|| (Center_Type=="Center Turn Lane" && (rint((nLanesTotal/2)

+_Transit_Lane_Count/2))>=2 && Lane_Width >=3.3528 &&

_Maxof(Left_Parking_Width,Right_Parking_Width)==0)&&

(Buffer_Type=="Shoulder" || Center_Type=="Barrier & Shoulder") :

1

case ((rint((nLanesTotal/2) +(_Transit_Lane_Count/2)))>=2 &&

Lane_Width >=3.6576 && _Maxof(Left_Parking_Width,Right_Parking_Width)==0)

|| (Center_Type=="Center Turn Lane" && (rint((nLanesTotal/2)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

136

+_Transit_Lane_Count/2))>=2 && Lane_Width >=3.3528 &&

_Maxof(Left_Parking_Width,Right_Parking_Width)==0):

.8

case ((rint((nLanesTotal/2) +(_Transit_Lane_Count/2)))>=2 &&

Lane_Width >=3.358 && (Left_Parking_Width==0 || Right_Parking_Width==0))

|| (Center_Type=="Center Turn Lane" && (rint((nLanesTotal/2)

+_Transit_Lane_Count/2))>=1 && Lane_Width >=3.048 &&

_Maxof(Left_Parking_Width,Right_Parking_Width)==0):

.6

case ((rint((nLanesTotal/2) +(_Transit_Lane_Count/2)))>=1 &&

Lane_Width >=3.048 && (Left_Parking_Width==0 || Right_Parking_Width==0))

|| (Center_Type=="Center Turn Lane" && (rint((nLanesTotal/2) +

_Transit_Lane_Count/2))>=1 && Lane_Width >=3.048 && (Left_Parking_Width==0

||Right_Parking_Width==0)):

.4

case ((rint((nLanesTotal/2) + (_Transit_Lane_Count/2)))>=1 &&

Lane_Width >=3.048) || (Center_Type=="Center Turn Lane" &&

(rint((nLanesTotal/2) +_Transit_Lane_Count/2))>=1 && Lane_Width >=3.048):

.2

else:

0

_TransitRank = #Criteria based on whether or not there are,

proper lane widths, transit dedicated lanes, painted red is

better,boulevard transit lanes are best performing (no ability to get into

transit lane)-HOV lane is treated a like a preferential bus lane-

essentially ranks a roads ability to provide preferential service

case Bus_Lane_Color== "red" && Transit_Lane =="Bus Lane" &&

Transit_Lane_Width >=3.35 &&

(rint((nLanesTotal/2))+(_Transit_Lane_Count/2))<=2 && Transit_Lane_Sides

=="Both" ||Center_Type=="Boulevard" && Boulevard_Configuration=="Bus Lanes"

&& Boulevard_Inside_Width>=6.5:

1

case Bus_Lane_Color== "red" && Transit_Lane =="Bus Lane":

.8

case Transit_Lane !="None" && Lane_Width >=3.048 &&

(rint(((nLanesTotal/2))+(_Transit_Lane_Count/2)))<=3:

.6

case Transit_Lane !="None" && Lane_Width >=3.048:

.4

case (rint(((nLanesTotal/2)) + _Transit_Lane_Count/2))<=2:

.2

else:

0

#This is the code for the decimal number to hex converter, and it is used

to create thematics based on a numerical

#critera that is normalized on a 0 to 1 scale.

#Number 0 to 1 decimal to Hexstring converter code from Chris Wilkins

#Hex string and 256 values from normal values (0 to 1).

convertNormalTo256(normalValue) = rint(normalValue * 255)

getSixteensDigitFrom256(value256) = floor(value256 / 16)

getOnesDigitFrom256(value256) = value256 -

(getSixteensDigitFrom256(value256) * 16)

# Just

# getHex256(sixteens, ones) = (sixteens * 16) + ones

getHex256String(sixteens, ones) = hexString(sixteens) + hexString(ones)

getHexColorString(normalR, normalG, normalB) =

"#" +

getHex256String(

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

137

getSixteensDigitFrom256(convertNormalTo256(normalR))

,

getOnesDigitFrom256(convertNormalTo256(normalR))

)

+

getHex256String(

getSixteensDigitFrom256(convertNormalTo256(normalG))

,

getOnesDigitFrom256(convertNormalTo256(normalG))

)

+

getHex256String(

getSixteensDigitFrom256(convertNormalTo256(normalB))

,

getOnesDigitFrom256(convertNormalTo256(normalB))

)

hexString(hexValue) =

case hexValue == 0 : "0"

case hexValue == 1 : "1"

case hexValue == 2 : "2"

case hexValue == 3 : "3"

case hexValue == 4 : "4"

case hexValue == 5 : "5"

case hexValue == 6 : "6"

case hexValue == 7 : "7"

case hexValue == 8 : "8"

case hexValue == 9 : "9"

case hexValue == 10 : "A"

case hexValue == 11 : "B"

case hexValue == 12 : "C"

case hexValue == 13 : "D"

case hexValue == 14 : "E"

case hexValue == 15 : "E"

case hexValue == 16 : "F"

else : "" #Error.

################################

# Normalization to 0 to 1 range.

const NormalMin = 0

const NormalMax = 1

#Use the following functions if you had data that can be fed into the _Rank

functions:

#dataValueAdj(dataValueOriginal,Max_Data_Value, Min_Data_Value) =

# case dataValueOriginal < Min_Data_Value: Min_Data_Value

# case dataValueOriginal > Max_Data_Value: Max_Data_Value

# else: dataValueOriginal

#normalValue(dataValue,Max_Data_Value,Min_Data_Value) =

# NormalMin + (((dataValueAdj(dataValue,Max_Data_Value,Min_Data_Value)

- Min_Data_Value )

# * ( NormalMax - NormalMin ))

# / ( Max_Data_Value - Min_Data_Value))

###################################################

###################################################

##

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

138

## RULES

##

##

###################################################

# Street Lane Texturing

#

@StartRule

# split away the crosswalks at the beginning (if any) using the special

UVSET 1

Street --> #DeleteUV if texturing is off

case _uScale==1: #IF the Street is long enough continue normally.

report("LTS (0 to 1 scale):Bicycle Stress", _BikeRank)

report("LTS (0 to 1 scale):Pedestrian Stress", _PedRank)

report("LTS (0 to 1 scale):Transit Stress", _TransitRank)

report("LTS (0 to 1 scale):Auto Stress", _AutoRank)

report("Speed:Level Braking Distance (ft)",Braking_Dist)

report("Speed:Level Braking Reaction Distance

(ft)",Brake_Reaction_Dist)

report("Speed:Level Stopping Sight Distance

(ft)",Stopping_Sight_Dist)#Design Value is rounded to nearest 5 feet.

BridgeMain

split(u,uvSpace,1){_crosswalkBeginWidth/10:

Asphalt(true,1,"Auto")

| _crosswalkBeginWidth : Crosswalk(

Crosswalk_Begin ,1)

| ~1 :

StreetWithCrosswalkEnd }

else: #If the street is too short no stop lines, no bike boxes.

report("LTS (0 to 1 scale):Bicycle Stress", _BikeRank)

report("LTS (0 to 1 scale):Pedestrian Stress", _PedRank)

report("LTS (0 to 1 scale):Transit Stress", _TransitRank)

report("LTS (0 to 1 scale):Auto Stress", _AutoRank)

report("Speed:Braking Distance (ft)",Braking_Dist)

report("Speed:Braking Reaction Distance

(ft)",Brake_Reaction_Dist)

report("Speed:Stopping Sight Distance

(ft)",Stopping_Sight_Dist)

BridgeMain

set( Right_Bike_Box ,false)

set( Left_Bike_Box ,false)

set( Stop_Begin ,"none")

set( Stop_End ,"none")

StreetWithEntries

# split away the crosswalks at the end (if any) using the special UVSET 2

StreetWithCrosswalkEnd -->

split(u,uvSpace,2){ _crosswalkEndWidth/10: Asphalt(true,1,"Auto")

| _crosswalkEndWidth : Crosswalk(

Crosswalk_End ,2)

| ~1 :

CrossWalkGap}

CrossWalkGap-->

#This solution while imperfect and vulnerable to distortion prevents

UVspace/UnitSpace conflicts from cutting geometry. User can adjust relative

gaps to compensate.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

139

split(u,unitSpace,0) {( Begin_Crosswalk_To_Stop_Bar

):Asphalt(true,1,"Auto")

|~1:StreetWithEntries

|( End_Crosswalk_To_Stop_Bar

):Asphalt(true,1,"Auto")}

# split into the two street sides (if not oneway)

StreetWithEntries -->

split(v,unitSpace,0) {~1:Drainage

|(_RightSplitSum+

_Distribute_Right_Lanes*

Lane_Width+_Rt_Transit_Lane_Width):scaleUV(0,DirectionalFlip,1)StopBox("Rig

htSide")# Will flip with a change in driving direction

| _centerWidth

:

scaleUV(0,DirectionalFlip,1)CenterLineReporting# Will flip with a change in

driving direction

|(_LeftSplitSum+nLanesLeft*

Lane_Width+_Lt_Transit_Lane_Width)

:scaleUV(0,DirectionalFlip,1)StopBox("LeftSide")# Will flip with a change

in driving direction

|~1:Drainage}

#The StopBox rule creates both the stop line and Bikebox when they are

selected,

#and then moves the rest of the space left to the dedicated lane spaces.

StopBox(RuleChoice)-->

case RuleChoice=="RightSide":

case Right_Bike_Box &&

geometry.dv(0,unitSpace)>BikeBoxGeometryThreshold :#Must be enough room,

turned on.

split(u,unitSpace,0) {~1:RightSide| Bike_Box_Length

:BikeBoxCreation("Right")}

else:

split(u,unitSpace,0)

{~1:RightSide|_stopEnd*ThickPaintLineWidth:AsphaltPainted("white",true,1,"A

uto")}

case RuleChoice=="LeftSide":

case Left_Bike_Box &&

geometry.dv(0,unitSpace)>BikeBoxGeometryThreshold: #Must be enough room,

turned on.

split(u,unitSpace,0) { Bike_Box_Length

:BikeBoxCreation("Left")|~1:LeftSide}

else:

split(u,unitSpace,0)

{_stopBegin*ThickPaintLineWidth:AsphaltPainted("white",true,1,"Auto")|~1:Le

ftSide}

else:

case RuleChoice=="RightSide":

split(u,unitSpace,0)

{~1:RightSide|_stopEnd*ThickPaintLineWidth:AsphaltPainted("white",true,1,"A

uto")}

else:

split(u,unitSpace,0)

{_stopBegin*ThickPaintLineWidth:AsphaltPainted("white",true,1,"Auto")|~1:Le

ftSide}

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

140

# Divides the two street sides into left subsection made up of splitspace

(holds bike, parking, and buffer),repeater conventional lanes, and transit

lanes (activiated by Location Switch).

RightSide-->

split(v,unitSpace,0){(_Transit_Lane_Width_Switch(0,"Sidewalk

Side")):Transit_Lane_Reporting(0)

|_RightSplitSum:RightSplitSpace

|(_Transit_Lane_Width_Switch(0,"Right

Most Lane")):Transit_Lane_Reporting(0)

|( _Distribute_Right_Lanes* Lane_Width

):Lanes(0,(case rightHandTraffic: Stop_End else: Stop_Begin))

|(_Transit_Lane_Width_Switch(0,"Left

Most Lane")):Transit_Lane_Reporting(0)}

# Divides the two street sides into left subsection made up of splitspace

(holds bike, parking, and buffer),repeater conventional lanes, and transit

lanes (activiated by Location Switch).

LeftSide-->

split(v,unitSpace,0){(_Transit_Lane_Width_Switch(2,"Left Most

Lane")): scaleUV(0,-1,-1) Transit_Lane_Reporting(2)

|(nLanesLeft* Lane_Width ):

translateUV(0,0,-geometry.vMax) scaleUV(0,-1,-1) # mirror the uv coords

Lanes(2,(case

rightHandTraffic: Stop_Begin else: Stop_End) )

|(_Transit_Lane_Width_Switch(2,"Right

Most Lane")):scaleUV(0,-1,-1) Transit_Lane_Reporting(2)

|_LeftSplitSum:LeftSplitSpace

|(_Transit_Lane_Width_Switch(2,"Sidewalk

Side")):scaleUV(0,-1,-1) Transit_Lane_Reporting(2)}

# "Sidewalk Side","Right Most Lane","Left Most Lane"

##

##Note about Dir Variable-#Dir represents direction 0 for right, 2 for

left. Any other number is to handle an exception.

##

##

# split lanes into a single lane each and respective transit lane (location

based transit lanes)

Lanes(dir,stopType) -->

split(v,unitSpace,0){{Lane_Width :

LaneReporting(dir,split.total,split.index,stopType,"MainLanes")}*}

# prepare the uv coordinates and texture the shape

LaneMarkings(dir,lanenumber,markings) --> # is used for textures for

intersection approach (stop,turn arrows etc).

tileUV(0,~14,~Lane_Width ) # the tileUV operation

makes sure that one unit in u-space corresponds to approx 14 meters, the v-

coord is not touched in the case of 0 as parameter

normalizeUV(0,v,separatePerFace)

texture(StreetTextureFolder +

"/Lanes/lanes_4"+markings+"_14x14m.jpg")

deleteUV(_Texture_Switch)

color(_Usage("Auto"))#If Display Thematics==Usage, goes to usage, if

not, Thematic.

AsphaltPainted("white",false,_stopTexPaintFractions(markings,lanenumb

er),"Auto")

Asphalt(false,(1-_stopTexPaintFractions(markings,lanenumber)),"Auto")

#TODO-More combinations

MainLaneMarkings(dir,lanenumber,markings)-->

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

141

tileUV(0,~14,~ Lane_Width ) # the tileUV operation

makes sure that one unit in u-space corresponds to approx 14 meters, the v-

coord is not touched in the case of 0 as parameter

scaleUV(0,_uScale,1/4) # flip direction if

needed, handle short lanes with _uScale, and scaling the v coord for the

texture (e.g. a street with 2 lanes has v coords from 0 to 2, this means it

has to map onto 0 to 2/8 on our texture with its 8 lanes)

texture(StreetTextureFolder +

"/Lanes/lanes_4"+markings+"_14x14m.jpg")

deleteUV(_Texture_Switch)

color(_Usage("Auto"))#If Display Thematics==Usage, goes to usage, if

not, Thematic.

AsphaltPainted("white",false,MainLane_WhiteFraction,"Auto")

Asphalt(false,(1-MainLane_WhiteFraction),"Auto")

#This rule contains the reports for the lanes defined by the lanes rule, no

bike/pking lanes etc.

LaneReporting(dir,lanestotal,lanenumber,stopType,laneType)-->

report("Lane: Actual Lane Width (ft)",geometry.dv(0,unitSpace)*Feet)

#Used to provide lane widths in feet

report("Lane: Car Lane Area (m^2)",geometry.area)

ConventionalLane(dir,lanestotal,lanenumber,stopType)

#################################

#Lane choice Region #

#################################

######################

#Convential Lane Set Up

#

ConventionalLane(dir,lanestotal,lanenumber,stopType)-->

case stopType=="none" && lanenumber==lanestotal-1:# Makes sure with

no stop type last lane has no lane with contiguous stripes

Asphalt(true,1,"Auto")

VehiclesOnLane(dir)

case stopType!="none" && (lanenumber==lanestotal-1):# Makes sure with

no stop type last lane has no lane with contiguous stripes

split(u,unitSpace,0){ ~1: Asphalt(true,1,"Auto")

| 14:

LaneMarkings(dir,lanenumber,_stopTex(stopType,lanenumber,lanestotal)) }

VehiclesOnLane(dir)

else: # Makes basic lanes that that are not next to the last lane or

a bus/hov lane (if they are on).

split(u,unitSpace,0){ ~1:

MainLaneMarkings(dir,lanenumber,"_stripes_white")

| 14:

LaneMarkings(dir,lanenumber,_stopTex(stopType,lanenumber,lanestotal))}

VehiclesOnLane(dir)

#######################################################

#######################################################

#Multimodal Lane Creation and Non-Car Lane Splits

Transit_Lane_Reporting(dir)--> #Reports based on shape geometry and sends

to allocator

report("Lane-Transit: Transit Lane Width

(ft)",geometry.dv(0,unitSpace)*Feet) #Used to provide lane widths in feet

report("Lane-Transit: Transit Lane Area (m^2)",geometry.area)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

142

Transit_Lane_Allocator(dir)

Transit_Lane_Allocator(dir)--> #Allocates the texture rule based on what

type of transit lane is selected.

case Transit_Lane=="Bus Lane":

Buslane_Texture_Rule(dir)

case Transit_Lane=="HOV Lane":

HOVlane_Texture(dir)

else: #Do not leave blank geometry.

Buslane_Texture_Rule(dir)

Buslane_Texture_Rule(dir)-->

split(v,unitSpace,0){PaintLineWidth*_PaintLineControl("Right",

Transit_Paint_Line_Sides ):AsphaltPainted("white",true,1,"Transit")

#Level 1-First split indentation

|~1:split(u,unitSpace,0){2:AsphaltPainted(Bus_Lane_Color,true,1,"Tran

sit")

#Level 2- sub-split

indentation

|

Transit_Lane_Width:BuslaneStamp(dir)

|~ Transit_Symbol_Spacing

:AsphaltPainted(Bus_Lane_Color,true,1,"Transit")

|{ Transit_Lane_Width

:BuslaneStamp(dir)

|~ Transit_Symbol_Spacing

:AsphaltPainted(Bus_Lane_Color,true,1,"Transit")}*

| Transit_Lane_Width

:BuslaneStamp(dir)

|2:AsphaltPainted(Bus_Lane_Color,true,1,"Transit")}

|PaintLineWidth*_PaintLineControl("Left", Transit_Paint_Line_Sides

):AsphaltPainted("white",true,1,"Transit")}

BusOnLane(dir)

BuslaneStamp(dir)-->

scaleUV(0,1,DirectionalFlip)# Will flip with a change in

driving direction

rotateUV(0,90)

tileUV(0,~Transit_Lane_Width,~ Transit_Lane_Width )

texture(LanesFolder+"/BusLaneStamp"+(case

Bus_Lane_Color=="black":"_black" else:"")+".jpg")#If Black change the stamp

chosen, might make more elegant later.

deleteUV(_Texture_Switch)

color(_Usage("Transit"))#If Display Thematics==Usage,

goes to usage, if not, Thematic.

AsphaltPainted(Bus_Lane_Color,false,1,"Transit")

AsphaltPainted("white",false,BusSym_WhiteFraction,"Transit")

HOVlane_Texture(dir)-->

split(v,unitSpace,0){PaintLineWidth*2*_PaintLineControl("Right",

Transit_Paint_Line_Sides ):AsphaltPainted("yellow",true,1,"Transit")

#Level 1-First split indentation

|~1:split(u,unitSpace,0){2:Asphalt(true,1,"Transit")

#Level 2- sub-split

indentation

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

143

|

Transit_Lane_Width:HOVlaneStamp(dir)

|~ Transit_Symbol_Spacing

:Asphalt(true,1,"Transit")

|{ Transit_Lane_Width

:HOVlaneStamp(dir)

|~ Transit_Symbol_Spacing

:Asphalt(true,1,"Transit")}*

| Transit_Lane_Width

:HOVlaneStamp(dir)

|2:Asphalt(true,1,"Transit")}

|PaintLineWidth*2*_PaintLineControl("Left", Transit_Paint_Line_Sides

):AsphaltPainted("yellow",true,1,"Transit")}

VehiclesOnLane(dir)

HOVlaneStamp(dir)-->

scaleUV(0,1,DirectionalFlip)# Will flip with a change in driving

direction

rotateUV(0,90)

tileUV(0,~ Transit_Lane_Width ,~Transit_Lane_Width )#Lane width is

used for texture size because it can repeat if need for large streets and

because it allows the text to stay in scale with that of a Bus or car.

texture(LanesFolder+"/HOV_Diamond"+".jpg")#If Black change the stamp

chosen, might make more elegant later.

deleteUV(_Texture_Switch)

color(_Usage("Transit"))#If Display Thematics==Usage, goes to usage,

if not, Thematic.

AsphaltPainted("white",false,HOV_Diamond_WhiteFraction,"Transit")

Asphalt(false,(1-HOV_Diamond_WhiteFraction),"Transit")

##############################################################

#Non-Carlane Split Space- This is the space where

#parking, bike, and buffer lanes are constructed.

RightSplitSpace-->

scaleUV(0,1,case Parking_Protection :-1 else:1)

split(v,unitSpace,0){Right_Parking_Width

:ParkingLane("Right",Right_Parking_Type,Right_Parking_Length,Right_Parking_

Width)

|( Right_Bike_Lane_Width +

Right_Buffer_Width ):RightBikeLaneSpace("list")}

LeftSplitSpace-->

scaleUV(0,1,case Parking_Protection :-1 else:1)

split(v,unitSpace,0){( Left_Bike_Lane_Width + Left_Buffer_Width

):LeftBikeLaneSpace("list")

| Left_Parking_Width

:ParkingLane("Left",Left_Parking_Type,Left_Parking_Length,Left_Parking_Widt

h)}

####################

#####BikeLane Rules- Includes Lane and Buffer

#Bike Space-Total

LeftBikeLaneSpace(list)-->

scaleUV(0,1,case Buffer_Protection : -1 else:1)

scaleUV(0,1,case Parking_Protection :-1 else:1)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

144

split(v,unitSpace,0) { Left_Bike_Lane_Width

:LeftBikeLaneSection(list)

|Left_Buffer_Width

:BikeBuffer(Left_Buffer_Width,2)}

RightBikeLaneSpace(list)-->

scaleUV(0,1,case Buffer_Protection : -1 else:1)

scaleUV(0,1,case Parking_Protection :-1 else:1)

split(v,unitSpace,0) {Right_Buffer_Width

:BikeBuffer(Right_Buffer_Width,0)

|Right_Bike_Lane_Width

:RightBikeLaneSection(list)}

#BikeLane Start

RightBikeLaneSection(list)-->

case Bike_Lane_Type=="One-way":

BikeLane(1,Right_Bike_Lane_Width)

else:

split(v,unitSpace,0) {'.5:BikeLane(-

1,Right_Bike_Lane_Width)|~1:BikeLane(1,Right_Bike_Lane_Width)}

LeftBikeLaneSection(list)-->

case Bike_Lane_Type=="One-way":

BikeLane(-1,Left_Bike_Lane_Width)

else:

split(v,unitSpace,0) {'.5:BikeLane(-1,Left_Bike_Lane_Width)|

~1:BikeLane(1,Left_Bike_Lane_Width)}

BikeLane(sideflip,Width)-->#Was Left,now both, fairly modular

Bikes((case sideflip==1:0 else: 2),(case Bike_Lane_Type=="Two-

way":Width/2 else: Width))

color(_Usage("Bikeways"))#If Display Thematics==Usage, goes to usage,

if not, Thematic.

scaleUV(0,sideflip,sideflip)

split(v,unitSpace,0){PaintLineWidth*_PaintLineControl("Left",

Bike_Paint_Line_Sides):BikeLaneLines

#Level 1-First split indentation

|~1:split(u,unitSpace,0){2:AsphaltPainted(Bike_Lane_Color,true,1,"Bik

eways")

#Level 2- sub-split

indentation

| Width :BikeLaneStamp(Width

,Bike_Lane_Color+"_stamp.jpg",Bike_Lane_Color)

|~ Bike_Symbol_Spacing

:AsphaltPainted(Bike_Lane_Color,true,1,"Bikeways")

|{ Width

:BikeLaneStamp(Width ,Bike_Lane_Color+"_stamp.jpg",Bike_Lane_Color)

|~ Bike_Symbol_Spacing

:AsphaltPainted(Bike_Lane_Color,true,1,"Bikeways")}*

| Width

:BikeLaneStamp(Width,Bike_Lane_Color+"_stamp.jpg",Bike_Lane_Color)

| Bike_Conflict_Spacing

:ConflictZone(Bike_Lane_Color)

|1:AsphaltPainted((Bike_Lane_Color),true,1,"Bikeways")}

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

145

|PaintLineWidth*_PaintLineControl("Right",

Bike_Paint_Line_Sides):BikeLaneLines}

BikeLaneLines-->

split(u,unitSpace,0){~1:AsphaltPainted("white",true,1,"Bikeways")

|Bike_Conflict_Spacing:ConflictZone("white")

|1:AsphaltPainted("white",true,1,"Bikeways")}

BikeLaneStamp(Stamp_Width,FileEnd, Color)-->

scaleUV(0,1,DirectionalFlip)# Will flip with a change in driving

direction

tileUV(0,~Stamp_Width,~Stamp_Width)

texture(LanesFolder+"/street_1bike_"+FileEnd)

deleteUV(_Texture_Switch)

color(_Usage("Bikeways"))#If Display Thematics==Usage, goes to usage,

if not, Thematic.

AsphaltPainted(Color,false,1,"Bikeways")

AsphaltPainted("white",false,(case

FileEnd==Color+"_stamp_noarrow.jpg":BikeSymNoArr_WhiteFraction

else:BikeSym_WhiteFraction),"Bikeways")

ConflictZone(passedcolor)-->

split(u,unitSpace,0){~1: AsphaltPainted(passedcolor,true,1,"Conflict

Zones")|~1:Asphalt(true,1,"Conflict Zones")}*

#Buffer Rules (Some Shared Rules in Median).

BikeBuffer(Buffer_Width,Dir)-->

case Buffer_Type=="Painted Stripes":

color(_Usage("Bikeways"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

Striped_Buffer(Buffer_Width)

case Buffer_Type=="Solid White":

color(_Usage("Bikeways"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

AsphaltPainted("white",true,1,"Bikeways")

case Buffer_Type=="Asphalt":

Asphalt(true,1,"Auto")

case Buffer_Type=="Shoulder":

Shoulder(Dir)

case Buffer_Type=="Curb Buffer with Trees" || Buffer_Type=="Curb

Buffer with Plantings":

color(_Usage("Bikeways"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

Raised_Curb("Buffer",1)

case Buffer_Type=="Curb Buffer":

color(_Usage("Bikeways"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

Raised_Curb("Buffer",1)

case Buffer_Type=="Cycle Track With Planters":

color(_Usage("Bikeways"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

Striped_Buffer(Buffer_Width)

ObjectSetup("Planter",Buffer_Object_Spacing,"/Planter_"+LOD_Setting+"

_LOD.obj",Buffer_Width)

case Buffer_Type=="Cycle Track With Tubular Markers":

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

146

color(_Usage("Bikeways"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

Striped_Buffer(Buffer_Width)

ObjectSetup("Tubular

Marker",Buffer_Object_Spacing,"/Tubular_Marker.obj",Buffer_Width)

else:

color(_Usage("Bikeways"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

Striped_Buffer(Buffer_Width)

ObjectSetup(Object_Type,distance_between_objs,File_Extension,Width)-->

alignScopeToAxes(y)

alignScopeToGeometry(yUp,largest,longest)

split(u,unitSpace,0){~.5:NIL

|{Width*.9:Cycle_Track_ObjIns(Object_Type,File_Extension,Width)

|~distance_between_objs:NIL}*

|~.2:NIL}

Cycle_Track_ObjIns(Object_Type,Buffer_File,Width)-->

alignScopeToAxes(y)

alignScopeToGeometry(yUp,largest,0)

s(0,0,0)

i(ObjectFolder+Buffer_File)

deleteUV(_Texture_Switch)

report("Objects: "+Object_Type+ " Count",1)

center(xz)

Buffer_Tree_Split-->

split(u,unitSpace,0) {Buffer_StartGap:NIL

|{~Buffer_Object_Spacing/2:NIL

|1:Tree_Setup("Buffer",

Sidewalk_Tree_1_Percentage , Sidewalk_Tree_1_Type,Sidewalk_Tree_2_Type )

|~Buffer_Object_Spacing/2:NIL}*

|Buffer_StartGap:NIL}

Buffer_Top-->

case Buffer_Type=="Curb Buffer with Trees":

Sidewalk_Planting

Buffer_Tree_Split

case Buffer_Type=="Curb Buffer":

Buffer_Texture

case Buffer_Type=="Curb Buffer with Plantings":

Sidewalk_Planting

else:

Buffer_Texture

Buffer_Texture-->

tileUV(0,2,2) texture(Sidewalk_Texture)

deleteUV(_Texture_Switch)

scaleUV(0, Sidewalk_Texture_Scale, Sidewalk_Texture_Scale)

rotateUV(0, Sidewalk_Texture_Rotation)

Shoulder(Dir)-->

case Dir==0:

split(v,unitSpace,0){PaintLineWidth:AsphaltPainted("white",true,1,"Au

to")

|Rumble_Strip_Wid:Rumble_Strip

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

147

|~1:Asphalt(true,1,"Auto")}

else:

split(v,unitSpace,0){~1:Asphalt(true,1,"Auto")

|Rumble_Strip_Wid:Rumble_Strip

|PaintLineWidth:AsphaltPainted("white",true,1,"Auto")}

Striped_Buffer(Buffer_Width)-->

rotateUV(0,90)

tileUV(0,~ Buffer_Width ,~Buffer_Width*1.5 )

texture(LanesFolder+"/street_1bike_"+"buffer2.jpg")

deleteUV(_Texture_Switch)

AsphaltPainted("black",false,1-Buffer_WhiteFraction,"Bikeways")

AsphaltPainted("white",false,Buffer_WhiteFraction,"Bikeways")

#Bike Box Creation Rule- controls the splits for the bike box. Works best

if Bike lane is adjacent to sidewalk.

BikeBoxCreation(side)-->

case side=="Left":

split(v, unitSpace,0)

{PaintLineWidth:AsphaltPainted("white",true,1,"Bikeways")|

~1:split(u, unitSpace,0){

PaintLineWidth:AsphaltPainted("white",true,1,"Bikeways")

|~1:BikeBoxSymbol(side)

|ThickPaintLineWidth:AsphaltPainted("white",true,1,"Bikeways")}

|Left_Bike_Lane_Width -

PaintLineWidth*_Bike_Paint_Adjuster:split(u,unitSpace,0){

PaintLineWidth:AsphaltPainted("white",true,1,"Bikeways")|~1:AsphaltPa

inted(Bike_Box_Color_Override,true,1,"Bikeways")}

|PaintLineWidth:AsphaltPainted("white",true,1,"Bikeways")}

else:

split(v, unitSpace,0)

{PaintLineWidth:AsphaltPainted("white",true,1,"Bikeways")

| Right_Bike_Lane_Width -

PaintLineWidth*_Bike_Paint_Adjuster:split(u,unitSpace,0){

~1:AsphaltPainted(Bike_Box_Color_Override,true,1,"Bikeways")|PaintLin

eWidth:AsphaltPainted("white",true,1,"Bikeways")}

|~1:split(u, unitSpace,0){

ThickPaintLineWidth:AsphaltPainted("white",true,1,"Bikeways")

|~1:BikeBoxSymbol(side)

|PaintLineWidth:AsphaltPainted("white",true,1,"Bikeways")}

|PaintLineWidth:AsphaltPainted("white",true,1,"Bikeways")}

BikeBoxSymbol(side)-->

case side=="Left":

scaleUV(0,-1,1)

split(v,unitSpace,0) {~ Bike_Box_Symbol_Spacing

/2:AsphaltPainted(Bike_Box_Color_Override ,true,1,"Bikeways")

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

148

| Lane_Width

*BikeBox_Fraction: BikeLaneStamp( Lane_Width ,Bike_Box_Color_Override

+"_stamp_noarrow.jpg",Bike_Box_Color_Override)

|~ Bike_Box_Symbol_Spacing

/2:AsphaltPainted(Bike_Box_Color_Override ,true,1,"Bikeways")}*

else:

scaleUV(0,1,1)

split(v,unitSpace,0) {~ Bike_Box_Symbol_Spacing

/2:AsphaltPainted(Bike_Box_Color_Override,true,1,"Bikeways")

| Lane_Width

*BikeBox_Fraction:BikeLaneStamp( Lane_Width ,Bike_Box_Color_Override

+"_stamp_noarrow.jpg",Bike_Box_Color_Override)

|~ Bike_Box_Symbol_Spacing

/2:AsphaltPainted(Bike_Box_Color_Override,true,1,"Bikeways")}*

########################

#####Parking Lane Rules

ParkingLane(Side,ParkingType,ParkingLength,ParkingWidth)-->

case ParkingType=="Parallel":

color(_Usage("Auto"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

scaleUV(0,

case Lane_Distribution==1:

-1

case Lane_Distribution==0:

1

else:

case Side=="Right":-1 else:1

,1)

split(u,unitSpace,0)

{~_Front_Parking_Spacing(ParkingType):Asphalt(true,1,"Auto")

|{ParkingLength:ParkingSpace(Side,ParkingType,split.index,split.total

,ParkingLength,ParkingWidth)}*

|~_Rear_Parking_Spacing(ParkingType):Asphalt(true,1,"Auto")}

else:

color(_Usage("Auto"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

scaleUV(0,case Side=="Right":-1 else:1,1)

split(u,unitSpace,0){~_Front_Parking_Spacing(ParkingType):Asphalt(tru

e,1,"Auto")# Make sure to pass right parameters/type shoudl work here

|{ParkingLength:ParkingSpace(Side,ParkingType,split.index,split.total

,ParkingLength,ParkingWidth)}*

|~_Rear_Parking_Spacing(ParkingType):Asphalt(true,1,"Auto")}

ParkingSpace(Side,ParkingType,SpaceNumber,TotalSpacesonSide,ParkingLength,P

arkingWidth)-->

case rand(0,100)<=Parklet_Percentage && SpaceNumber>1:

Asphalt(true,1,"Pedestrian")

Parklet_Insert(ParkingLength,case Side=="Right":0 else: 180)

case ParkingType=="Angled Nose In":

AngledNoseIn(Side,ParkingType,SpaceNumber,TotalSpacesonSide,ParkingLe

ngth,ParkingWidth)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

149

case ParkingType=="Parallel":

ParallelParking(Side,ParkingType,SpaceNumber,TotalSpacesonSide,Parkin

gLength,ParkingWidth)

else:

AngledNoseOutParking(Side,ParkingType,SpaceNumber,TotalSpacesonSide,P

arkingLength,ParkingWidth)

Parklet_Insert(ParkingLength,Rotation)-->

alignScopeToGeometry(yUp, largest, 1)

rotateScope(0,Rotation,0)

s(scope.sx-Parklet_Shift,0,scope.sz)

t(Parklet_Shift,0,_Parklet_OneWay_Shift(Rotation)*(ParkingLength/8))

report("Objects: Parklet Count",1)

i(Parklet_Object)

deleteUV(_Texture_Switch)

AngledNoseIn(Side,ParkingType,SpaceNumber,TotalSpacesonSide,ParkingLength,P

arkingWidth)-->

AngledParkingCar((case Side=="Right":0

else:2),ParkingType,ParkingLength, ParkingWidth,SpaceNumber)

scaleUV(0,-1,

(case Side=="Right":

(case Parking_Protection :1 else:-1)

else:

(case Parking_Protection :-1 else:1)))

tileUV(0,~ParkingLength,~ParkingWidth)

texture(LanesFolder+"/AngledParking.jpg")

deleteUV(_Texture_Switch)

color(_Usage("Auto"))#If Display Thematics==Usage, goes to usage, if

not, Thematic.

ParkingReport(Side,ParkingType,case SpaceNumber==1: false

else:true)#Don't include last spot

AngledNoseOutParking(Side,ParkingType,SpaceNumber,TotalSpacesonSide,Parking

Length,ParkingWidth)-->

AngledParkingCar((case Side=="Right":0

else:2),ParkingType,ParkingLength, ParkingWidth,SpaceNumber)

scaleUV(0,1,(case Side=="Right":

(case Parking_Protection :1 else:-

1)

else:

(case Parking_Protection :-1

else:1)))

tileUV(0,~ParkingLength,~ParkingWidth)

texture(LanesFolder+"/AngledParking.jpg")

deleteUV(_Texture_Switch)

color(_Usage("Auto"))#If Display Thematics==Usage, goes to usage, if

not, Thematic.

ParkingReport(Side,ParkingType,case SpaceNumber==1: false else:true)

#Don't include last spot

ParallelParking(Side,ParkingType,SpaceNumber,TotalSpacesonSide,ParkingLengt

h,ParkingWidth)-->

case SpaceNumber==TotalSpacesonSide-2:#1 from index total, 1 from

additional split

ParallelParkingCar(_ParParkedFacing(Side),ParkingLength,

ParkingWidth)# Fix Parking Angle on oneway Streets

scaleUV(0,1,(case Side=="Right":

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

150

(case Parking_Protection :1 else:-

1)

else:

(case Parking_Protection :-1

else:1)))

tileUV(0,~ParkingLength,~ParkingWidth)

texture(LanesFolder+"/ParallelParkFront.jpg")

deleteUV(_Texture_Switch)

color(_Usage("Auto"))#If Display Thematics==Usage, goes

to usage, if not, Thematic.

ParkingReport(Side,ParkingType,true)

case SpaceNumber==1:

scaleUV(0,1,(case Side=="Right":

(case Parking_Protection :1 else:-

1)

else:

(case Parking_Protection :-1

else:1)))

tileUV(0,~ParkingLength,~ParkingWidth)

texture(LanesFolder+"/ParallelParkRear.jpg")

deleteUV(_Texture_Switch)

color(_Usage("Auto"))#If Display Thematics==Usage, goes

to usage, if not, Thematic.

ParkingReport(Side,ParkingType,false)#it is the last

texture, it does not make an actual parking space.

else:

ParallelParkingCar(_ParParkedFacing(Side),ParkingLength,

ParkingWidth)# Fix Parking Angle on oneway Streets-TODO

scaleUV(0,1,(case Side=="Right":

(case Parking_Protection :1 else:-

1)

else:

(case Parking_Protection :-1

else:1)))

tileUV(0,~ParkingLength,~ParkingWidth)

texture(LanesFolder+"/ParallelParkMid.jpg")

deleteUV(_Texture_Switch)

color(_Usage("Auto"))#If Display Thematics==Usage, goes

to usage, if not, Thematic.

ParkingReport(Side,ParkingType,true)

ParallelParkingCar(dir,ParkingLength, ParkingWidth) -->

case p(Parked_Car_Percentage):

ParallelParkingCarStep2(dir,ParkingLength, ParkingWidth)

else: NIL

ParallelParkingCarStep2(dir,ParkingLength, ParkingWidth) -->

alignScopeToGeometry(yUp, 0, (case dir==2:3 else:1))#If distortion is

too high, the edge numbers might change making this look weird. Hard to

evaluate options.

rotateScope(0,DirectionalRotation,0)

s(0,0,0)

i(vehicleAsset("car"))

t(0,0,(ParkingLength/2)+1)

center(x)

deleteUV(_Texture_Switch)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

151

AngledParkingCar(dir,ParkingType,ParkingLength, ParkingWidth,SpaceNumber)--

>

case p(Parked_Car_Percentage)&& SpaceNumber!=1: #Don't include last

spot

case (dir == 2):

AngledParkingCarStep2(-1,case ParkingType=="Angled Nose

In":1 else:-1,Left_Parked_Car_Angle,ParkingLength, ParkingWidth)

else:

AngledParkingCarStep2(1,case ParkingType=="Angled Nose

In":1 else:-1,Right_Parked_Car_Angle,ParkingLength, ParkingWidth)

else: NIL

AngledParkingCarStep2(DirsenseFlip,NoseSenseFlip,Rotation_Angle,ParkingLeng

th, ParkingWidth)-->

alignScopeToGeometry(yUp, 0, (case DirsenseFlip==-1:3 else:1))#If

distortion is too high, the edge numbers might change making this look

weird. Hard to evaluate options.

s(0,0,0)

t((ParkingWidth/2.3),0,(ParkingLength)) # Suggest changing base

concept later.

rotateScope(0,NoseSenseFlip*-Rotation_Angle,0)

i(vehicleAsset("car"))

deleteUV(_Texture_Switch)

ParkingReport(Side,ParkingType,Rear_Edge_Case)-->#This edge case parameter

only makes sure the correct number of parking spaces is reported.

case Rear_Edge_Case:

report("Parking: "+Side+" Parking Space Area

(m^2)",geometry.area)

report("Parking: Total Parking Space Area (m^2)",geometry.area)

AsphaltPainted("black",false,case ParkingType=="Parallel":1-

ParallelPark_WhiteFraction else:1-AngledPark_WhiteFraction,"Auto")

AsphaltPainted("white",false,case

ParkingType=="Parallel":ParallelPark_WhiteFraction

else:AngledPark_WhiteFraction,"Auto")

else:

AsphaltPainted("black",false,case ParkingType=="Parallel":1-

ParallelPark_WhiteFraction else:1-AngledPark_WhiteFraction,"Auto")

AsphaltPainted("white",false,case

ParkingType=="Parallel":ParallelPark_WhiteFraction

else:AngledPark_WhiteFraction,"Auto")

###################################################

# Centerline and Center Section Code

#

CenterLineReporting-->

report("Center: Center Section Area",geometry.area)

color(_Usage("Auto"))#If Display Thematics==Usage, goes to usage, if

not, Thematic.

CenterSpace

CenterSpace -->

case Center_Type =="Median":

Raised_Curb("Median",1)# IF a median, and this will be use dto

make a different rule

case Center_Type =="Boulevard":

Boulevard

case Center_Type =="Barrier":

split(u,unitSpace,0) {{1:Barrier }*|1:Asphalt(true,1,"Auto")}

Asphalt(true,1,"Auto")

case Center_Type =="Barrier & Shoulder":

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

152

split(u,unitSpace,0) {{1:Barrier }*|1:NIL}

split(v,unitSpace,0) {Rumble_Strip_Wid:Rumble_Strip

|~1:Asphalt(true,1,"Auto")

|Rumble_Strip_Wid:Rumble_Strip}

case Center_Type=="Center Turn Lane":

Center_Turn_Lane

case Centerline_Color =="none":

split(u,unitSpace,0){ _stopBegin*21:

CenterLineMarkings("single_white")

| ~1 :

CenterLineMarkings("stripes_white")

| _stopEnd*21 :

CenterLineMarkings("single_white") }

else:

CenterLineMarkings("double_"+ Centerline_Color )

Center_Turn_Lane-->

split(u,unitSpace,0){(_Bike_Box_Gap("Begin")):

Bike_Box_Left_Turn_Gap("Begin")

|_neighborBegin*_stopBegin*ThickPaintLineWidth:AsphaltPainted("white"

,true,1,"Auto")

|(_tooShort(geometry.du(0,unitSpace),30))*_neighborBegin*_stopBegin*1

8:CenterTurnLaneStamp("Transition_",180)

|~ Lane_Width

:CenterTurnLaneStamp("",90)

|{~ Lane_Width

:CenterTurnLaneStamp("",90)

| Lane_Width

:CenterTurnLaneStamp("Turn_",90)

| ~Lane_Width

:CenterTurnLaneStamp("",90)}*

|~ Lane_Width

:CenterTurnLaneStamp("",90)

|(_tooShort(geometry.du(0,unitSpace),30))*_neighborEnd*_stopEnd*18:Ce

nterTurnLaneStamp("Transition_",0)

|_neighborEnd*_stopEnd*ThickPaintLineWidth:AsphaltPainted("white",tru

e,1,"Auto")

|(_Bike_Box_Gap("End")):

Bike_Box_Left_Turn_Gap("End")}

Boulevard-->

case Boulevard_Configuration=="Open Space": #If open space send to

different split set up.

split(v,unitSpace,0){~(case WalkWay_Width==0:1

else:WalkWay_Width):Raised_Curb("Boulevard",0)

|Boulevard_Inside_Width:Raised_Curb("Open Space",0)

|~(case WalkWay_Width==0:1

else:WalkWay_Width):scaleUV(0,-1,-1)Raised_Curb("Boulevard",2)}

else: # If any type of lane set to Typical split set up.

split(v,unitSpace,0){~(case WalkWay_Width==0:1

else:WalkWay_Width):Raised_Curb("Boulevard",0)

|Boulevard_Inside_Width/2-

(Boulevard_Center_Width/2):Boulevard_StopBars(0)

|Boulevard_Center_Width:Boulevard_Center

|Boulevard_Inside_Width/2-

(Boulevard_Center_Width/2): Boulevard_StopBars(2)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

153

|~(case WalkWay_Width==0:1

else:WalkWay_Width):scaleUV(0,-1,-1)Raised_Curb("Boulevard",2)}

Boulevard_StopBars(dir)-->

case Boulevard_Configuration=="Bus Lanes":

case dir==0:

split(u,unitSpace,0)

{~1:Buslane_Texture_Rule(dir)|_stopEnd*ThickPaintLineWidth:AsphaltPainted("

white",true,1,"Auto")}

else:

split(u,unitSpace,0)

{_stopBegin*ThickPaintLineWidth:AsphaltPainted("white",true,1,"Auto")|~1:sc

aleUV(0,-1,-1)Buslane_Texture_Rule(dir)}

case Boulevard_Configuration=="Normal Lanes":

case dir==0:

split(u,unitSpace,0)

{~1:Center_Normal_Lanes(dir)|_stopEnd*ThickPaintLineWidth:AsphaltPainted("w

hite",true,1,"Auto")}

else:

split(u,unitSpace,0)

{_stopBegin*ThickPaintLineWidth:AsphaltPainted("white",true,1,"Auto")|~1:sc

aleUV(0,-1,-1)Center_Normal_Lanes(dir)}

else:

case dir==0:

split(u,unitSpace,0)

{~1:BikeLane(1,geometry.dv(0,unitSpace))|_stopEnd*ThickPaintLineWidth:Aspha

ltPainted("white",true,1,"Auto")}

else:

split(u,unitSpace,0)

{_stopBegin*ThickPaintLineWidth:AsphaltPainted("white",true,1,"Auto")|~1:Bi

keLane(-1,geometry.dv(0,unitSpace))}

Boulevard_Center-->

case Boulevard_Center_Type=="Center Line":

CenterLineMarkings("double_"+ (case

Centerline_Color=="none":"yellow" else:Centerline_Color))

case Boulevard_Center_Type=="Median":

Raised_Curb("Boulevard Center",1) #HAS no bus stop

case Boulevard_Center_Type=="Curb Buffer":

Raised_Curb("Boulevard Center",1) #HAS no bus stop

case Boulevard_Center_Type=="Tubular Markers":

ObjectSetup("Tubular

Marker",Center_Tube_Marker_Dist,"/Tubular_Marker.obj",1)

Asphalt(true,1,"Auto")

case Boulevard_Center_Type=="Chain Link Fence":

split(u,unitSpace,0) {.3:NIL|~1:Fence("Boulevard

Center")|.3:NIL}#The split only makes it so the fence poles are not put in

the curb.

Raised_Curb("Boulevard Center",1)

case Boulevard_Center_Type=="Gate Fence":

split(u,unitSpace,0) {.3:NIL|~1:Fence("Boulevard

Center")|.3:NIL}#The split only makes it so the fence poles are not put in

the curb.

Raised_Curb("Boulevard Center",1)

else:

CenterLineMarkings("double_"+(case

Centerline_Color=="none":"yellow" else:Centerline_Color))

Center_Normal_Lanes(Dir)-->

split(v,unitSpace,0) {~1:Drainage

|{ Lane_Width

:MainLaneMarkings(0,split.index,"_stripes_white") VehiclesOnLane(Dir)}*

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

154

| Lane_Width :Asphalt(true,1,"Auto")

VehiclesOnLane(Dir)}

CenterLineMarkings(tex) -->

normalizeUV(0,v,collectiveAllFaces)

tileUV(0,~14,0)

texture(StreetTextureFolder + "/Lanes/centerline_" + tex +

"_14m.jpg")

deleteUV(_Texture_Switch)

AsphaltPainted(case Centerline_Color=="none":"white"

else:Centerline_Color,false,Center_Line_Paint_Fraction,"Auto")#Slight over

estimate for none-case.

color(_Usage("Auto"))#If Display Thematics==Usage, goes to usage, if

not, Thematic.

CenterTurnLaneStamp(texture_choice,degree)-->

normalizeUV(0,v,collectiveAllFaces)

rotateUV(0,degree)

tileUV(0, '1 ,'1)

texture(LanesFolder+"/Center_"+texture_choice+"Lane"+".jpg")

deleteUV(_Texture_Switch)

color(_Usage("Auto"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

AsphaltPainted("yellow",false,CenterTurnLane_YellowFraction,"Auto")

AsphaltPainted("white",false,case texture_choice=="Turn_" ||

texture_choice=="Transition_":CenterTurnLane_WhiteFraction else: 0,"Auto")

Bike_Box_Left_Turn_Gap(street_side)--> #If Bike boxes are on for the

correct side

case street_side=="Begin": split (u,unitSpace,0)

{PaintLineWidth:AsphaltPainted("white",true,1,"Conflict Zones")

|~1:split(v,unitSpace,0)

{PaintLineWidth:AsphaltPainted("white",true,1,"Conflict Zones")|

~1:Asphalt(true,1,"Conflict Zones")}}

case street_side=="End": split (u,unitSpace,0)

{~1:split(v,unitSpace,0){ ~1:Asphalt(true,1,"Conflict

Zones")|PaintLineWidth:AsphaltPainted("white",true,1,"Conflict Zones")}

|PaintLineWidth:AsphaltPainted("white",true,1,"Conflict Zones")}

else: Asphalt(true,1,"Conflict Zones")

Barrier-->

alignScopeToGeometry(yUp, largest, 0)

i(ObjectFolder+"/Jersey_Barrier.obj")

report("Objects: Jersey Barrier Count",1)

r(0,90,0)

s(1,1,1.2)

center(x)

deleteUV(_Texture_Switch)

#Raised Curb and Street_Pavement-

#This code is a fairly modular is called by several different rules. #Dir

is 0 for right, 2, left, 1 middle or not assigned.

Raised_Curb(Location,Dir)-->

Cut_And_Fill_Reporting(Location)

Street_Lamp_Center(Location,Dir)

split(u,unitSpace,0){ Curb_Depth:Curbs_Mass(true)|#End Curb

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

155

~1:split(v,unitSpace,0){

Curb_Depth:Curbs_Mass(false)

|~1:Street_Pavement(0,Location,Dir)

| Curb_Depth:Curbs_Mass(false)}

| Curb_Depth:Curbs_Mass(true)}#End Curb

Street_Pavement(Boulevard_Side,Location,Dir)-->

#Boulevard side is used when arranging the Benches where the WalkWay Side

and Side of Boulevard are both needed

#if it is not needed is is filled with string=="None"

case Location=="Buffer":

extrude(world.y, Sidewalk_Height )

comp(f){top=Buffer_Top}

case Location=="Median":

extrude(world.y, Sidewalk_Height )

comp(f){top=Median_Top_Setup(Dir)}

case Location=="Boulevard":

extrude(world.y, Sidewalk_Height )

comp(f){top=Boulevard_Top(Dir) }

case Location=="Boulevard Center":

extrude(world.y, Sidewalk_Height )

comp(f){top=Boulevard_Center_Top(Dir) }

case Location=="WalkWay_Right"||Location=="WalkWay_Left":

WalkWay_Texture

Master_Split(Boulevard_Side,(geometry.dv(0,unitSpace)>=Bench_Threshol

d_Width),"WalkWay",Dir)

People

case Location=="Open Space":

extrude(world.y, Sidewalk_Height )

comp(f){top=OpenSpace_Planting}

else:

extrude(world.y, Sidewalk_Height )

WalkWay_Texture

Median_Top_Setup(Dir)-->

case Dir==0:

Median_Top(Dir)

else:

scaleUV(0,-1,1)

Median_Top(Dir)

Boulevard_Top(Dir)-->

split(u,

unitSpace,0){Median_Planting_Length+Median_Tree_Spacing:Main_Section_Constr

uction(Dir)

|~_Bus_Furniture_Base("Boulevard","Far-

side",Dir):Bus_Stop_Base("Boulevard",case Dir==0:180 else:0)

|~geometry.du(0,unitSpace)/2:Main_Section_Construction(Dir)

|~_Bus_Furniture_Base("Boulevard","Mid-

Block",Dir):Bus_Stop_Base("Boulevard",case Dir==0:180 else:0)

|~geometry.du(0,unitSpace)/2:Main_Section_Construction(Dir)

|~_Bus_Furniture_Base("Boulevard","Near-

side",Dir):Bus_Stop_Base("Boulevard",case Dir==0:180 else:0)

|Median_Planting_Length+Median_Tree_Spacing:Main_Section_Construction(Dir)}

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

156

Median_Top(Dir)-->

split(u,

unitSpace,0){Median_Planting_Length+Median_Tree_Spacing:Main_Section_Constr

uction(Dir)

|~_Bus_Furniture_Base("Median","Far and

Near Side",(case Median_Bus_Stop_Location=="Far-side":0 else:

2)):Bus_Stop_Base_Setup("Median",0)

|~geometry.du(0,unitSpace)/2:Main_Section_Construction(Dir)

|~_Bus_Furniture_Base("Median","Mid-

Block",1):Bus_Stop_Base_Setup("Median",1)

|~geometry.du(0,unitSpace)/2:Main_Section_Construction(Dir)

|~_Bus_Furniture_Base("Median","Far and

Near Side",(case Median_Bus_Stop_Location=="Far-side":2 else:

0)):Bus_Stop_Base_Setup("Median",2)

|Median_Planting_Length+Median_Tree_Spacing:Main_Section_Construction(Dir)}

Boulevard_Center_Top(Dir)-->

case Boulevard_Center_Type=="Median":

Main_Section_Construction(Dir) # Does not construct bus stop-

walkways/plantings only.

else:

Buffer_Texture

Bus_Stop_Base_Setup(Location,Stop_Number)-->

case Median_Bus_Stop_Location=="Mid-Block":

split(v,unitSpace,0){'_Median_Midblock_Switch(0,"WalkWay"):WalkWay_Te

xture

|'_Median_Midblock_Switch(0,"BusStop"):Bus_Stop_Base(Location,0)

|'_Median_Midblock_Switch(2,"BusStop"):Bus_Stop_Base(Location,180)

|'_Median_Midblock_Switch(2,"WalkWay"):WalkWay_Texture}

case Median_Bus_Stop_Location=="Near-side":

case Stop_Number==0:

split(v,unitSpace,0){'.5:Bus_Stop_Base(Location,0)

|'.5:WalkWay_Texture}

else:

split(v,unitSpace,0){'.5:WalkWay_Texture

|'.5:Bus_Stop_Base(Location,180)}

else:

case Stop_Number==0:

split(v,unitSpace,0){'.5:WalkWay_Texture

|'.5:Bus_Stop_Base(Location,180)}

else:

split(v,unitSpace,0){'.5:Bus_Stop_Base(Location,0)

|'.5:WalkWay_Texture}

Main_Section_Construction(Boulevard_Side)--># Rename

Walkway_Right/Walk_WayLeft- DIR can replace it but is currently only used

for benches.

case Planting_and_Walkway_Layout=="Plant:Walk":

split(v,unitSpace,0){~1:Median_Plant_Side(Boulevard_Side,0)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

157

|WalkWay_Width:Street_Pavement(Boulevard_Side,"WalkWay_Left",2)}

case Planting_and_Walkway_Layout=="Walk:Plant":

split(v,unitSpace,0){WalkWay_Width:Street_Pavement(Boulevard_Side,"Wa

lkWay_Right",0)

|~1:Median_Plant_Side(Boulevard_Side,2)}

case Planting_and_Walkway_Layout=="Plant:Walk:Plant":

split(v,unitSpace,0){~1:Median_Plant_Side(Boulevard_Side,2)

|WalkWay_Width:Street_Pavement(Boulevard_Side,"WalkWay_Left",2)

|WalkWay_Width:Street_Pavement(Boulevard_Side,"WalkWay_Right",0)

|~1:Median_Plant_Side(Boulevard_Side,0)}

case Planting_and_Walkway_Layout=="Walk:Plant:Walk":

split(v,unitSpace,0){WalkWay_Width:Street_Pavement(Boulevard_Side,"Wa

lkWay_Right",0)

|~1:Median_Plant_Side(Boulevard_Side,0)

|WalkWay_Width:Street_Pavement(Boulevard_Side,"WalkWay_Left",2)}

else:

NIL

Median_Plant_Side(Boulevard_Side,Dir)-->#The Bus Stop, Bike Racks, and

WayFinder are put here.

split(u,unitSpace,0){{~Median_Tree_Spacing/2:WalkWay_Texture

|~Median_Planting_Length:Median_Plant_Base

|~Median_Tree_Spacing/2:WalkWay_Texture

}*}

Bus_Stop_Base(Location,RotationAng)-->

case Location=="Median":

WalkWay_Texture

Median_Object_Split(RotationAng)

case Location=="Boulevard":

WalkWay_Texture

Boulevard_Object_Split(RotationAng)

else:

WalkWay_Texture

Sidewalk_Object_Split(RotationAng)

Median_Object_Split(RotationAng)-->

split(u,unitSpace,0){'_Bus_Alloc("Median"):Bus_Objects_Insert("Bus

Stop",Bus_Stop_Object,RotationAng,-.5,2,3,3.35)

|'_Bike_Rack_Alloc("Median"):Median_Bike_Rack_Split(RotationAng,-1)

|'_WayFinder_Alloc("Median"):Bus_Objects_Insert("Wayfinder",Wayfinder

_Object,RotationAng,-.5,.3,3,1.2)}

Boulevard_Object_Split(RotationAng)-->

split(u,unitSpace,0){'_Bus_Alloc("Boulevard"):Bus_Objects_Insert("Bus

Stop",Bus_Stop_Object,RotationAng,0,2,3,3.35)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

158

|'_Bike_Rack_Alloc("Boulevard"):Bike_Rack_Split(RotationAng,-.5)

|'_WayFinder_Alloc("Boulevard"):Bus_Objects_Insert("Wayfinder",Wayfin

der_Object,RotationAng,-.5,.3,3,1.2)}

Bus_Objects_Insert(Object_Identity,File_Extension,RotationAng,Translation,S

X,SY,SZ)-->#Bus Object Constructor Method

alignScopeToAxes(y)

alignScopeToGeometry(yUp, largest, 1)

rotateScope(0,RotationAng,0)

center(xz)

t(scope.sx-SX,0,0)

t(Translation,0,0)

report("Objects: "+Object_Identity+" Count",1)

i(File_Extension)

s(SX,SY,SZ)

deleteUV(_Texture_Switch)

Bike_Rack_Split(RotationAng,Translation)-->

split(v,unitSpace,0){.7:Bus_Objects_Insert("Bike

Rack",Bike_Rack_Object,RotationAng,Translation,.1,1,.3)

|.7:Bus_Objects_Insert("Bike

Rack",Bike_Rack_Object,RotationAng,Translation,.1,1,.3)

|~1:NIL}

Median_Bike_Rack_Split(RotationAng,Translation)-->

case RotationAng==180:

split(v,unitSpace,0){.7:Bus_Objects_Insert("Bike

Rack",Bike_Rack_Object,RotationAng,Translation,.1,1,.3)

|.7:Bus_Objects_Insert("Bike

Rack",Bike_Rack_Object,RotationAng,Translation,.1,1,.3)

|~1:NIL}

else:

split(v,unitSpace,0){~1:NIL

|.7:Bus_Objects_Insert("Bike

Rack",Bike_Rack_Object,RotationAng,Translation,.1,1,.3)

|.7:Bus_Objects_Insert("Bike

Rack",Bike_Rack_Object,RotationAng,Translation,.1,1,.3)}

Median_Plant_Base-->

case Median_Ground_Cover =="None":

WalkWay_Texture

else:

Tree_Setup("Median", Median_Tree_1_Percentage ,

Median_Tree_1_Type,Median_Tree_2_Type )

Median_Planting

Median_Planting-->

case Median_Ground_Cover =="Random":

tileUV(0,2,2) texture(Random_Grass)

deleteUV(_Texture_Switch)

Pervious_Reporting

else:

tileUV(0,2,2)texture(GrassFolder+"/"+ Median_Ground_Cover +

".jpg")

deleteUV(_Texture_Switch)

Pervious_Reporting

OpenSpace_Planting-->

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

159

scatter(surface,geometry.du(0,unitSpace)/3,uniform) {

Tree_Setup("Median", Median_Tree_1_Percentage ,

Median_Tree_1_Type,Median_Tree_2_Type ) }

tileUV(0,2,2) texture(Random_Grass)

deleteUV(_Texture_Switch)

Pervious_Reporting

WalkWay_Texture-->

tileUV(0,2,2) texture(Sidewalk_Texture)

deleteUV(_Texture_Switch)

scaleUV(0, Sidewalk_Texture_Scale, Sidewalk_Texture_Scale)

rotateUV(0, Sidewalk_Texture_Rotation)

color(_Usage("Pedestrian"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

report("Center: Median Walkway Area (m^2)",geometry.area())

#Object Loading Insertion

Master_Split(Boulevard_Side,Start_Condition, Location,Dir)-->#The Bus Stop,

Bike Racks, and WayFinder are put here.

case Start_Condition:

case Boulevard_Side==2:

split(u,unitSpace,0){~Median_Bench_Spacing/2:NIL|

{~2:Bench_Rule(Boulevard_Side,Dir)}|~Median_Bench_Spacing/2:NIL}*

else:

split(u,unitSpace,0){~Median_Bench_Spacing/2:NIL|

{~2:Bench_Rule(Boulevard_Side,Dir)}|~Median_Bench_Spacing/2:NIL}*

else:

NIL

Bench_Rule(Boulevard_Side,Dir)--> # DEAL WITH BUSTOP ANOTHER WAY_ DO A

SPLIT THAT GROWS

case Center_Type=="Boulevard":

alignScopeToAxes(y)

alignScopeToGeometry(yUp, largest, Boulevard_Side)#Side

corresponds to appropriate edge selection

Bench_Rotater(Dir)

else:

alignScopeToAxes(y)

alignScopeToGeometry(yUp, largest, 0)

Bench_Rotater(Dir)

Bench_Rotater(Dir)-->

case Dir==2:

rotateScope(0,90,0)

Bench_Insert(Dir)

else:

rotateScope(0,270,0)

Bench_Insert(Dir)

Bench_Insert(Dir)-->

case Dir==2 && (Median_Benches=="Both"||Median_Benches=="Left"):

s(1,1,2)

center(xz)

t(-WalkWay_Width/2+Bench_Adjuster,0,0)

report("Objects: Bench Count",1)

i(Bench_Object)

deleteUV(_Texture_Switch)

case Dir==0 && (Median_Benches=="Both"||Median_Benches=="Right"):

s(1,1,2)

center(xz)

report("Objects: Bench Count",1)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

160

t(-WalkWay_Width/2+Bench_Adjuster,0,0)

i(Bench_Object)

deleteUV(_Texture_Switch)

else:

NIL

Street_Lamp_Center(Location,Dir)-->

case Location=="Boulevard":

split(u,unitSpace,0) {~ Median_Street_Lamp_Spacing :NIL

|{1:Street_Lamp_Sider(Dir)

|~ Median_Street_Lamp_Spacing

:NIL}*}

case Location=="Median":

split(u,unitSpace,0) {~ Median_Street_Lamp_Spacing:NIL

|{1:Street_Lamp_Sider(0) #Median

Dir should be set to 0 to grab right edge

|~ Median_Street_Lamp_Spacing

:NIL}*}

else:

NIL

Street_Lamp_Sider(Dir)-->

case Median_Street_Lamps =="Both":

split(v,unitSpace,0) {.5:Lamp_Center_Asset(90,case Dir==0:0

else:2,Dir)

|~1:NIL

|.5:Lamp_Center_Asset(-180,case

Dir==0:5 else:3,Dir)}

case Median_Street_Lamps =="Right":

split(v,unitSpace,0) {~1:NIL

|.5:Lamp_Center_Asset(-180,case

Dir==0:5 else:3,Dir)}

case Median_Street_Lamps =="Left":

split(v,unitSpace,0) {.5:Lamp_Center_Asset(90,case Dir==0:0

else:2,Dir)

|~1:NIL}

else:

NIL

Lamp_Center_Asset(Side_Rotation,Shape_Edge,Dir)-->

alignScopeToGeometry(yUp, largest,Shape_Edge)

alignScopeToAxes(y) // place the Lamps vertically

center(xz)

s(0,5,0) //set initital height to 5 others are

based on OBJ

r(0,Side_Rotation,0)

report("Objects: Street Lamp Count", 1)

i(Street_Lamp_Object)

deleteUV(_Texture_Switch)

##########################################

#Tree Loader Code

Median_TreeSplit-->

#color(rand(1),rand(1),rand(1))

split(u,unitSpace,0){{~Median_Tree_Spacing/2:NIL

|1:Tree_Setup("Median",

Median_Tree_1_Percentage , Median_Tree_1_Type, Median_Tree_2_Type)

|~Median_Tree_Spacing/2:NIL}*}

Tree_Setup(Location,Percentage1,Tree_Type1,Tree_Type2)-->

s(0,0,0) // set scope

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

161

r(scopeCenter, 0,rand(0,360),0)// random rotate

alignScopeToAxes(y)

center(xz)

TreeInsert(Location,Percentage1,Tree_Type1,Tree_Type2)

TreeInsert(Location,Percentage1,Tree_Type1,Tree_Type2) -->

case texturingOn:

case p(Percentage1):

s(0,0,0)

report("Vegetation: Construction, Tree

Cost",TreeCostAverage)

set(Tree.Name, Tree_Type_Adjusted(Tree_Type1))

#set(Tree.Height, _Tree_Height(Tree_Type1))

#set(Tree.Radius,_Tree_Radius(Tree_Type1))

Tree.Generate

case Tree_Type2!="None":

s(0,0,0)

report("Vegetation: Construction, Tree Cost",

TreeCostAverage)

set(Tree.Name, Tree_Type_Adjusted(Tree_Type2))

Tree.Generate

else:

NIL

else: #If Texturing is off, the tree texture is overrided to the

current thematic color

case p(Percentage1):

s(0,0,0)

report("Vegetation: Construction, Tree

Cost",TreeCostAverage)

set(Tree.Name, Tree_Type_Adjusted(Tree_Type1))

set(Tree.OverwriteColor,_Usage("Plantings"))

Tree.Generate

case Tree_Type2!="None": #So if the percentage if 50%, and

Tree1 does not fire, if tree 2 is not set to None, that tree 2 will be

selected.

s(0,0,0)

report("Vegetation: Construction, Tree Cost",

TreeCostAverage)

set(Tree.Name, Tree_Type_Adjusted(Tree_Type2))

set(Tree.OverwriteColor,_Usage("Plantings"))

Tree.Generate

else:

NIL

Tree_Type_Adjusted(Tree_Type) =

case Tree_Type == "Random": randomTreeType

else: Tree_Type

randomTreeType =

20%: "Tree of Heaven"

20%: "White Ash"

20%: "Common Hackberry"

20%: "Sweetgum"

else: "Sassafras"

###################################################

###################################################

# Crosswalk

#

Crosswalk(crosswalkType,uvSet) -->

case crosswalkType == "transverse" : CrosswalkTransverse(uvSet)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

162

case crosswalkType == "dashed" : CrosswalkDashed(uvSet)

case crosswalkType == "ladder" : CrosswalkLadder(uvSet)

case crosswalkType == "solid" : AsphaltPainted(

Crosswalk_Color,true,1,"Conflict Zones")

case crosswalkType == "custom" : CrosswalkWalkway(true)

case crosswalkType == "ladder custom": CrosswalkLadderWalkway(uvSet)

else : CrosswalkContintental

CrosswalkContintental -->

report("Crosswalk: Crosswalk Area",geometry.area())

split(v,uvSpace,0){ (ceil(geometry.vMin-0.01)-geometry.vMin):

Asphalt(true,1,"Conflict Zones")

| ~1: CrosswalkStripes(1)

| geometry.vMax-floor(geometry.vMax+0.01):

Asphalt(true,1,"Conflict Zones") }

CrosswalkLadder(uvSet) -->

report("Crosswalk: Crosswalk Area",geometry.area())

split(u,uvSpace,uvSet){ 0.17: AsphaltPainted(

Crosswalk_Color,true,1,"Conflict Zones")

| ~1 : CrosswalkStripes(1)

| 0.17: AsphaltPainted(

Crosswalk_Color,true,1,"Conflict Zones" ) }

CrosswalkTransverse(uvSet) -->

report("Crosswalk: Crosswalk Area",geometry.area())

split(u,uvSpace,uvSet){ 0.27: AsphaltPainted(

Crosswalk_Color,true,1,"Conflict Zones" )

| ~1 : Asphalt(true,1,"Conflict

Zones")

| 0.27: AsphaltPainted(

Crosswalk_Color,true,1,"Conflict Zones" ) }

CrosswalkLadderWalkway(uvSet)-->

report("Crosswalk: Crosswalk Area",geometry.area())

split(u,uvSpace,uvSet){ 0.27: AsphaltPainted(

Crosswalk_Color,true,1,"Conflict Zones")

| ~1 : CrosswalkWalkway(false)

| 0.27: AsphaltPainted(

Crosswalk_Color,true,1,"Conflict Zones" ) }

CrosswalkDashed(uvSet) -->

report("Crosswalk: Crosswalk Area",geometry.area())

split(u,uvSpace,uvSet){ 0.17: CrosswalkStripes(0.6)

| ~1 : Asphalt(true,1,"Conflict

Zones")

| 0.17: CrosswalkStripes(0.6) }

CrosswalkStripes(stripeWidth) -->

report("Crosswalk: Crosswalk Area",geometry.area())

cleanupGeometry(all, 0.001)

tileUV(0,0,~1) scaleUV(0,1,1/8/stripeWidth) # to setup the

v-direction: a continental crosswalk line is 1m width, and the texture

contains 8 of these.

texture(StreetTextureFolder + "/Lanes/crosswalk_continental_"+

Crosswalk_Color +".jpg")

deleteUV(_Texture_Switch)

color(_Usage("Conflict Zones"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

AsphaltPainted(Crosswalk_Color,false,Crosswalk_PaintFraction,"Conflic

t Zones")

Asphalt(false,1-Crosswalk_PaintFraction,"Conflict Zones")

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

163

CrosswalkWalkway(reporting)-->

case reporting:

tileUV(0,2,2) texture(Custom_Crosswalk_Texture)

deleteUV(_Texture_Switch)

color(_Usage("Conflict Zones"))#If Display Thematics==Usage,

goes to usage, if not, Thematic.

report("Crosswalk: Crosswalk Area",geometry.area())

else:

tileUV(0,2,2) texture(Custom_Crosswalk_Texture)

deleteUV(_Texture_Switch)

color(_Usage("Conflict Zones"))#If Display Thematics==Usage,

goes to usage, if not, Thematic.

###################################################

# Other default Start Rules of the graph

#

#Many are only sent to Asphalt. This includes joints, crossings, and

junctions.

# drive-through street segments

Joint -->

BridgeMain

report("Joint Area",geometry.area())#Only reports given to Joints

Asphalt(true,1,"Auto")

Junction -->

BridgeMain

report("Intersection Area",geometry.area())

Asphalt(true,1,"Auto")

Freeway -->

report("Freeway Area",geometry.area())#Only reports given to

freeways.

set(streetWidth,geometry.dv(0,unitSpace))

set( Lane_Width ,streetWidth/geometry.dv(0,uvSpace))

split(v,unitSpace,0){ Lane_Width *18/256: tileUV(0,0,- Lane_Width )

MainLaneMarkings(0,split.index,"_stripes_white") # with tileUV we make

sure that the v-coord starts always at zero (independent of the direction

of the segment) and since the last stripe is on the top of the texture, we

have to reverse the v-coord

| { Lane_Width :

MainLaneMarkings(0,split.index,"_stripes_white")}*

| Lane_Width

:Asphalt(true,1,"Auto")}

BridgeMain

# crossing is just Asphalt for now

Crossing -->

BridgeMain

report("Crossing Area", geometry.area())#Only reports given to

crossings

Asphalt(true,1,"Auto")

# freeway entries have an additional striped line (splits the shape into

lanes but also splits away a shape just for the striped line using special

UVSET 1

FreewayEntry -->

report("Freeway Entry Area",geometry.area())#Only reports given to

freeways.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

164

set(streetWidth,geometry.dv(0,unitSpace))

set( Lane_Width ,streetWidth/geometry.dv(0,uvSpace))

split(v,unitSpace,1){ Lane_Width *18/256: tileUV(0,0,- Lane_Width )

MainLaneMarkings(0,split.index,"_stripes_white") # with tileUV we make

sure that the v-coord starts always at zero (independent of the direction

of the segment) and since the last stripe is on the top of the texture, we

have to reverse the v-coord

| { Lane_Width :

MainLaneMarkings(0,split.index,"_stripes_white")}* }

BridgeMain

###################################################

# Roundabout

#

Roundabout -->

case valency>1: Asphalt(true,1,"Auto") BridgeMain

#split(v,unitSpace,0){ 1: MainLaneMarkings(0,split.index,"_stripes_white")

}*

else : Asphalt(true,1,"Auto") BridgeMain

# cul-de-sac is Asphalt only

RoundaboutIsland -->

case Sidewalk_Ground_Cover !="None": IslandWithGreen BridgeMain

else : Asphalt(true,1,"Auto") BridgeMain

# cul-de-sac is Asphalt only

IslandWithGreen -->

offset(- Sidewalk_Height )

comp(f){ inside: Tree_Scatter

| border: setupProjection(0,scope.xy,'1,'1) projectUV(0)

Curbs_Mass(false) }

Green -->

translate(rel,world,0, Sidewalk_Height ,0)

setupProjection(0,scope.yx,2,2) projectUV(0)

texture(Random_Grass)

deleteUV(_Texture_Switch)

Pervious_Reporting

Tree_Scatter-->

scatter(surface,3,gaussian,center,'2) { Tree_Setup("Round About",

Sidewalk_Tree_1_Percentage ,Sidewalk_Tree_1_Type,Sidewalk_Tree_2_Type) }

Green

###################################################

# Sidewalk

#

Sidewalk-->

BridgeSide

set(SidewalkWidth,scope.sz)

set(SidewalkLength,scope.sx)

color(_Usage("Pedestrian"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

report("Cut/Fill: Total Sidewalk Cut/Fill Volume (m^3)",

geometry.area()*Sidewalk_Height)

report("Sidewalk: Total Sidewalk Area (m^2)", geometry.area())

split(v,unitSpace,0){Curb_Depth: Curbs_Mass(false)

| ~1: Sidewalk_Setup }

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

165

Curbs_Mass(RotateUV)-->

extrude(world.y, Sidewalk_Height )

comp(f) {top:Curbs(RotateUV)|side:Curbs(false)}

Curbs(RotateUV) -->

case RotateUV:#Used to handle an exception where scope changes on

horizontal curbs (parallel to crosswalk)

rotateUV(0,270)

setupProjection(0,scope.yx,~2,'1)#Notice axis choice changed.

texture(SidewalkFolder+"/curbs_2m.jpg")

projectUV(0)

deleteUV(_Texture_Switch)

else:

setupProjection(0,scope.xy,~2,'1)

texture(SidewalkFolder+"/curbs_2m.jpg")

projectUV(0)

deleteUV(_Texture_Switch)

Sidewalk_Setup-->

case sidewalkSide=="Right":

extrude(world.y, Sidewalk_Height )

comp(f){top=SidewalkTop|side:Pavement("Building Side") }

case sidewalkSide=="Left":

scaleUV(0,1,1)

extrude(world.y, Sidewalk_Height )

comp(f){top=SidewalkTop|side:Pavement("Building Side") }

else:

print("Error: two right sidewalks as default- please map this

attribute.")

extrude(world.y, Sidewalk_Height )

comp(f){top=SidewalkTop|side:Pavement("Building Side") }

SidewalkTop-->

case valency>1:

Pavement("Corners")

case Sidewalk_Ground_Cover =="None":

split(v,unitSpace,0)

{CurbtoPlantingGap:Sign_Loader|~1:Pavement("Through Zone") People}

else:

split(v,unitSpace,0){CurbtoPlantingGap:Sign_Loader

|Sidewalk_Planting_Width:

Sidewalk_Loading_Section(case sidewalkSide=="Right":0 else:2)

|~1:Pavement("Through Zone")

People}

Sign_Loader-->

Pavement("Sign Gap")

Traffic_Light_Setup

Parking_Meter_Setup

Lamp_Setup

Lamp_Setup-->

case Sidewalk_Street_Lamps =="None":

NIL

case sidewalkSide=="Right":

case Sidewalk_Street_Lamps =="Right" || Sidewalk_Street_Lamps

=="Both":

split(u,unitSpace,0) {~ Sidewalk_Street_Lamp_Spacing :NIL

|{.1:Lamp(0)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

166

|~

Sidewalk_Street_Lamp_Spacing :NIL}*}

else:

NIL

case sidewalkSide=="Left":

case Sidewalk_Street_Lamps =="Left" || Sidewalk_Street_Lamps

=="Both":

split(u,unitSpace,0) {~ Sidewalk_Street_Lamp_Spacing :NIL

|{.1:Lamp(2)

|~

Sidewalk_Street_Lamp_Spacing :NIL}*}

else:

NIL

else:

NIL

Traffic_Light_Setup-->

case Traffic_Lights=="None":

NIL

case sidewalkSide=="Right":

case Traffic_Lights=="Right" || Traffic_Lights=="Both":

split(u,unitSpace,0) {_crosswalkEndWidth-3.5:NIL #-3.5 is

so that if if the crosswalk is short its just placed at the end of the

sidewalk-handles up to 9 m crosswalks well.

|1:Traffic_Light(0)

|~1:NIL}

else:

NIL

case sidewalkSide=="Left":

case Traffic_Lights=="Left" || Traffic_Lights=="Both":

split(u,unitSpace,0) {_crosswalkEndWidth-3.5:NIL #-3.5 is

so that if if the crosswalk is short its just placed at the end of the

sidewalk-handles up to 9 m crosswalks well.

|1:Traffic_Light(2)

|~1:NIL}

else:

NIL

else:

NIL

Traffic_Light(index)-->

alignScopeToAxes(y) // place the Lamps vertically

s(0,5,0) // set height to 5 meters

Traffic_Light_Asset(index)

Traffic_Light_Asset(index)-->

r(0,90,0)

report("Objects: Traffic Lights Count", 1)

i(Traffic_Light_Object)

deleteUV(_Texture_Switch)

Lamp(index) -->

alignScopeToAxes(y) // place the Lamps vertically

center(xz)

s(0,5,0) // set height to 5 meters

report("Objects: Street Lamp Count", 1)

LampAsset(index) // since the scope's dimenstion are zero in x

and z, these are set according to the asset

LampAsset(nr) -->

case nr == 2 : r(0,90,0)

i(Street_Lamp_Object)deleteUV(_Texture_Switch)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

167

else : r(0,90,0) i( Street_Lamp_Object)

deleteUV(_Texture_Switch)

Parking_Meter_Setup-->

case Parking_Meters=="None":

NIL

case sidewalkSide=="Right":

case Parking_Meters=="Right" || Parking_Meters=="Both":

Parking_Meter_Loader(Right_Parking_Length,0)

else:

NIL

case sidewalkSide=="Left":

case Parking_Meters=="Left" || Parking_Meters=="Both":

Parking_Meter_Loader(Left_Parking_Length,2)

else:

NIL

else:

NIL

Parking_Meter_Loader(Parking_Length,Dir)-->

split(u,unitSpace,0) {(_Sidewalk_CrossStop_Gap(Dir,"Begin") +

Parking_Meter_Setback):NIL # moves starting point for meters into near

middle

|{.25:Sign_Objects_Insert("Parking

Meter",Parking_Meter_Object,0,0,.3,1.4,.3)

|~Parking_Meters_Spacing:NIL}*

|(_Sidewalk_CrossStop_Gap(Dir,"End")):NIL}

Pavement(Location) -->

case Location== "Through Zone" || Location=="Corners":

alignScopeToAxes(y)

tileUV(0,2,2)

texture(Sidewalk_Texture)

deleteUV(_Texture_Switch)

scaleUV(0, Sidewalk_Texture_Scale, Sidewalk_Texture_Scale)

rotateUV(0, Sidewalk_Texture_Rotation)

report("Sidewalk: "+Location+" Area (m^2)",geometry.area())

case Location=="Building Side":

setupProjection(0,scope.xy,2, 2)

texture(Sidewalk_Texture)

projectUV(0)

deleteUV(_Texture_Switch)

scaleUV(0, Sidewalk_Texture_Scale, Sidewalk_Texture_Scale)

rotateUV(0, Sidewalk_Texture_Rotation)

else:

alignScopeToAxes(y)

tileUV(0,2,2)

texture(Sidewalk_Texture)

deleteUV(_Texture_Switch)

scaleUV(0, Sidewalk_Texture_Scale, Sidewalk_Texture_Scale)

rotateUV(0, Sidewalk_Texture_Rotation)

Sidewalk_Loading_Section(Dir)-->

split(u,unitSpace,0){(_Sidewalk_CrossStop_Gap(Dir,"Begin")):Pavement(

"Cross Walk Begin Gap")

|~_Bus_Sidewalk_Base("Near-

side"):Bus_Stop_Base("Sidewalk",0)

|~geometry.du(0,unitSpace)/2:Sidewalk_Plant_Side("Begin")

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

168

|~_Bus_Sidewalk_Base("Mid-

Block"):Bus_Stop_Base("Sidewalk",0)

|~geometry.du(0,unitSpace)/2:Sidewalk_Plant_Side("End")

|~_Bus_Sidewalk_Base("Far-

side"):Bus_Stop_Base("Sidewalk",0)

|(_Sidewalk_CrossStop_Gap(Dir,"End")

):Pavement("Cross Walk End Gap")}

Sidewalk_Object_Split(RotationAng)-->

split(u,unitSpace,0){'_Bus_Alloc("Sidewalk"):Bus_Objects_Insert("Bus

Stop",Bus_Stop_Object,RotationAng,Sidewalk_Bus_Stop_Setback,2,3,3.35)

|'_Bike_Rack_Alloc("Sidewalk"):Bike_Rack_Split(RotationAng,0)

|'_WayFinder_Alloc("Sidewalk"):Bus_Objects_Insert("Wayfinder",Wayfind

er_Object,RotationAng,-.5,.3,3,1.2)}

Sidewalk_Plant_Side(Plant_Side_Base_Switch)-->

split(u,unitSpace,0){~Sidewalk_Planting_Spacing /2:Pavement("Before

Planting")

|~Sidewalk_Planting_Length:Plant_Base

|~Sidewalk_Planting_Spacing/2:Pavement("After Planting")

Sidewalk_Bench_Loader(split.index,split.total,Plant_Side_Base_Switch)}*

Sidewalk_Bench_Loader(splitNum,splitTotal,Plant_Side_Base_Switch)-->

case Sidewalk_Benches =="None":

NIL

case sidewalkSide=="Right" && (splitNum!=splitTotal-1 ||

Plant_Side_Base_Switch!="End"):#Does not place a bench on the end split of

the End Sidewalk_Plant_Side_Base (if Switch is removed no bench is

generated mid-block)

case Sidewalk_Benches =="Right" || Sidewalk_Benches=="Both":

Sidewalk_Bench_Insert(0,geometry.du(0,unitSpace))

else:

NIL

case sidewalkSide=="Left" && (splitNum!=splitTotal-1 ||

Plant_Side_Base_Switch!="End"): #Does not place a bench on the end

case Sidewalk_Benches =="Left" || Sidewalk_Benches=="Both":

Sidewalk_Bench_Insert(2,geometry.du(0,unitSpace))

else:

NIL

else:

NIL

Sidewalk_Bench_Insert(Dir,geometry_Len)-->

case geometry.du(0,unitSpace)>1: #Remember two gaps, so it is 2

(width of bench)/2

alignScopeToAxes(y)

alignScopeToGeometry(yUp, largest, 0)

rotateScope(0,90,0)

s(1,1,2)

t(.5,0,geometry_Len-1)#When geometry.du is used functionality

is different (alignment issue?) passed parameter works best likely because

it is before scope manipulation (rotate etc)dv. might work instead.

report("Objects: Bench Count",1)

i(Bench_Object)

deleteUV(_Texture_Switch)

else:

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

169

NIL

Plant_Base-->

case Sidewalk_Ground_Cover =="None":

Pavement("Plant_Space")

else:

Sidewalk_Planting

Tree_Setup("Sidewalk", Sidewalk_Tree_1_Percentage ,

Sidewalk_Tree_1_Type, Sidewalk_Tree_2_Type )

Sidewalk_Planting--># THis is set up this way to support a vegetated buffer

with no trees on sidewalk

case Sidewalk_Ground_Cover =="None":

tileUV(0,2,2) texture(Random_Grass)

deleteUV(_Texture_Switch)

Pervious_Reporting

case Sidewalk_Ground_Cover =="Random":

tileUV(0,2,2) texture(Random_Grass)

deleteUV(_Texture_Switch)

Pervious_Reporting

else:

tileUV(0,2,2)texture(GrassFolder+"/"+ Sidewalk_Ground_Cover +

".jpg")

deleteUV(_Texture_Switch)

Pervious_Reporting

Sign_Objects_Insert(Object_Identity,File_Extension,RotationAng,Translation,

SX,SY,SZ)-->#Sidewalk Object Constructor Rule

alignScopeToAxes(y)

alignScopeToGeometry(yUp, largest, 1)

rotateScope(0,RotationAng,0)

center(xz)

t(scope.sx-SX,0,0)

t(Translation,0,0)

i(File_Extension)

s(SX,SY,SZ)

report("Objects: "+Object_Identity+" Count",1)

deleteUV(_Texture_Switch)

##################################################

#Paint Reporting

#Asphalt Painted is actually retrofitted to be the paint reporting

aggregator, all "Paint Areas" originate here.

AsphaltPainted(paintColor,TextureAndReport,Area_Fraction,Usage) -->

case Area_Fraction==0:# If the area fraction is 0, we don't even want

to have it be included in the sum (throws off averages/stats).

NIL

case TextureAndReport && paintColor!="black":# This makes sure that

if the color is black, it is thrown into Asphalt Reporting

tileUV(0,7,7)

cleanupGeometry(all,0.001)

texture(StreetTextureFolder + "/Lanes/asphalt_painted_" +

paintColor + "_7x7m.jpg")

deleteUV(_Texture_Switch)

color(_Usage(Usage))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

report("Paint: "+paintColor+" Painted Area

(m^2)",geometry.area*Area_Fraction)

report("Paint Cost Estimate: "+paintColor+" Painted Area

($)",(geometry.area*Area_Fraction*SquareFeet)*_PaintCost(paintColor))

case paintColor=="black":#If Black redirect to asphalt rule.

Asphalt(TextureAndReport,Area_Fraction,Usage)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

170

else:#Only Reports no texturing desired.

report("Paint: "+paintColor+" Painted Area (m^2)",

(geometry.area*Area_Fraction))

report("Paint Cost Estimate: "+paintColor+" Painted Area

($)",(geometry.area*Area_Fraction*SquareFeet)*_PaintCost(paintColor))

# ------------------Paint:-------------------------

#######################################################################

#Vehicles

#

# Sample assets provided by lowpolygon3d.com

#

# More assets with high-res textures can be

# purchased at http://www.lowpolygon3d.com.

#

# -------------------------------------------

vehicleAsset(type) = fileRandom(StreetTextureFolder +

"/LowPolygon3D.com_Vehicles/" + type + "/*.obj")

const vehiclesProb = ( Vehicles_Per_KM *minCarDistance)/1000

const busProb = (Bus_Lane_Buses_Per_KM*minCarDistance)/1000

const minCarDistance = 6

BusOnLane(dir)-->

case geometry.du(0,unitSpace)>10:

split(u,unitSpace,0){ ~1: BusOnLane(dir) | (rand(15,25)):

Bus_Vehicle(dir,"bus") }

else:

NIL

VehiclesOnLane(dir) -->

case geometry.du(0,unitSpace) > 1000:

split(u,unitSpace,0){ '0.5: VehiclesOnLane(dir) | '0.5:

VehiclesOnLane(dir) }

case geometry.du(0,unitSpace) > 10 && p(

Mixed_Traffic_Bus_Percentage):

split(u,unitSpace,0){ ~1: VehiclesOnLane(dir) | (rand(15,25)):

Vehicle(dir,"bus") }

case geometry.du(0,unitSpace) > 5:

split(u,unitSpace,0){ ~1: VehiclesOnLane(dir) |

(rand(minCarDistance,15)): VehicleTaxiOrCar(dir) }

else:

NIL

VehicleTaxiOrCar(dir) -->

case p(Taxi_Percentage):

Vehicle(dir,"taxi")

else:

Vehicle(dir,"car")

Bus_Vehicle(dir,type) -->

case p(busProb):

split(u,unitSpace,0){ ~1: NIL | 0.5:

alignScopeToGeometry(yUp,dir) VehicleAsset(type) | ~1: NIL }

else:

NIL

Vehicle(dir,type) -->

case p(vehiclesProb):

split(u,unitSpace,0){ ~1: NIL | 0.5:

alignScopeToGeometry(yUp,dir) VehicleAsset(type) | ~1: NIL }

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

171

else:

NIL

VehicleAsset(type) -->

t(0,0,'rand(0.4,0.6))

s(0,0,0)

r(0,90,0)

r(0,DirectionalRotation,0)

i(vehicleAsset(type))

color(_Usage(case type=="bus":"Transit" else:"Auto"))

Delete_Texture

# -------------------------------------------

# Cyclists

#

# Sample assets provided by lowpolygon3d.com

#

# More assets with high-res textures can be

# purchased at http://www.lowpolygon3d.com.

#

# -------------------------------------------

bikeAsset = fileRandom(StreetTextureFolder +

"/LowPolygon3D.com_Cyclists/*.obj")

const bikeProb = (Bicycles_Per_KM * minBikeDistance)/1000

const minBikeDistance = 2

Bikes(dir,Bike_Lane_Width) -->

case bikeProb > 0:

BikesOnLane(dir,Bike_Lane_Width)

else:

NIL

BikesOnLane(dir,Bike_Lane_Width) --> #Fix: Lots of logic here that doesn't

apply to bikes, since it was adapted from car logic.

case geometry.du(0,unitSpace) > 1000:

split(u,unitSpace,0){ '0.5: BikesOnLane(dir,Bike_Lane_Width) | '0.5:

BikesOnLane(dir,Bike_Lane_Width) }

case geometry.du(0,unitSpace)> 10:

split(u,unitSpace,0){ ~1: BikesOnLane(dir,Bike_Lane_Width) |

(rand(minBikeDistance,minBikeDistance*2)): Bike(dir,Bike_Lane_Width) }

case geometry.du(0,unitSpace) > 5:

split(u,unitSpace,0){ ~1: BikesOnLane(dir,Bike_Lane_Width) |

(rand(minBikeDistance,3)): Bike(dir,Bike_Lane_Width) }

else:

NIL

Bike(dir,Bike_Lane_Width) -->

case p(bikeProb):

split(u,unitSpace,0){ ~1: NIL | 0.5:

alignScopeToGeometry(yUp,dir) BikeAsset(Bike_Lane_Width) | ~1: NIL }

else:

NIL

BikeAsset(Bike_Lane_Width) -->

rotateScope(0,DirectionalRotation,0)

t(0,0,Bike_Lane_Width/2 + rand(-Bike_Lane_Width/4,Bike_Lane_Width/4))

s(0,0,0) i(bikeAsset) r(scopeCenter,0,90,0)

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

172

Bike_Delete_Texture_Color # will only color when textures are

removed.

Bike_Delete_Texture_Color-->

case texturingOn:

X.

else:

deleteUV(0)

color(_Usage("Bikeways"))

# Our bicycle models have both textured and colored parts.

# So when texturing is off, we still need to change the color

of the bikes.

# color(thematicColor)- see remove_Bike_color

Delete_Texture-->

case texturingOn:

X.

else:

deleteUV(0)

# -------------------------------------------

# People

#

# Sample assets provided by lowpolygon3d.com

#

# More assets with high-res textures can be

# purchased at http://www.lowpolygon3d.com.

#

# -------------------------------------------

peopleAsset = fileRandom(StreetTextureFolder +

"/LowPolygon3D.com_People/*.obj")

dirHuman = 50%: 90 else: -90

People -->

case geometry.du(0,unitSpace) > 20:

split(u,unitSpace,0){ '0.5: People | '0.5: People }

case People_Percentage > 0:

50% : split(u,unitSpace,0){ { 0.1: Human | ~rand(2,5): NIL |

0.1: Human | ~rand(2,5): NIL }* | 0.1: Human } # could be

distributed better...

else: split(u,unitSpace,0){ { 0.1: Human | ~rand(0.5,5.5): NIL

| 0.1: Human | ~rand(0.5,5.5): NIL }* | 0.1: Human } # could be

distributed better...

else:

NIL

Human -->

case (scope.sz < 2 && p(People_Percentage*0.3))

|| (scope.sz >= 2 && p(People_Percentage)):

alignScopeToAxes(y)

t(0,0,'rand(0.1,0.6))

s(0,rand(1.7,1.9),0) r(0,dirHuman,0)

i(peopleAsset)

color(_Usage("Pedestrian"))

deleteUV(_Texture_Switch)

else:

NIL

# Bridge can be explicitly activated or deactivated,

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

173

# or automatically set by height over terrain.

isBridge = (Bridge_Display == "On, Regardless")

|| (Bridge_Display == "On, Show All Piers")

|| (Bridge_Display == "On, Flag Occlusions")

|| (Bridge_Display == "On, By Elevation" && isRaised)

# Road segment is raised if it is higher than Bridge_Starts_At attribute.

# isRaised DOES NOT imply it is a bridge.

isRaised = heightOverTerrain > Bridge_Starts_At

heightOverTerrain = convert(y, scope, world, pos,

scope.sx * 0.5, scope.sy * 0.5, scope.sz * 0.5) - elevation

# The above convert function finds the y world coordinate at the center

# of the scope, then subtracts the elevation to get the

# height over the terrain.

# NOTE: To use this function, you must add a layer attribute

# to your terrain layer, like this:

# attr elevation = map_01(brightness, 405.20847, 419.22385) +

elevationDelta

BridgeMain -->

case isBridge:

# For debugging:

#print("heightOverTerrain = " + heightOverTerrain)

# Give bridge thickness, sending the street shape to thickness

rule.

BridgeConcrete(Bridge_Thickness)

# Drop street shape down by thickness, to split for piers.

translate(rel, world, 0, -Bridge_Thickness, 0)

# Split to make starting points for piers.

split(u, unitSpace, 0) {

~( Pier_Distance / 2) : NIL

| { Pier_Width : Pier | ~ Pier_Distance : NIL }*

# XX: Not sure why the pattern was repeated in this

manner:

| Pier_Width : Pier | ~ Pier_Distance : NIL

}

case Bridge_Display== "Concrete Extrusion Only":

BridgeConcrete(Bridge_Thickness)

else :

NIL

Pier -->

case heightOverTerrain > 0:

split(v,unitSpace,0){ '0.15: NIL

| '0.70: PierStep2

| '0.15: NIL }

else: NIL

PierStep2 -->

alignScopeToGeometry(yUp,0,0)

# Make "feeler" for occlusion check in next rule.

# Extrude down to the terrain (must be mapped in layer attribute).

extrude(world.y,-heightOverTerrain)

# Align to yUp for feeler scaling.

alignScopeToAxes(y)

# Scale to go past regular pier shape.

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

174

s('1,'20,'1)

t(0,-0.5,0)

# Check if pier will hit something.

PierCheck

PierCheck -->

case (Bridge_Display == "On, Show All Piers"):

# Occlusion test is disabled, by "On, Show All piers".

PierShow

case (Bridge_Display == "On, Flag Occlusions"):

case overlaps(inter):

# This pier hits another model.

print("Occlusion true: Bridge pier overlaps another

model!")

# Flag the pier in red. This is a debugging mode for the

piers.

color(1,0,0)

PierShow

else:

# No occlusion so show the pier.

print("Occlusion false.")

PierShow

else:

# Use standard occlusion method.

case overlaps(inter):

# Omit piers due to positive occlusion check.

# This means the pier would hit a street or other model.

NIL

else:

# No occlusion so show the pier.

PierShow

PierShow -->

# Scale back occlusion feelers, reversing the feeler code.

s('1,'0.05,'1)

t(0,0.5,0)

#

split(y){2.2: PierBase | ~1: PierShafts | 1: BridgeSolid }

# XX: Come back later and make smarter pier sizing code.

PierShafts -->

case scope.sz > 7:

split(x){ 0.5: NIL

| ~1 : split(z){ ~1: NIL | ~3: comp(f){side:

BridgeSolid} | ~4: NIL | ~3: comp(f){side: BridgeSolid} | ~1: NIL }

| 0.5: NIL }

else:

split(x){ 0.5: NIL

| ~1 : split(z){ ~0.5: NIL | ~3: comp(f){side:

BridgeSolid} | ~0.5: NIL }

| 0.5: NIL }

# XX: Come back later and make smarter pier sizing code.

PierBase -->

s('1,scope.sy+5,'1) t(0,-5.3,0) i("builtin:cube")

comp(f){ side: BridgeSolid | top: roofHip(60) split(y){ 0.3:

BridgeSolid } }

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

175

BridgeSide -->

case isBridge:

BridgeRailing

BridgeConcrete(0.4) translate(rel,world,0,-0.4,0)

reverseNormals

comp(f){all: BridgeSlope }

case Bridge_Display== "Concrete Extrusion Only":

BridgeConcrete(Bridge_Thickness)

else: NIL

BridgeCrossing -->

case isBridge:

BridgeConcrete(Bridge_Thickness)

else: NIL

BridgeSlope -->

case geometry.isRectangular(10) && Bridge_Thickness > 2:

roofShed(23,2)

comp(f){all = BridgeMaterial }

else:

NIL

BridgeConcrete(height) -->

translate(rel,world,0,-height,0)

extrude(world.y,height)

comp(f){top: NIL | all= BridgeMaterial }

BridgeRailing -->

case LOD_Setting=="High":

translate(rel,world,0, Sidewalk_Height ,0)

split(v,unitSpace,0){ ~1: NIL | 0.4:

extrude(world.y,0.8)

color(case coloringOn: "#eeeeee" else: "")

comp(f){all: BridgeMaterial} }

split(v,unitSpace,0){ ~1: NIL | 0.1:

translate(rel,world,0,0.8,0)

VerticalRails

translate(rel,world,0,0.3,0)

extrude(world.y,0.05)

RailMaterial

| 0.17: NIL }

else:

translate(rel,world,0, Sidewalk_Height ,0)

split(v,unitSpace,0){ ~1: NIL | 0.4: extrude(world.y,0.8)

color(case coloringOn: "#eeeeee" else: "") comp(f){all: BridgeMaterial } }

split(v,unitSpace,0){ ~1: NIL | 0.1:

translate(rel,world,0,0.8,0) VerticalRails translate(rel,world,0,0.3,0)

comp(f){ all: extrude(world.y,0.05) comp(f){front: RailMaterial} | 0.17:

NIL } }

VerticalRails -->

case LOD_Setting=="High":

comp(f){all: split(x){ ~1 : NIL

| 0.1: s('1,0.07,'1) center(y)

extrude(world.y,0.3) RailMaterial

| { ~2 : NIL

| 0.1: s('1,0.07,'1) center(y)

extrude(world.y,0.3) RailMaterial }*

| ~1 : NIL } }

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

176

else:

comp(f){all: split(x){ ~1 : NIL

| 0.1: s('1,0.07,'1) center(y)

extrude(world.y,0.3) comp(f){front: RailMaterial}

| { ~2 : NIL

| 0.1: s('1,0.07,'1) center(y)

extrude(world.y,0.3) comp(f){front: RailMaterial} }*

| ~1 : NIL } }

BridgeSolid -->

comp(f){ all: setupProjection(2,scope.xy,'1,'1) projectUV(2)

set(material.dirtmap,LanesFolder+"/dirtmap.1.512x512.jpg")

BridgeMaterial }

BridgeMaterial -->

case texturingOn:

setupProjection(0,scope.xy,~12,~9,1) projectUV(0)

texture(Default_Pavement)

else:

X.

RailMaterial -->

case texturingOn:

set(material.specular.r, 1) set(material.specular.g, 1)

set(material.specular.b, 1)

set(material.shininess, 20)

setupProjection(0,scope.xy,~12,~9,1) projectUV(0)

texture(SidewalkFolder+"/Concrete Rough Light.jpg")

RailMaterialStep2

else:

RailMaterialStep2

RailMaterialStep2 -->

case coloringOn:

color("#cccccc")

else:

X.

###################################################

# Misc

#

Pervious_Reporting-->

case peakRunoffDisplayOn:

report("Vegetation: Pervious Area",geometry.area)

color(0,0,1)

X.

else:

report("Vegetation: Pervious Area",geometry.area)

color(_Usage("Plantings"))#If Display Thematics==Usage, goes to

usage, if not, Thematic.

X.

Cut_And_Fill_Reporting(Text_Fill)-->

report("Cut/Fill: Total "+Text_Fill+" Cut/Fill Volume (m^3)",

geometry.area()*Sidewalk_Height)

X.

Asphalt(TextureAndReport,Area_Fraction,Usage) -->

case TextureAndReport:

tileUV(0,14,14)

cleanupGeometry(all, 0.001)

texture(StreetTextureFolder + "/Lanes/asphalt_14x14m.jpg")

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

177

deleteUV(_Texture_Switch)

color(_Usage(Usage))#If Display Thematics==Usage, goes to

usage, if not, Thematic-strings might have other purpose later.

report("Lane: Asphalt Only Area Total

(m^2)",geometry.area*Area_Fraction)

else:

report("Lane: Asphalt Only Area Total

(m^2)",geometry.area*Area_Fraction)

Rumble_Strip-->

tileUV(0,~Rumble_Strip_Len,~Rumble_Strip_Wid)

rotateUV(0,90)

texture(LanesFolder+"/Rumble_Strip.jpg")

deleteUV(_Texture_Switch)

color(_Usage("Auto"))

Asphalt(false,1,"Auto")

Drainage-->

case geometry.dv(0,unitSpace)> Lane_Width /3 &&

Flag_Empty_Space:#Will flag the drainage area as Red if it is >1/3 the

laneWidth-I mean really 1/3 of a lane is drainage? Put a bike lane or

something

tileUV(0,~1,'1)

cleanupGeometry(all, 0.001)

texture(LanesFolder+"/Drainage_Side.jpg")

color(_Usage("Conflict Zones"))#If Display Thematics==Usage,

goes to usage, if not, Thematic.

color(.7,0,0)

deleteUV(_Texture_Switch)

else:

tileUV(0,~1,'1)

cleanupGeometry(all, 0.001)

texture(LanesFolder+"/Drainage_Side.jpg")

color(_Usage("Conflict Zones"))#If Display Thematics==Usage,

goes to usage, if not, Thematic.

deleteUV(_Texture_Switch)

#Fence Rule

Fence(Location)-->

split(v,unitSpace,0) {~1:NIL|

.05:FenceMesh

|~1:NIL}

FencePoles

FenceMesh -->

extrude(world.y,1.3)

alignScopeToAxes(y) #Cast Scope to prevent edge issues

alignScopeToGeometry(yUp, 0, 3)#Cast Scope to prevent edge issues.

FencePrep

FencePrep-->

comp(f) {left=FenceTexture|all:NIL}

FenceTexture -->

case Boulevard_Center_Type=="Chain Link Fence":

setupProjection(0, scope.xy, ~1.2, '1)

projectUV(0)

texture(MiscFolder+"/Fence/wireTexture.png")

deleteUV(_Texture_Switch)

case Boulevard_Center_Type=="Gate Fence":

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

178

setupProjection(0, scope.xy, ~4, '1)

projectUV(0)

texture(MiscFolder+"/Fence/aluminumPerimeter.png")

deleteUV(_Texture_Switch)

else:

setupProjection(0, scope.xy, ~1.2, ~1)

projectUV(0)

texture(MiscFolder+"/Fence/wireTexture.png")

deleteUV(_Texture_Switch)

FencePoles -->

case Boulevard_Center_Type=="Chain Link Fence":

split(u,unitSpace,0) {{0.01: PoleBase | ~ 3.5: NIL }* | 0.01:

PoleBase}

else:

NIL

poleDim = 0.04

PoleBase -->

alignScopeToAxes(y)

s(poleDim, 0, poleDim)

center(xz)

i(MiscFolder+"/Fence/quad.obj")

center(xz)

extrude(world.y, 1.3)

comp(f) {all: PoleTexturing}

PoleTexturing -->

setupProjection(0, scope.xy, 1, 1)

projectUV(0)

texture(MiscFolder+"/Fence/aluLight.png")

#Debugging Rules

#White-->

#envelope(world.up, .1016, .05, 50, .05, 50,.05,60)

#alignScopeToAxes(y)

#t(0,1,0)

#color(1,1,1)

#Red-->

# alignScopeToAxes(y)

# t(0,1,0)

# color(1,0,0)

#Blue-->

#alignScopeToAxes(y)

#t(0,1,0)

#color(0,0,1)

##

6.3. Código empleado para generar los árboles /**

* Created: 7 Nov 2013 19:16:08 GMT

* Modified: Jan 2013, Redlands

* Author: Esri R&D Center Zurich

*/

version "2013.1"

######################################################

# Control Attributes (set by user or geodatabase)

#

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

179

@Order(1) @Range("Alder Buckthorn","Amazon Sword Plant","American

Chestnut","American Sycamore","Apricot","Australian

Pine","Baldcypress","Balsam Fir","Bamboo","Banana Tree","Basswood","Bay

Laurel","Black Locust","Blue Gum Eucalyptus","Boxwood","Cabbage Palm

Fern","California Bay","California Incense Cedar","California

Palm","California Redwood","California Walnut","Coconut Palm","Common

Hawthorn","Common Whitebeam","Conker Tree","Date Palm","Desert

Willow","Douglas Fir","European Beech","European Larch","Ficus","Field

Elm","Flannelbush","Flowering Dogwood","Giant Sequoia","Hedgehog

Agave","Japanese Angelica Tree","Lacy Tree Philodendron","Leyland

Cypress","Lily of the Valley","Lodgepole Pine","Mediterranean

Buckthorn","Mexican Palmetto","Mountain Mahogany","Northern Red

Oak","Norway Maple","Norway Spruce","Orange Tree","Orchid","Oval-leaved

Privet","Palm Lily","Palo Verde","Paper Birch","Parlour Palm","Prickly Pear

Cactus","Red Alder","Red Hickory","Rhododendron Azaleas","Rose","Ruffle

Palm","Saguaro Cactus","Sassafras","Scots Pine","Sea Islands

Yucca","Shadbush","Snake Plant","Southern Magnolia","Spanish

Broom","Strawberry Tree","Sugar Maple","Sunflower","Sweetgum","Umbrella

Acacia","Western Juniper","White Ash","White Oak","White Poplar","White

Willow","Witch

Hazel","","_____________________________","GENERICS","","Generic Dead

Tree","Generic Stump","Generic

Unknown","","_____________________________","PROXIES","","Algarrobo","Ameri

can Elderberry","American Pepper","American Silverberry","Athel

Tamarisk","Avocado","Black Tupelo","Buttonbush","Canada

Buffaloberry","Chinaberry Tree","Chinese Tallow Tree","Common

Hackberry","Common Holly","Common Persimmon","Desert Bitterbrush","European

Hornbeam","Giant Chinquapin","Honey Locust","Hophornbeam","Huckleberry

Shrub","Japanese Hemlock","Japanese Nutmeg","Judas Tree","Lawson

Cypress","Loblolly Bay","Mexican Buckeye","Necklacepod","Northern

Bilberry","Northern White Cedar","Octopus Tree","Osage Orange","Paper Bark

Tree","Pawpaw","Persian Silk Tree","Princess Tree","Smooth

Sumac","Sourwood","Southern Wax Myrtle","Tanoak","Tree of Heaven","Turkish

Hazel","Western Soapberry","White Mulberry","Yellow

Poplar","Yew","","_____________________________","LATIN NAME","","Abies

balsamea","Acacia tortilis","Acer platanoides","Acer saccharum","Aesculus

hippocastanum","Agave stricta","Ailanthus altissima","Aiphanes

horrida","Albizia julibrissin","Alnus rubra","Amelanchier

canadensis","Aralia elata","Arbutus unedo","Asimina triloba","Betula

papyrifera","Bulbophyllum phalaenopsis","Buxus sempervirens","Calocedrus

decurrens","Carnegiea saguaro","Carpinus betulus","Carya ovalis","Castanea

dentata","Casuarina equisetifolia","Celtis occidentalis","Cephalanthus

occidentalis","Cercis siliquastrum","Cercocarpus montanus","Chamaecyparis

lawsoniana","Chamaedorea elegans","Chilopsis linearis","Chrysolepis

chrysophylla","Citrus sinensis","Cocos nucifera","Convallaria

majalis","Cordyline petiolaris","Cornus florida","Corylus

colurna","Crataegus monogyna","Cupressus leylandii","Cyrilla

racemiflora","Diospyros virginiana","Echinodorus bleheri","Elaeagnus

commutata","Eucalyptus globulus","Fagus sylvatica","Ficus

benjamina","Frangula alnus","Fraxinus americana","Fremontodendron

californicum","Generic deadtree","Generic stump","Generic

unknown","Gleditsia triacanthos","Gordonia lasianthus","Hamamelis

virginiana","Helianthus annuus","Ilex aquifolium","Juglans

regia","Juniperus occidentalis","Larix decidua","Laurus nobilis","Ligustrum

ovalifolium","Liquidambar styraciflua","Liriodendron

tulipifera","Lithocarpus densiflorus","Maclura pomifera","Magnolia

grandiflora","Melaleuca quinquenervia","Melia azedarach","Morus alba","Musa

acuminata","Myrica cerifera","Nyssa sylvatica","Opuntia aciculata","Ostrya

virginiana","Oxydendrum arboreum","Parkinsonia aculeata","Paulownia

tomentosa","Persea americana","Philodendron selloum","Phlebodium

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

180

aureum","Phoenix dactylifera","Phyllostachys aurea","Picea abies","Pinus

contorta","Pinus sylvestris","Platanus occidentalis","Populus

tremuloides","Prosopis nigra","Prunus armeniaca","Pseudotsuga

menziesii","Purshia glandulosa","Quercus alba","Quercus rubra","Rhamnus

alaternus","Rhododendron tsutsuji","Rhus glabra","Robinia

pseudoacacia","Rosa grandiflora","Sabal mexicana","Salix alba","Sambucus

canadensis","Sansevieria trifasciata","Sapindus saponaria","Sassafras

albidum","Schefflera actinophylla","Schinus molle","Sequoia

sempervirens","Sequoiadendron giganteum","Shepherdia canadensis","Sophora

tomentosa","Sorbus aria","Spartium junceum","Tamarix aphylla","Taxodium

distichum","Taxus baccata","Thuja occidentalis","Tilia americana","Torreya

nucifera","Triadica sebifera","Tsuga diversifolia","Ulmus

minor","Umbellularia californica","Ungnadia speciosa","Vaccinium

uliginosum","Washingtonia filifera","Yucca gloriosa")

attr Name = "Alder Buckthorn" #

Redlands: removed "Orange Tree" as default until more accurate Orange Tree

model is located (truck is too long).

@Order(2) @Range(0.5,80)

attr Height = getStandardHeight

# default depends on Name (i.e. adapts if user selects another plant

(if not overwritten by user))

@Order(3) @Range(0.5,30)

attr Radius = getRadius

# default depends on Name and Height (and adapts in case user adjusts

only height in Inspector)

@Group("Options",4) @Order(1) @Range("Model","Fan","Analytical")

attr Representation = "Model"

@Group("Options") @Order(2) @Range(0,1)

attr Transparency = 0

@Group("Options") @Order(3) @Color @Description("To turn color overwrite

off, delete the color value (in the text field)")

attr OverrideColor = ""

@Group("Options") @Order(4)

attr RandomRotation = true

@Group("Options") @Order(5) @Description("Note that this tripples the

instance count e.g. web scenes get three times bigger")

attr RandomBrightness = false

@Group("Options") @Order(5) @Range("Mature only","Mature and young")

attr RandomHeights = "Mature and young"

@Group("Options") @Order(6) @Range("None","Metadata","Instance

Information") @Description("Instance Information suited for LumentRT of e-

on Software and other 3rd party applications.")

attr Reporting = "None"

# Constants

const AssetFolder = "Plants"

# no "/" at the end (taken care of

below)

const FallbackPlant = "Generic Unknown"

# this plant representation

is used in case the user-selected plant does not exist in library

const RandomRadiusDeviation = 0.10

# plant radius varies

plus/minus within this percentage

const RandomHeightYoungPercentage = case RandomHeights=="Mature only": 0

else: 0.5 # this percentage gives random heights below the minheight

######################################################

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

181

# Library Functions (suited for external usage)

#

# attribute lookups

getGenus(commonName) =

_genus(_indexFromCommonName(commonName))

getSpecies(commonName) =

_species(_indexFromCommonName(commonName))

getWikipediaURL(commonName) =

_wikipediaURL(_indexFromCommonName(commonName)) # consists

of latin name

getStandardHeight(commonName) =

_heightAvg(_indexFromCommonName(commonName))

getMinimumHeight(commonName) =

_heightMin(_indexFromCommonName(commonName))

getMaximumHeight(commonName) =

_heightMax(_indexFromCommonName(commonName))

getRandomHeight(commonName) =

_randomHeight(_indexFromCommonName(commonName))

getStandardRadius(commonName) =

_radiusAvg(_indexFromCommonName(commonName))

getStandardTrunkRadius(commonName) =

_trunkRadiusAvg(_indexFromCommonName(commonName))

getStandardTrunkHeight(commonName) =

_trunkHeightAvg(_indexFromCommonName(commonName))

getRegions(commonName) =

_regions(_indexFromCommonName(commonName))

getCrownShape(commonName) =

_crownShape(_indexFromCommonName(commonName))

isProxy(commonName) =

_proxy(_indexFromCommonName(commonName)) != "X"

# attribute lookups assuming that Name attr has been set correctly set

getGenus = _genus(_indexFromCommonName(Name))

getSpecies = _species(_indexFromCommonName(Name))

getLatinName = getGenus + " " + getSpecies

getWikipediaURL = _wikipediaURL(_indexFromCommonName(Name))

# consists of latin name

getStandardHeight = _heightAvg(_indexFromCommonName(Name))

getMinimumHeight = _heightMin(_indexFromCommonName(Name))

getMaximumHeight = _heightMax(_indexFromCommonName(Name))

getRandomHeight = _randomHeight(_indexFromCommonName(Name))

getStandardRadius = _radiusAvg(_indexFromCommonName(Name))

getRegions = _regions(_indexFromCommonName(Name))

getHardinessZoneMin = _zoneMin(_indexFromCommonName(Name))

getHardinessZoneMax = _zoneMax(_indexFromCommonName(Name))

getCrownShape = _crownShape(_indexFromCommonName(Name))

isProxy = _proxy(_indexFromCommonName(Name)) != "X"

# attribute lookups assuming that Name and Height have been set

getRadius = _radius(_indexFromCommonName(Name),Height)

# relative to current height

getRandomRadius = _randomRadius(_indexFromCommonName(Name),Height)

# +-5% of default radius

getTrunkHeight = _trunkHeight(_indexFromCommonName(Name),Height)

# relative to current height

# attribute lookups assuming that Name and Radius have been set

getTrunkRadius = _trunkRadius(_indexFromCommonName(Name),Radius)

# relative to current radius

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

182

# general utility functions

isPlantInLibrary(commonName) = listIndex(_dataCommonName,commonName) >= 0

# utility functions needed for setups which are driven by latin names (i.e.

genus and species)

isPlantInLibrary(genus,species) = listIndex(_dataLatinName,genus+"

"+species) >= 0

isGenusInLibrary(genus) = listIndex(_dataGenus,genus) >= 0

getCommonName(genus,species) =

_commonName(_indexFromLatinName(genus,species)) # NOTE: in case species is

not given or wrong, then it falls back to first plant entry with this genus

(i.e. first entry should be a very common species of this genus)

######################################################

# Library data with accessors (for internal usage only)

#

# number of plants in library

const nPlants = 127

const nModels = 82 # models (= non-proxies) MUST be listed first in

the data (see _getAsset function)

# THE data from Excel sheet (latin name contains both the genus AND species

column)

const _dataCommonName = "Orange Tree;Balsam Fir;Umbrella Acacia;Norway

Maple;Sugar Maple;Conker Tree;Hedgehog Agave;Ruffle Palm;Red

Alder;Shadbush;Japanese Angelica Tree;Strawberry Tree;Paper

Birch;Orchid;Boxwood;California Incense Cedar;Saguaro Cactus;Red

Hickory;American Chestnut;Australian Pine;Mountain Mahogany;Parlour

Palm;Desert Willow;Coconut Palm;Lily of the Valley;Palm Lily;Flowering

Dogwood;Common Hawthorn;Leyland Cypress;Amazon Sword Plant;Blue Gum

Eucalyptus;European Beech;Ficus;Alder Buckthorn;White

Ash;Flannelbush;Generic Stump;Generic Dead Tree;Generic Unknown;Witch

Hazel;Sunflower;California Walnut;Western Juniper;European Larch;Bay

Laurel;Oval-leaved Privet;Sweetgum;Southern Magnolia;Banana Tree;Prickly

Pear Cactus;Palo Verde;Lacy Tree Philodendron;Cabbage Palm Fern;Date

Palm;Bamboo;Norway Spruce;Lodgepole Pine;Scots Pine;American Sycamore;White

Poplar;Apricot;Douglas Fir;Northern Red Oak;White Oak;Mediterranean

Buckthorn;Rhododendron Azaleas;Black Locust;Rose;Mexican Palmetto;White

Willow;Snake Plant;Sassafras;California Redwood;Giant Sequoia;Common

Whitebeam;Spanish Broom;Baldcypress;Basswood;Field Elm;California

Bay;California Palm;Sea Islands Yucca;Tree of Heaven;Persian Silk

Tree;Pawpaw;European Hornbeam;Common Hackberry;Buttonbush;Judas Tree;Lawson

Cypress;Giant Chinquapin;Turkish Hazel;Huckleberry Shrub;Common

Persimmon;American Silverberry;Honey Locust;Loblolly Bay;Common

Holly;Yellow Poplar;Tanoak;Osage Orange;Paper Bark Tree;Chinaberry

Tree;White Mulberry;Southern Wax Myrtle;Black

Tupelo;Hophornbeam;Sourwood;Princess Tree;Avocado;Algarrobo;Desert

Bitterbrush;Smooth Sumac;American Elderberry;Western Soapberry;Octopus

Tree;American Pepper;Canada Buffaloberry;Necklacepod;Athel

Tamarisk;Yew;Northern White Cedar;Japanese Nutmeg;Chinese Tallow

Tree;Japanese Hemlock;Mexican Buckeye;Northern Bilberry;"

const _dataLatinName = "Citrus sinensis;Abies balsamea;Acacia tortilis;Acer

platanoides;Acer saccharum;Aesculus hippocastanum;Agave stricta;Aiphanes

horrida;Alnus rubra;Amelanchier canadensis;Aralia elata;Arbutus

unedo;Betula papyrifera;Bulbophyllum phalaenopsis;Buxus

sempervirens;Calocedrus decurrens;Carnegiea saguaro;Carya ovalis;Castanea

dentata;Casuarina equisetifolia;Cercocarpus montanus;Chamaedorea

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

183

elegans;Chilopsis linearis;Cocos nucifera;Convallaria majalis;Cordyline

petiolaris;Cornus florida;Crataegus monogyna;Cupressus

leylandii;Echinodorus bleheri;Eucalyptus globulus;Fagus sylvatica;Ficus

benjamina;Frangula alnus;Fraxinus americana;Fremontodendron

californicum;Generic stump;Generic deadtree;Generic unknown;Hamamelis

virginiana;Helianthus annuus;Juglans regia;Juniperus occidentalis;Larix

decidua;Laurus nobilis;Ligustrum ovalifolium;Liquidambar

styraciflua;Magnolia grandiflora;Musa acuminata;Opuntia

aciculata;Parkinsonia aculeata;Philodendron selloum;Phlebodium

aureum;Phoenix dactylifera;Phyllostachys aurea;Picea abies;Pinus

contorta;Pinus sylvestris;Platanus occidentalis;Populus tremuloides;Prunus

armeniaca;Pseudotsuga menziesii;Quercus rubra;Quercus alba;Rhamnus

alaternus;Rhododendron tsutsuji;Robinia pseudoacacia;Rosa grandiflora;Sabal

mexicana;Salix alba;Sansevieria trifasciata;Sassafras albidum;Sequoia

sempervirens;Sequoiadendron giganteum;Sorbus aria;Spartium junceum;Taxodium

distichum;Tilia americana;Ulmus minor;Umbellularia californica;Washingtonia

filifera;Yucca gloriosa;Ailanthus altissima;Albizia julibrissin;Asimina

triloba;Carpinus betulus;Celtis occidentalis;Cephalanthus

occidentalis;Cercis siliquastrum;Chamaecyparis lawsoniana;Chrysolepis

chrysophylla;Corylus colurna;Cyrilla racemiflora;Diospyros

virginiana;Elaeagnus commutata;Gleditsia triacanthos;Gordonia

lasianthus;Ilex aquifolium;Liriodendron tulipifera;Lithocarpus

densiflorus;Maclura pomifera;Melaleuca quinquenervia;Melia azedarach;Morus

alba;Myrica cerifera;Nyssa sylvatica;Ostrya virginiana;Oxydendrum

arboreum;Paulownia tomentosa;Persea americana;Prosopis nigra;Purshia

glandulosa;Rhus glabra;Sambucus canadensis;Sapindus saponaria;Schefflera

actinophylla;Schinus molle;Shepherdia canadensis;Sophora tomentosa;Tamarix

aphylla;Taxus baccata;Thuja occidentalis;Torreya nucifera;Triadica

sebifera;Tsuga diversifolia;Ungnadia speciosa;Vaccinium uliginosum;"

const _dataGenus =

"Citrus;Abies;Acacia;Acer;Acer;Aesculus;Agave;Aiphanes;Alnus;Amelanchier;Ar

alia;Arbutus;Betula;Bulbophyllum;Buxus;Calocedrus;Carnegiea;Carya;Castanea;

Casuarina;Cercocarpus;Chamaedorea;Chilopsis;Cocos;Convallaria;Cordyline;Cor

nus;Crataegus;Cupressus;Echinodorus;Eucalyptus;Fagus;Ficus;Frangula;Fraxinu

s;Fremontodendron;Generic;Generic;Generic;Hamamelis;Helianthus;Juglans;Juni

perus;Larix;Laurus;Ligustrum;Liquidambar;Magnolia;Musa;Opuntia;Parkinsonia;

Philodendron;Phlebodium;Phoenix;Phyllostachys;Picea;Pinus;Pinus;Platanus;Po

pulus;Prunus;Pseudotsuga;Quercus;Quercus;Rhamnus;Rhododendron;Robinia;Rosa;

Sabal;Salix;Sansevieria;Sassafras;Sequoia;Sequoiadendron;Sorbus;Spartium;Ta

xodium;Tilia;Ulmus;Umbellularia;Washingtonia;Yucca;Ailanthus;Albizia;Asimin

a;Carpinus;Celtis;Cephalanthus;Cercis;Chamaecyparis;Chrysolepis;Corylus;Cyr

illa;Diospyros;Elaeagnus;Gleditsia;Gordonia;Ilex;Liriodendron;Lithocarpus;M

aclura;Melaleuca;Melia;Morus;Myrica;Nyssa;Ostrya;Oxydendrum;Paulownia;Perse

a;Prosopis;Purshia;Rhus;Sambucus;Sapindus;Schefflera;Schinus;Shepherdia;Sop

hora;Tamarix;Taxus;Thuja;Torreya;Triadica;Tsuga;Ungnadia;Vaccinium;"

const _dataSpecies =

"sinensis;balsamea;tortilis;platanoides;saccharum;hippocastanum;stricta;hor

rida;rubra;canadensis;elata;unedo;papyrifera;phalaenopsis;sempervirens;decu

rrens;saguaro;ovalis;dentata;equisetifolia;montanus;elegans;linearis;nucife

ra;majalis;petiolaris;florida;monogyna;leylandii;bleheri;globulus;sylvatica

;benjamina;alnus;americana;californicum;stump;deadtree;unknown;virginiana;a

nnuus;regia;occidentalis;decidua;nobilis;ovalifolium;styraciflua;grandiflor

a;acuminata;aciculata;aculeata;selloum;aureum;dactylifera;aurea;abies;conto

rta;sylvestris;occidentalis;tremuloides;armeniaca;menziesii;rubra;alba;alat

ernus;tsutsuji;pseudoacacia;grandiflora;mexicana;alba;trifasciata;albidum;s

empervirens;giganteum;aria;junceum;distichum;americana;minor;californica;fi

lifera;gloriosa;altissima;julibrissin;triloba;betulus;occidentalis;occident

alis;siliquastrum;lawsoniana;chrysophylla;colurna;racemiflora;virginiana;co

mmutata;triacanthos;lasianthus;aquifolium;tulipifera;densiflorus;pomifera;q

uinquenervia;azedarach;alba;cerifera;sylvatica;virginiana;arboreum;tomentos

a;americana;nigra;glandulosa;glabra;canadensis;saponaria;actinophylla;molle

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

184

;canadensis;tomentosa;aphylla;baccata;occidentalis;nucifera;sebifera;divers

ifolia;speciosa;uliginosum;"

const _dataHeightMin =

"5;10;5;20;25;25;1;3;15;3;3;5;12;0.5;0.8;20;3;20;20;10;3;1;2;20;0.15;2;5;5;

3;0.5;20;10;2;6;10;2;0.4;5;5;2;1.5;15;20;20;2;2;10;15;3;0.5;2;0.5;0.5;20;5;

12;30;25;20;12;4;45;18;14;1;0.5;10;0.5;12;12;0.5;9;50;50;15;2;25;25;20;20;1

4;2;10;5;8;15;7;2;6;20;20;15;3;2;1;20;10;10;18;20;3;10;4;10;3;20;14;10;10;1

0;10;1;1;2;2;3;10;1;1;12;10;10;10;8;15;2;0.5;"

const _dataHeightMax =

"13;20;15;30;35;35;2;10;20;5;5;10;18;1.5;1.2;30;9;30;30;20;4;3;6;30;0.3;4;1

0;15;7;1.5;30;15;4;14;16;4;1;35;35;4;3.5;25;25;40;6;4;16;25;6;1;6;1.5;1.5;2

5;9;20;50;45;40;20;10;75;35;24;5;2;16;1.5;18;18;1;18;80;80;25;4;40;35;26;30

;22;3;15;12;12;25;13;4;10;40;30;25;5;4;3;30;20;10;32;25;7;20;12;14;5;25;18;

20;25;20;20;3;4;4;6;15;15;4;3;18;20;20;20;12;25;4;1.5;"

const _dataHeightAvg =

"9;15;10;25;30;30;1.5;6.5;17.5;4;4;7.5;15;1;1;25;6;25;25;15;3.5;2;4;25;0.25

;3;7.5;10;5;1;25;12.5;3;10;13;3;0.6;20;20;3;2.5;20;22.5;30;4;3;13;20;4.5;0.

75;4;1;1;22.5;7;16;40;32;30;16;7;60;24;19;3;1.25;13;1;15;15;0.75;13.5;65;65

;20;3;30;30;23;25;18;2.5;12.5;8.5;10;20;10;3;8;30;25;20;4;3;2;25;15;15;24;2

2.5;5;15;8;12;4;22;16;15;17;15;15;2;2;3;4;10;12;2.5;2;15;15;15;15;10;20;3;1

;"

const _dataRadiusAvg =

"2.5;3.35;4.35;6.3;10.21;9;1.06;2.16;2.97;0.92;1.84;2.54;3.75;0.47;0.44;4.3

5;0.82;9.02;4.38;3.28;1.38;0.83;2.11;5.12;0.07;0.7;2.4;3.07;0.64;0.56;7.1;4

.5;0.9;3.63;2.8;0.66;0.5;5;5;1.72;0.56;9.06;11.03;4.57;0.8;0.5;2.85;7.64;1.

5;0.49;2.16;0.7;0.85;6.56;1.66;3.02;6.59;5.96;6.06;2.9;2.02;12.28;10.35;8.5

6;1.07;0.37;3.49;0.57;3.59;4.17;0.13;2.94;9.42;13.93;6;0.99;8.56;6.85;7.81;

9.38;3.24;0.68;2.69;2.72;3;4.36;2.18;0.66;2.88;6.57;11.26;4.56;1.58;0.87;0.

4;8.51;4.6;2.72;9.17;8.11;1.44;4.26;2.15;4.33;2.29;4.74;6.11;4.03;7.65;4.33

;6.47;1.14;0.66;0.92;2.16;2.68;3.98;0.83;1.41;6.47;1.91;1.91;2.84;3;3.78;0.

99;0.22;"

const _dataCrownShape =

"S4;S8;S5;S4;S4;S5;S6;S6;S7;S6;S5;S4;S4;S2;S6;S4;S2;S4;S5;S6;S6;S5;S5;S4;S5

;S5;S5;S5;S3;S5;S4;S4;S4;S5;S5;S7;S1;S4;S4;S4;S6;S4;S4;S4;S5;S7;S5;S4;S4;S4

;S5;S6;S5;S4;S6;S5;S4;S6;S4;S5;S4;S6;S5;S4;S4;S6;S4;S4;S4;S6;S6;S5;S5;S4;S4

;S5;S6;S5;S4;S4;S4;S4;S5;S5;S4;S5;S5;S7;S4;S6;S4;S5;S6;S4;S7;S4;S5;S5;S4;S4

;S4;S4;S4;S4;S4;S5;S4;S4;S4;S4;S5;S4;S5;S5;S5;S4;S6;S5;S6;S5;S3;S3;S5;S4;S5

;S5;S7;"

const _dataTrunkRadiusAvg =

"0.13;0.35;0.35;0.46;0.85;0.8;0.04;0.1;0.34;0.12;0.11;0.21;0.23;0.05;0.05;0

.31;0.18;0.68;0.56;0.32;0.12;0.04;0.13;0.2;0.05;0.03;0.23;0.21;0.09;0.07;0.

64;0.32;0.06;0.1;0.17;0.1;0.5;0.5;0.5;0.06;0.04;0.4;1.03;0.5;0.06;0.11;0.2;

0.48;0.09;0.04;0.09;0.1;0.09;0.54;0.08;0.23;0.58;0.39;0.68;0.23;0.11;0.88;0

.82;0.46;0.11;0.03;0.18;0.05;0.21;0.23;0.04;0.22;1.3;2.39;0.29;0.1;0.46;0.4

3;1.11;1.1;0.25;0.04;0.17;0.26;0.2;0.33;0.16;0.1;0.2;0.64;0.61;0.29;0.13;0.

05;0.07;0.7;0.32;0.22;0.58;0.57;0.08;0.38;0.11;0.32;0.08;0.29;0.38;0.2;0.41

;0.23;0.51;0.09;0.07;0.06;0.09;0.13;0.18;0.08;0.2;0.51;0.26;0.26;0.21;0.15;

0.28;0.1;0.03;"

const _dataTrunkHeightAvg =

"2.1;4;5.2;4.25;8.1;4.8;0;3.64;6.3;0;1;2.17;3.3;0;0;6;1.32;4;7.25;2.25;0;0;

1.52;15.75;0;0.81;2.17;2.1;0.15;0.26;7;3;0.63;1.8;1.43;0;0.6;6;6;0.45;0;4.8

;7.87;4.5;0;0;2.34;3.2;2.48;0.04;1.36;0;0;12.6;0;2.4;8.6;7.36;6.6;2.08;1.75

;7.2;9.84;3.99;0.24;0;4.03;0;9.15;4.9;0;2.97;29.9;9.1;6.8;0;16.5;6.6;7.59;6

.75;11.7;0.68;1.38;2.46;2.1;4.4;2.2;0;1.92;4.5;5.25;4.4;0;0.75;0;6.75;3.15;

1.95;3.84;5.4;1.25;4.2;2.48;1.92;0.6;2.42;2.56;4.65;3.57;3.75;6.15;0;0;0.63

;1.36;3.1;3.36;0;0;6.15;0.45;0.45;2.25;3.4;3;0;0;"

const _dataRegions =

"NA,EU,AS,SA;NA;AF,AS;EU,AS;NA,EU;EU;NA;SA,NA;NA;NA;AS;AS;NA;AS;NA,EU;NA;NA

;NA,EU;NA,EU,AS;AU;NA;NA;NA;NA,AS;NA,AS,EU;AU;NA,EU;EU,AS,AF;NA,EU;SA,NA;AU

,AS,NA;EU;AU;AU,EU;EU,NA,AS;NA,EU;NA,AS,EU,AF,SA,AU;NA,AS,EU,AF,SA,AU;NA,AS

,EU,AF,SA,AU;NA;NA,SA,EU;EU,NA;NA;EU,NA,AS;EU,NA;EU;NA;NA;AS,SA;NA;NA,AF;NA

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

185

,AF,AU;NA,SA;AS,NA,SA;AS;EU;NA;EU,AS,NA;NA;NA;NA,EU,AS;NA;NA;NA;EU;NA,EU,AS

;NA,EU;NA,EU;NA;NA,EU,AS;AS,SA;NA;NA;NA;EU;EU,AS,AF;NA;NA;EU,NA;NA;NA;NA;AS

,NA;AS;NA;EU;NA;NA;EU,AS;NA;NA;AS;NA,SA;NA,EU;NA;AS,NA;NA,AS;EU,AF,AS;NA,AS

;NA;NA,AS;AU;AU;NA;NA;NA;EU,NA;NA;AS;NA;SA;NA;NA;NA;NA;AU;SA;NA;AS,NA;AF,AU

,AS;EU,AF,AS;NA;AS;AS,NA;AS,NA;NA;NA;"

const _dataZoneMin =

"9;3;9;3;3;4;10;10;7;4;4;7;2;11;5;5;8;4;4;9;4;10;7;10;2;10;5;4;6;10;9;4;10;

3;3;9;0;0;0;3;4;5;5;3;8;4;5;6;9;8;8;8;9;8;6;2;1;3;4;2;5;3;3;3;8;3;4;3;8;2;9

;4;7;6;6;8;4;3;3;9;9;6;5;6;5;5;3;4;6;5;6;4;5;4;2;4;8;5;4;7;4;9;7;4;7;4;3;5;

6;9;9;3;3;4;7;9;8;2;9;7;5;2;6;8;6;7;2;"

const _dataZoneMax =

"11;5;11;7;8;7;11;11;8;7;8;9;7;11;8;8;11;8;8;11;4;11;11;11;7;11;9;8;10;11;1

1;7;11;7;9;11;12;12;12;8;9;9;8;6;10;7;9;10;11;10;11;11;11;11;11;7;7;7;9;5;7

;6;8;9;9;7;9;10;11;8;11;8;10;8;8;9;10;9;9;11;11;11;8;9;8;7;9;10;9;7;9;7;10;

9;6;8;9;9;9;11;9;11;9;9;10;9;9;8;9;10;9;9;9;9;10;11;11;6;11;10;8;8;10;10;9;

9;6;"

const _dataProxy =

"X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;

X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X

;X;X;X;X;X;X;X;White Ash;Flowering

Dogwood;Ficus;Sassafras;Sassafras;Flannelbush;European Beech;Australian

Pine;White Oak;Basswood;Mountain Mahogany;Apricot;Flannelbush;Sugar

Maple;Common Hawthorn;White Poplar;Southern Magnolia;European

Beech;Apricot;Blue Gum Eucalyptus;Black Locust;Red Hickory;Witch

Hazel;White Ash;Southern Magnolia;Black Locust;White Oak;Apricot;Northern

Red Oak;Rose;Spanish Broom;Common Hawthorn;Palo Verde;Black Locust;White

Willow;Spanish Broom;Lacy Tree Philodendron;Northern Red Oak;Leyland

Cypress;Leyland Cypress;Norway Spruce;Common Whitebeam;Norway

Spruce;Spanish Broom;Flannelbush;"

# Get index from common name, latin name, or genus.

_indexFromName(name) = _indexCheckCommonName(listIndex(_dataCommonName,

name), name)

_indexCheckCommonName(idx, name) =

case idx < 0: _indexCheckLatinName(listIndex(_dataLatinName, name),

name) # fallback if plant has not been found

else: idx

_indexCheckLatinName(idx, name) =

case idx < 0:

_indexCheckGenus(listIndex(_dataGenus,_genusFromLatinName(name))) #

fallback if plant has not been found

else: idx

_indexCheckGenus(idx) =

case idx < 0: _fallbackIdx # fallback if plant has not been found

else: idx

# getting index for accessors either via common name only (no latin name

fallback)

# kept here in case we still need it, but might be deprecated due to

_indexFromName.

_indexFromCommonName(commonName) = _indexFromName(commonName)

_indexCheck(idx) =

case idx < 0: _fallbackIdx

else: idx # fallback if plant has not been found

_genusFromLatinName(latinName) = getPrefix(latinName, " ")

# getting index via latin name: in case plant cannot be found, we try to

search a plant of at least the given genus as first fallback

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

186

_indexFromLatinName(genus,species) =

_indexCheckLatin(listIndex(_dataLatinName,genus+" "+species),genus)

_indexCheckLatin(idx,genus) = case idx < 0:

_indexCheck(listIndex(_dataGenus,genus)) else: idx

# this plantNbr is displayed if the user-selected plant does not exist in

library

const _fallbackIdx = listIndex(_dataCommonName,FallbackPlant)

# accessors

_commonName(idx) = listItem(_dataCommonName,idx)

_latinName(idx) = listItem(_dataLatinName,idx)

_genus(idx) = listItem(_dataGenus,idx)

_species(idx) = listItem(_dataSpecies,idx)

_heightMax(idx) = float(listItem(_dataHeightMax,idx))

_heightMin(idx) = float(listItem(_dataHeightMin,idx))

_heightAvg(idx) = case _valid(idx):

float(listItem(_dataHeightAvg,idx)) else: 1 # to avoid divisions by zero

_radiusAvg(idx) = case _valid(idx):

float(listItem(_dataRadiusAvg,idx)) else: 1 # to avoid divisions by zero

_trunkHeightAvg(idx)= float(listItem(_dataTrunkHeightAvg,idx))

_trunkRadiusAvg(idx)= float(listItem(_dataTrunkRadiusAvg,idx))

_crownShape(idx) = listItem(_dataCrownShape,idx)

_regions(idx) = listItem(_dataRegions,idx)

_zoneMin(idx) = float(listItem(_dataZoneMin,idx))

_zoneMax(idx) = float(listItem(_dataZoneMax,idx))

_proxy(idx) = listItem(_dataProxy,idx)

# special accessors: randomHeight

_randomHeight(idx) = case p(RandomHeightYoungPercentage):

_randomHeightYoung(_heightMin(idx))

else

: _randomHeightMature(_heightMin(idx),_heightMax(idx))

_randomHeightYoung(hMin) = rand(hMin * 0.7,hMin)

_randomHeightMature(hMin,hMax) = rand(hMin,hMax)

# special accessors: getting plant attributes for given height or radius

_radius(idx,height) = _radiusAvg(idx) *

height/_heightAvg(idx)

_randomRadius(idx,height) = _radius(idx,height) * rand(1-

RandomRadiusDeviation,1+RandomRadiusDeviation)

_trunkHeight(idx,height) = _trunkHeightAvg(idx) *

height/_heightAvg(idx)

_trunkRadius(idx,radius) = _trunkRadiusAvg(idx) *

radius/_trunkRadiusAvg(idx)

# helper

_valid(idx) = 0 <= idx && idx < nPlants

_wikipediaURL(idx) = "http://en.wikipedia.org/wiki/" +

_genus(idx) + "_" + _species(idx)

######################################################

# Internal functions for rules only

#

# for higher performance (i.e. plant index for getting radius/height/radius

can be stored to avoid multiple index lookups via name)

@Hidden

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

187

attr _plantNbr = 0

@Hidden

attr _plantName = ""

@Hidden

attr _plantHeight = 0

@Hidden

attr _plantRadius = 0

# validate name (assummes that _plantNbr has been set)

_validate(name) = case _plantNbr==_fallbackIdx: FallbackPlant else: name

# file handling (assumes that Name and _plantNbr is correctly set)

_getAsset =

case _plantNbr < nModels: _getFilepath(replace(_plantName," ","_"))

else :

_getFilepath(replace(_proxy(_plantNbr)," ","_"))

_getFilepath(commonNameUnderscores) =

AssetFolder + "/" + commonNameUnderscores + "/" +

commonNameUnderscores + "_" + Representation + "_0.obj"

# asset scale handling (assumes that Height, Radius, _plantNbr have been

set and the asset has been inserted)

_getScaleY = _plantHeight/scope.sy

_getScaleXZ =

case _plantRadius > 0 : _plantRadius/_radius(_plantNbr,scope.sy)

# the ratio of

the user-set ratio versus the ratio of the inserted asset (since the ratio

does not correspond to the bounding box, this has to be looked up (i.e.

getting the value of the average-sized tree))

else : _plantHeight/scope.sy * rand(1-

RandomRadiusDeviation,1+RandomRadiusDeviation) # in case the Radius

is zero, we assume the (most typical) random case. This is for performance

reasons only --> see also alternative plant loader rule which uses this as

marker (to save above lookups which are not needed if the user-set Radius

has not been set)

# rule helpers

_roundTransparency = rint(20*Transparency) / 20 # round to

0.05 steps (to avoid the creation of too many materials)

_randomRotation = case RandomRotation: rand(0,360) else: 0

########################################################################

########################################################################

###

### RULES

###

###

######################################################

# Plant Loader

#

@StartRule # assumes that all main attributes have been set outside

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

188

Generate -->

case Height > 0:

set(_plantNbr,_indexFromName(Name))

set(_plantName,_validate(_commonName(_plantNbr)))

set(_plantHeight,Height)

set(_plantRadius,Radius)

s(0,0,0)

center(xyz)

alignScopeToAxes(y)

TrunkOrigin

else:

Generate(Name)

TrunkOrigin -->

case Representation == "Analytical":

PlantAnalytical

case Representation == "Fan":

PlantFan

else:

PlantModel

######################################################

# Alternative Plant Loader (doesn't use the main attributes!)

#

# In the most typical design use case where a random-sized plant needs to

# be set, we recommend to use this rule in the importing rule file.

#

# On the one hand it is more practical since the attributes do not need to

be

# set before calling it as in the Plant rule above. But the main reason why

# we are provding this rule is that it is faster (because less library

lookups

# are required here).

Generate(name) -->

set(_plantNbr,_indexFromName(name))

set(_plantName,_validate(name))

set(_plantHeight,_randomHeight(_plantNbr))

set(_plantRadius,0) # marks that the random radius can be used

s(0,0,0)

center(xyz)

alignScopeToAxes(y)

TrunkOrigin

######################################################

# Realistic Model

#

PlantModel -->

PlantModel(_getAsset)

PlantModel(asset) --> # needs special

treatment because the bbox of the asset is not centered in orgin:

i(asset)

PlantModel(_getScaleY,_getScaleXZ,

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

189

assetInfo(asset,tx)/scope.sx, # relative origin

offset in x-dir (trunk is at origin i.e. this value is needed for scaling

around origin)

assetInfo(asset,tz)/scope.sz) # relative origin

offset in z-dir (trunk is at origin i.e. this value is needed for scaling

around origin)

PlantModel(scaleY,scaleXZ,relOffsetX,relOffsetZ) -->

t('-relOffsetX,0,'-relOffsetZ)

r(0,_randomRotation,0)

s('scaleXZ,'scaleY,'scaleXZ) # scale standard model

to meet the user-given Height and Radius

t('relOffsetX,0,'relOffsetZ)

PlantVisualization

######################################################

# Analytical Model

#

PlantAnalytical -->

i(_getAsset)

PlantAnalytical(_getScaleY,_getScaleXZ)

PlantAnalytical(scaleY,scaleXZ) -->

s('scaleXZ,'scaleY,'scaleXZ) center(xz)

PlantVisualization

######################################################

# Fan

#

PlantFan -->

i(_getAsset)

PlantFan(_getScaleY,_getScaleXZ)

PlantFan(scaleY,scaleXZ) -->

s('scaleXZ,'scaleY,'scaleXZ) center(xz)

r(scopeCenter,0,_randomRotation,0)

PlantVisualization

######################################################

# Post operations

#

PlantVisualization -->

case OverrideColor != "" && _roundTransparency > 0.01: #

leaf cards will not work in webgl anymore (CE2013)

set(material.opacity,1-_roundTransparency)

set(material.colormap,"")

color( OverrideColor )

PlantReporting

case OverrideColor != "":

# leaf cards will not work in webgl anymore (CE2013)

set(material.colormap,"")

color( OverrideColor )

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

190

PlantReporting

case _roundTransparency > 0.01:

# leaf cards will not work in webgl anymore (CE2013)

set(material.opacity,1-_roundTransparency)

PlantReporting

case RandomBrightness:

color(40%: "#ffffff" 33%: "#dddddd" else: "#bbbbbb") #

variation in brightness for better looks (but tripples the instance

count...)

PlantReporting

else:

PlantReporting

PlantReporting -->

case Reporting == "Metadata":

PlantFinal

report( "Common Name", _plantName

)

report( "Genus", _genus(_plantNbr)

)

report( "Species",

_species(_plantNbr) )

report( "Total Height", _plantHeight

)

report( "Trunk Height",

_trunkHeight(_plantNbr,_plantHeight) )

report( "Trunk Radius",

_trunkRadius(_plantNbr,_plantRadius) )

report( "Crown Radius", _plantRadius

)

report( "Crown Shape", _crownShape(_plantNbr)

)

report( "Wikipedia URL for Species",_wikipediaURL(_plantNbr)

)

report( "Minimun Height of Species",_heightMin(_plantNbr)

)

report( "Maximum Height of Species",_heightMax(_plantNbr)

)

report( "Hardiness Zone Min", _zoneMin(_plantNbr)

)

report( "Hardiness Zone Max", _zoneMax(_plantNbr)

)

report( "Contintents of Species", _regions(_plantNbr)

)

NIL

case Reporting == "Instance Information":

PlantFinal

report("asset", "Plants/" +

_plantName )

report("scale", _plantHeight

)

# report position in world coords

s(0.001,'1,0.001) center(xz) # This line was causing trees to

become vertical line.

report("xpos",

convert(x,scope,world,pos,0,0,0) )

report("ypos",

convert(y,scope,world,pos,0,0,0) )

report("zpos",

convert(z,scope,world,pos,0,0,0) )

# report rotation in world coords

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

191

report("xrot", -

(convert(x,scope,world,orient,0,0,0)) )

report("yrot", -

(convert(y,scope,world,orient,0,0,0)) )

report("zrot",

convert(z,scope,world,orient,0,0,0) )

NIL

else:

PlantFinal

PlantFinal -->

PlantFinal.

###########################################

# DEV NOTES:

#

# Move Random Brightness and Height to the distributor rules - Loader

standalone does not use them.

# Consider replacing all instances of _indexFromCommonName with

_indexFromName; needs more thorough testing first.

# Reporting of strings is not supported yet, but we are reporting strings

here in anticipation of that.

6.4. Código empleado para generar el edificio nuevo

/**

* File: edificio_nuevo.cga

* Created: 4 May 2008 23:27:29 GMT

* Author: Antonio

*/

version "2010.3"

/* Attributes *************************************/

attr groundfloor_height = 4

attr floor_height = 3.5

attr tile_width = 3

attr Height = 11

attr wallColor = "#fefefe"

attr LOD = 1

/* Assets *************************************/

// geometries

window_asset = "facades/window.obj"

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

192

// textures

frontdoor_tex = "facades/textures/shopdoor.tif"

wall_tex = "facades/textures/brickwall.jpg"

dirt_tex = "facades/textures/dirtmap.15.tif"

roof_tex = "roofs/roof.tif"

# this function will get one of the 9 window textures in the assets folder

randomWindowTexture = fileRandom("*facades/textures/window.*.tif")

/* Initial Shape starting rule *************/

# scale the lit to leave a small border and extrude the lot to building

height

Lot -->

extrude(Height) Building

# inner lots are dropped

LotInner --> NIL

# split the building geometry into its facade components

Building -->

comp(f) { front : Frontfacade | side : Sidefacade | top: Roof}

# the front facade is subdivided into one front groundfloor

# and upper floors

Frontfacade -->

setupProjection(0, scope.xy, 1.5, 1, 1) # setup 1.5m x 1m texture

tiles along scopes xy plane (and distortion in z)

setupProjection(2, scope.xy, scope.sx, scope.sy)

split(y){ groundfloor_height : Groundfloor

| {~floor_height : Floor}* }

# a side facade is subdivided into one bottom floor

# and upper floors.

Sidefacade -->

setupProjection(0, scope.xy, 1.5, 1, 1) # setup 1.5m x 1m texture

tiles along scopes xy plane (and distortion in z)

setupProjection(2, scope.xy, scope.sx, scope.sy)

split(y){ groundfloor_height : Floor

| {~floor_height : Floor}* }

# a roof texture is applied to the roof face

Roof -->

setupProjection(0, scope.xy, scope.sx, scope.sy)

texture(roof_tex)

projectUV(0)

# each floor is horizontally split into two narrow corner areas on

# each side of the floor, and into a set of window tiles in between

Floor -->

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

193

split(x){ 1 : Wall

| { ~tile_width : Tile }*

| 1 : Wall }

# similarily, the front groundfloor is horizontally split into

# two narrow corner areas on each side of the floor,

# a special entrance tile on the right

# and into a set of window tiles in between

Groundfloor -->

split(x){ 1 : Wall

| { ~tile_width : Tile }*

| ~tile_width : EntranceTile

| 1 : Wall }

# a tile consists of a centered window element and

# wall elements above, below, left and right

Tile -->

split(x){ ~1 : Wall

| 2 : split(y){ 1: Wall | 1.5: Window | ~1: Wall }

| ~1 : Wall }

# similarily, the EntranceTile contains a centered Door element,

# but with no wall on spacing below

EntranceTile -->

split(x){ ~1 : SolidWall

| 2 : split(y){ 2.5: Door | ~2: SolidWall }

| ~1 : SolidWall }

# firstly, the depth and the depth position of the future window is set

# secondly, one of nine window textures is randomly selected

# finally, the window geometry asset is inserted

Window -->

case LOD > 0 :

s('1,'1,0.4)

t(0,0,-0.25)

texture(randomWindowTexture)

i(window_asset)

else :

setupProjection(0,scope.xy,scope.sx,scope.sy)

texture(randomWindowTexture)

projectUV(0)

# same for the door asset. Scaling, positioning, texture selection

# and geometry insert

# TODO: fix door uv bug (problem with uv handling on split?)

Door -->

case LOD > 0 :

s('1,'1,0.1)

t(0,0,-0.5)

texture(frontdoor_tex)

i("builtin:cube")

else :

setupProjection(0,scope.xy,scope.sx,scope.sy)

texture(frontdoor_tex)

projectUV(0)

# for the wall asset, setting the texture scale params u and v

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

194

# guarantees a texture mapping that nicely fits over the whole facade

Wall -->

color(wallColor)

texture(wall_tex)

set(material.dirtmap, dirt_tex)

projectUV(0) projectUV(2)

SolidWall -->

case LOD > 0 :

color(wallColor)

s('1,'1,0.4)

t(0,0,-0.4)

texture(wall_tex)

set(material.dirtmap, dirt_tex)

i("builtin:cube:notex")

projectUV(0) projectUV(2)

else :

Wall

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

195

7. Mapas

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

196

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

197

Antonio de la Torre Morales Técnicas Geomáticas y Modelado Procedural para la Generación de Modelos Urbanos en 3D

Centro de Estudios de Postgrado Master Universitario en Tecnologías Geoespaciales aplicadas a la Gestión Inteligente del Territorio

198