Azulejos irregulares en la superficie de planetas generados por procedimientos

Aquí consideraremos un método para dividir la superficie esférica de un planeta generado por procedimientos con mosaicos irregulares y, como consecuencia, dividir el océano y los continentes en secciones separadas (sectores). Suponemos que la estructura de las áreas terrestres ya se ha establecido en la superficie del planeta utilizando algunos SIG y es posible exportar datos vectoriales a archivos de forma ESRI o directamente a una base de datos PostgreSQL con la extensión PostGIS . El proceso de creación de sectores se lleva a cabo utilizando PostGIS.

Vea el enlace al script con código SQL al final de la publicación, aquí la explicación será más fácil. La explicación proporciona las funciones básicas del script y también supone la disponibilidad de datos para continentes y ríos de planetas generados por procedimientos tomados de forgedmaps.com .

La elección de mosaicos irregulares nos permite subdividir con precisión la superficie del planeta.
en sectores, generalmente sin mezclar los territorios del océano y la tierra en ninguna parte. Lagos y mares interiores
Lo consideramos parte de la tierra. También veremos cómo se pueden usar los ríos como límites naturales de los sectores. Los sectores mismos se construirán sobre la base de una división básica de la esfera por polígonos.

Cuando se trata de dividir una región plana, generalmente recurren al diagrama de Voronoi para obtener fichas irregulares. Usando también el algoritmo de Lloyd , podemos llegar a una forma visualmente atractiva de polígonos convexos que no son muy diferentes en tamaño (teselado centroidal de Voronoi). La esencia del algoritmo de Lloyd's es repetir la construcción del diagrama de Voronoi, en cada iteración posterior, tomando los centros de los polígonos obtenidos en la iteración anterior como puntos generadores.

Impondremos ciertos requisitos en la división básica por polígonos de una esfera:
la convexidad de los polígonos esféricos y sus desviaciones no muy grandes de un tamaño promedio dado.

El sector de nombre se usa en lugar de una ficha debido al hecho de que la ficha suele tener un significado elemental, por ejemplo, como parte de la unidad de las cartas de fichas de los juegos estratégicos, o como parte de la unidad de una determinada superficie. Dentro del sector hay una estructura interna: el relieve y varios objetos geográficos en el mismo. Los sectores, a su vez, también pueden servir como mosaicos elementales: construir un gráfico de posibles transiciones entre sectores sirve para este propósito.

La división básica de la esfera y los segmentos de los océanos.


PostGIS tiene una función ST_VoronoiPolygons , que construye un diagrama de Voronoi en un área cuadrada. Veamos cómo podemos usarlo para nuestros propósitos.

¿Qué sucede si intentas usar un enfoque directo? Una proyección rectangular del planeta se puede convertir en un cuadrado por coordenadas, construir polígonos allí y realizar la transformación inversa de coordenadas. Pero, los rectángulos construidos de esta manera se estirarán en una dirección, lo que sería indeseable. Y, si intenta aplicar el algoritmo de Lloyd, entonces los rectángulos cercanos a los polos de la esfera serán significativamente más pequeños en área (en la esfera) que cerca del ecuador.

Tratemos de adaptar este método con la eliminación de desventajas. Los puntos de partida aleatorios del diagrama de Voronoi se eligen para que se distribuyan uniformemente en la esfera. En la proyección de Mercator, esto significa que en los polos deberían aparecer con menos frecuencia con una probabilidad proporcional al coseno de la latitud. Estamos construyendo el diagrama de Voronoi en el polígono del "mundo": esta es la proyección rectangular completa del planeta o solo una parte de él. La función ST_VoronoiPolygons completa el rectángulo en un cuadrado, solo necesitamos recortar el diagrama resultante de acuerdo con el polígono "mundial".

Observamos la imagen de los polígonos de Voronoi obtenidos de forma adaptada. Aquí hay una parte del mapa del planeta de prueba desde el ecuador en el borde superior a 73 grados de latitud sur en el borde inferior. (Aquí el área de tierra ya ha sido cortada de vertederos).

imagen

Como se puede ver en la proyección de Mercator, los polígonos son generalmente más grandes cuando se acercan a los polos, pero se distribuirán aproximadamente por igual sobre la esfera en términos de tamaño del área. Esto es lo que necesitamos. Pero, también se ve que los polígonos tienen una gran extensión de áreas y la imagen general es bastante desagradable.

Intentemos aplicar varias iteraciones del algoritmo de Lloyd. Como nuevos puntos
Para las iteraciones posteriores del diagrama de Voronoi, elegiremos los centros de los ya recortados.
Polígono "Mundo" polígonos Voronoi. Y para evitar demasiada reducción en el área de polígonos cerca de los polos, solo hacemos un pequeño número de iteraciones (más o menos 3).

Para obtener segmentos oceánicos, el área de tierra ocupada se excluye de los vertederos obtenidos. Como resultado, se pueden formar pequeños polígonos, que es deseable unir a los vecinos. Además, los polígonos pequeños pueden estar cerca del borde del polígono "mundial". Conectamos los polígonos de tal manera que seleccionemos al vecino "más cercano" y no estropeemos el panorama general.

Después de aplicar dicho algoritmo modificado, obtenemos la siguiente imagen, que ya puede ser aceptable. Los segmentos rojos en la figura indican la fusión deseada de los polígonos.

imagen

La selección de polígonos para fusionar se puede hacer de diferentes maneras. En el script mencionado, se implementan 2 métodos: en el borde más largo y en el centro más cercano. La siguiente figura muestra el resultado de la fusión de la segunda manera.

imagen

En general, hemos logrado lo que se puede desear de los sectores oceánicos. Su área es aproximadamente la misma (en la esfera), y son convexas o con pequeñas desviaciones de la convexidad.

La función principal para generar sectores oceánicos:

 map.makeOceanSectors( world Geometry, avg_vp_areaKM Double Precision, merging_ratio Double Precision, merging_method Int ) RETURNS Void 

world : un campo de entrenamiento “mundial” que sirve como las fronteras del mundo.
avg_vp_areaKM : el área promedio (km 2 ) de polígonos a partir de los cuales se forman los sectores oceánicos.
merging_ratio : parte de avg_vp_areaKM , de modo que si el área del sector es menor que ella, se unirá al vecino.
merging_method : método de fusión ('1' o '2').

Un ejemplo Estamos construyendo sectores en un vertedero "mundial" dado con un área promedio de vertederos base de 1,000,000 km 2 . Los sectores cuya área es menor que la mitad de este tamaño se unirán a otros. Se utiliza el segundo método de fusión, en el centro más cercano.

 SELECT * FROM map.makeOceanSectors( ST_GeomFromText( 'POLYGON((-75 -85, 75 -85, 75 85, -75 85, -75 -85))', 4326 ), 1000000, 0.5, 2 ); 

Segmentos de los continentes.


En el continente, puede ingresar a una división más interesante, basada, por un lado, en la totalidad de pequeños rangos de base y, por otro, en objetos naturales como ríos y cuencas hidrográficas. La estructura así obtenida es muy similar al mapa de estados y provincias en ellos. Es decir, este es el proceso de generar procesalmente el mapa político del mundo .

A diferencia de los segmentos oceánicos, el abultamiento se vuelve completamente opcional.

Todavía no hay cuencas en forgedmaps.com, pero ya hay ríos. El uso de ríos en un script requiere su representación en MultiLineString . Tienen esta idea en el archivo shape de Riversz . Al importar a la base de datos, puede deshacerse inmediatamente del exceso de coordenadas z en este proceso. Otros datos requeridos, a saber, los límites de las áreas de tierra, se encuentran en el archivo de forma de tierras . Cada área de tierra tiene un identificador de aid (Id de área) y puede consistir en el continente y las islas más cercanas, o solo pequeñas islas ubicadas cerca.

Para nuestro ejemplo, elegimos el tamaño medio del sector de 40,000 km 2 y el tamaño promedio del polígono base de 5,000 km 2 . Este es un tamaño bastante grande, elegido solo para ilustración. Los tamaños más pequeños también son aceptables (hasta unos pocos m 2 ), pero realice un seguimiento del tiempo de cálculo y use la configuración de base de datos adecuada.

En esta imagen, un ejemplo de cómo se ven los polígonos básicos dentro del área terrestre.

imagen

El siguiente paso es combinar los polígonos base en sectores. Para hacer esto, seleccione aleatoriamente de los polígonos base tantos sectores como queramos hacer y gradualmente agregue polígonos vecinos a los sectores acumulados.

imagen

Ahora es el momento de tener en cuenta el río. Los usamos para dividir sectores en
partes separadas por la función ST_Split . Tal división se puede realizar dependiendo de algunas condiciones: el flujo final del río o el área de la parte separada.

Ahora podemos ver cómo algunas fronteras van a lo largo de los ríos.

imagen

Conectamos pequeñas partes de sectores a grandes sectores. Pero debemos intentar
No adjunte piezas a los mismos sectores de los que se cortaron.

imagen

Con grandes extensiones de tierra que manejamos, pero aún pequeñas islas. Hacemos que aquellos que tienen un área cercana al área promedio del sector sean sectores separados a la vez. Pero con aquellos cuya área es mucho más pequeña que el sector promedio, estamos haciendo dos cosas.

1. Si tales islas están ubicadas relativamente lejos de los sectores existentes, entonces las hacemos sectores separados. La “agricultura” aquí depende del área promedio dada del sector: cuanto más pequeña sea esta área, más probable es que la isla se convierta en un sector separado.

2. Si la isla está cerca de otros sectores ya creados, entonces se combina con uno de ellos. Es decir, con el que tiene el área más grande en un cierto polígono obtenido usando ST_Buffer de esta isla.

imagen

Aquí cuatro islas cayeron en dos sectores diferentes. Si aumenta el área del sector promedio establecido, tarde o temprano todas las islas caerán en un solo sector.

La función principal para generar sectores en tierra:

 map.makeLandSectors( aid BigInt, avg_vp_areaKM Double Precision, avg_sector_areaKM Double Precision, max_sector_cut_area_ratio Float, pref_min_island_area_ratio Float, min_streamflow Int ) RETURNS Void 

aid - identificador de la parcela de tierra.
avg_vp_areaKM : el área promedio (km 2 ) de los polígonos base.
avg_sector_areaKM : área promedio (km 2 ) de sectores.
max_sector_cut_area_ratio : la parte de avg_sector_areaKM , que determina el área máxima que el río puede cortar.
pref_min_island_area_ratio - la parte de avg_sector_areaKM , que determina el área mínima, teniendo que la isla se convierte inmediatamente en un sector separado.
streamflow : si el río tiene un flujo final de al menos este valor, entonces participa en sectores de corte.

En el siguiente ejemplo, el uso de la función creará sectores en un terreno con ayuda = 5. En este caso, se utilizarán polígonos básicos con un área promedio de 5,000 km 2 para crear sectores con un área promedio de 40,000 km 2 . Además, al mismo tiempo, el territorio máximo cortado por ríos será 0.125 * 40,000 km 2 , y 0.25 * 40,000 km 2 es el área mínima en la cual las islas se convierten inmediatamente en sectores. Para cortar sectores por ríos, se utilizan ríos con una escorrentía final mínima de 2.

 SELECT * FROM map.makeLandSectors(5, 5000, 40000, 0.125, 0.25, 2); 

Referencias


El código de script SQL está disponible y hace todo el trabajo, incluida la creación de sectores y la creación de gráficos de transición entre sectores vecinos. Los datos SIG de planetas generados por procedimientos pueden tomarse de forgedmaps.com . Puede usar datos de GIS Earth , llevándolos a una estructura similar. También puede, utilizando cualquier SIG moderno , crear datos manualmente desde cero u obtener nuevos datos mediante la conversión de datos recibidos de cualquier otra fuente. Se pueden encontrar instrucciones más completas para el script en el manual .

Source: https://habr.com/ru/post/es414699/


All Articles