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
Top Related