Aqui, consideraremos um método para dividir a superfície esférica de um planeta processualmente gerado por ladrilhos irregulares e, como conseqüência, dividir o oceano e os continentes em seções (setores) separados. Assumimos que na superfície do planeta uma estrutura de terreno já foi definida usando algum GIS e é possível exportar dados vetoriais para shapefiles da ESRI ou diretamente para um banco de dados PostgreSQL com a extensão
PostGIS . O processo de criação de setores é realizado usando o PostGIS.
Veja o link para o script com código SQL na parte inferior da postagem, aqui a explicação será mais direta. A explicação fornece as funções básicas do script e também pressupõe a disponibilidade de dados para continentes e rios de planetas gerados proceduralmente retirados de
forgedmaps.com .
A escolha de ladrilhos irregulares nos permite subdividir com precisão a superfície do planeta
em setores, geralmente não misturando territórios do oceano e terra em qualquer lugar. Lagos e mares interiores
consideramos parte da terra. Também veremos como os rios podem ser usados como limites naturais de setores. Os próprios setores serão construídos com base em alguma divisão básica da esfera por polígonos.
Quando se trata de dividir uma região plana, eles geralmente recorrem ao
diagrama de Voronoi para obter ladrilhos irregulares. Usando também
o algoritmo Lloyd , podemos chegar a uma forma visualmente atraente de polígonos convexos que não são muito diferentes em tamanho (mosaico de Vroidono Centroidal). A essência do algoritmo de Lloyd's é repetir a construção do diagrama de Voronoi, a cada iteração subsequente, tomando como pontos geradores os centros dos polígonos obtidos na iteração anterior.
Imporemos certos requisitos à divisão básica por polígonos de uma esfera:
a convexidade dos polígonos esféricos e seus desvios não muito grandes de um determinado tamanho médio.
O
setor de nome
é usado em vez de um
bloco devido ao fato de que o bloco geralmente tem um significado elementar, por exemplo, como parte da unidade das cartas de peças de jogos estratégicos ou como parte da unidade de uma determinada superfície. Dentro do setor existe uma estrutura interna: o relevo e vários objetos geográficos. Os setores, por sua vez, também podem servir como blocos elementares: a construção de um gráfico de possíveis transições entre setores serve a esse propósito.
A divisão básica da esfera e segmentos dos oceanos.
O PostGIS possui uma função
ST_VoronoiPolygons
, que constrói um diagrama de Voronoi em uma área quadrada. Vamos ver como podemos usá-lo para nossos propósitos.
O que acontece se você tentar usar uma abordagem direta? Uma projeção retangular do planeta pode ser convertida em quadrado por coordenadas, construir polígonos lá e realizar a transformação inversa de coordenadas. Porém, os retângulos construídos dessa maneira serão esticados em uma direção, o que seria indesejável. E, se você tentar aplicar o algoritmo de Lloyd, os retângulos próximos aos pólos da esfera serão significativamente menores em área (na esfera) do que próximos ao equador.
Vamos tentar adaptar esse método com a eliminação de desvantagens. Os pontos de partida aleatórios do diagrama de Voronoi são escolhidos para serem distribuídos uniformemente na esfera. Na projeção de Mercator, isso significa que, para os pólos, eles devem aparecer com menos frequência, com uma probabilidade proporcional ao cosseno da latitude. Estamos construindo o diagrama de Voronoi no polígono do “mundo” - essa é a projeção retangular inteira do planeta ou apenas uma parte dele. A
ST_VoronoiPolygons
função
ST_VoronoiPolygons
completa o retângulo para um quadrado, basta cortar o diagrama resultante de acordo com o polígono "mundo".
Observamos a figura dos polígonos de Voronoi obtidos de maneira adaptada. Aqui está uma parte do mapa do planeta de teste do equador na borda superior a 73 graus de latitude sul na borda inferior. (Aqui a área de terra já foi cortada dos aterros sanitários.)

Como pode ser visto na projeção de Mercator, os polígonos geralmente são maiores ao se aproximar dos polos, mas serão distribuídos aproximadamente igualmente pela esfera em termos de tamanho da área. É disso que precisamos. Mas, também é visto que os polígonos têm uma grande variedade de áreas e o quadro geral é bastante desagradável.
Vamos tentar aplicar várias iterações do algoritmo Lloyd. Como novos pontos
para iterações subseqüentes do diagrama de Voronoi, escolheremos os centros dos já cortados
Polígono de "mundo" polígonos de Voronoi. E para evitar muita redução na área de polígonos perto dos pólos, fazemos apenas um pequeno número de iterações (3 ou mais).
Para obter segmentos oceânicos, a área ocupada é excluída dos aterros obtidos. Como resultado, pequenos polígonos podem ser formados, o que é desejável anexar aos vizinhos. Além disso, pequenos polígonos podem estar próximos à borda do polígono “mundial”. Conectamos os polígonos de maneira a selecionar o vizinho "mais próximo" e não estragar a imagem geral.
Após a aplicação de um algoritmo modificado, obtemos a seguinte imagem, que já pode ser aceitável. Segmentos vermelhos na figura indicam a mesclagem desejada dos polígonos.

A seleção de polígonos para mesclagem pode ser feita de diferentes maneiras. No script mencionado, dois métodos são implementados: na borda mais longa e no centro mais próximo. A figura a seguir mostra o resultado da fusão da segunda maneira.

Em geral, alcançamos o que pode ser desejado dos setores oceânicos. Sua área é aproximadamente a mesma (na esfera) e são convexas ou com pequenos desvios da convexidade.
A principal função para gerar setores oceânicos:
map.makeOceanSectors( world Geometry, avg_vp_areaKM Double Precision, merging_ratio Double Precision, merging_method Int ) RETURNS Void
world
- um campo de treinamento do “mundo” que serve como as fronteiras do mundo.
avg_vp_areaKM
- a área média (km
2 ) de polígonos a partir da qual os setores oceânicos são feitos.
merging_ratio
- compartilhamento de
avg_vp_areaKM
, de modo que, se a área do setor for menor que ela, ela será anexada à vizinha.
método de
merging_method
- mesclagem ('1' ou '2').
Um exemplo Estamos construindo setores em um determinado aterro “mundial”, com uma área média de aterros de base de 1.000.000 km
2 . Setores cuja área é menor que a metade desse tamanho serão unidos a outros. O segundo método de fusão é usado - no centro mais próximo.
SELECT * FROM map.makeOceanSectors( ST_GeomFromText( 'POLYGON((-75 -85, 75 -85, 75 85, -75 85, -75 -85))', 4326 ), 1000000, 0.5, 2 );
Segmentos dos continentes.
No continente, é possível entrar em uma divisão mais interessante, baseada, por um lado, na totalidade de pequenos polígonos básicos e, por outro lado, em objetos naturais, como rios e bacias hidrográficas. A estrutura assim obtida é muito semelhante ao mapa de estados e províncias neles. Ou seja, esse é o processo de
gerar processualmente o mapa político do mundo .
Ao contrário dos segmentos oceânicos, a protuberância se torna completamente opcional.
Ainda não há bacias hidrográficas no forgedmaps.com, mas já existem rios. O uso de rios em um script requer sua representação em um
MultiLineString . Eles têm essa idéia no
arquivo shapefile do
riversz . Ao importar para o banco de dados, você pode se livrar imediatamente do excesso de coordenadas z nesse processo. Outros dados necessários, nomeadamente os limites das áreas de terra, estão no arquivo de formas da terra. Cada área terrestre possui um identificador de
aid
(ID da área) e pode consistir no continente e nas ilhas mais próximas, ou apenas pequenas ilhas localizadas nas proximidades.
Para o nosso exemplo, escolhemos o tamanho médio do setor de 40.000 km
2 e o tamanho médio do polígono base de 5.000 km
2 . Esse é um tamanho bastante grande, escolhido apenas para ilustração. Tamanhos menores também são aceitáveis (até alguns m
2 ), mas acompanhe o tempo de cálculo e use a configuração apropriada do banco de dados.
Nesta figura, um exemplo de como os polígonos básicos ficam dentro da área de terra.

O próximo passo é combinar os polígonos de base em setores. Para fazer isso, selecione aleatoriamente a partir dos polígonos base, quantos setores quisermos criar, e gradualmente anexe polígonos vizinhos aos setores acumulados.

Agora é a hora de levar o rio em consideração. Nós os usamos para dividir setores em
partes separadas pela função
ST_Split
. Essa divisão pode ser realizada dependendo de algumas condições: o fluxo final do rio ou a área da parte separada.
Agora podemos ver como algumas fronteiras percorrem os rios.

Conectamos pequenas partes de setores a grandes. Mas devemos tentar
Não conecte peças aos mesmos setores dos quais foram cortadas.

Com grandes áreas de terra que conseguimos, mas ainda pequenas ilhas. Tornamos aqueles que possuem uma área próxima à área média do setor como setores separados de uma só vez. Mas com aqueles cuja área é muito menor que o setor médio, estamos fazendo duas coisas.
1. Se essas ilhas estiverem localizadas relativamente distantes dos setores existentes, então as separamos. “Farness” aqui depende da área média especificada do setor: quanto menor essa área, maior a probabilidade de a ilha se tornar um setor separado.
2. Se a ilha estiver próxima de outros setores já criados, ela será combinada com um deles. Ou seja, com a que possui a maior área em um determinado polígono obtido usando
ST_Buffer
desta ilha.

Aqui, quatro ilhas se dividiram em dois setores diferentes. Se você aumentar a área média do setor definida, mais cedo ou mais tarde todas as ilhas cairão em um único setor.
A principal função para gerar setores em terra:
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 do terreno.
avg_vp_areaKM
- a área média (km
2 ) dos polígonos de base.
avg_sector_areaKM
- área média (km
2 ) de setores.
max_sector_cut_area_ratio
- o compartilhamento de
avg_sector_areaKM
, que determina a área máxima que pode ser cortada pelo rio.
pref_min_island_area_ratio
- a parcela de
avg_sector_areaKM
, que determina a área mínima, com a qual a ilha se torna imediatamente um setor separado.
streamflow
- se o rio tiver um fluxo final de pelo menos esse valor, ele participará dos setores de corte.
No exemplo a seguir, o uso da função criará setores em um terreno com aid = 5. Nesse caso, polígonos básicos com uma área média de 5.000 km
2 serão usados para criar setores com uma área média de 40.000 km
2 . Além disso, ao mesmo tempo, o território máximo cortado pelos rios será de 0,125 * 40.000 km
2 , e 0,25 * 40.000 km
2 é a área mínima na qual as ilhas se tornam setores imediatamente. Para cortar setores por rios, são usados rios com um escoamento final mínimo de 2.
SELECT * FROM map.makeLandSectors(5, 5000, 40000, 0.125, 0.25, 2);
Referências
Está disponível um
código de script SQL que faz todo o trabalho, incluindo a criação de setores e a criação de gráficos de transição entre os setores vizinhos. Dados GIS de planetas gerados proceduralmente podem ser obtidos em
forgedmaps.com . Você pode usar os
dados do GIS Earth , levando-os a uma estrutura semelhante. Você também pode, usando qualquer
SIG moderno , criar dados manualmente do zero ou obter novos dados convertendo dados recebidos de qualquer outra fonte. Instruções mais completas para o script podem ser encontradas no
manual .