A ilustração abaixo mostra o problema :
como em (a) , tenho um conjunto de polígonos disjuntos, como geometrias no PostGIS. Preciso de algo como (b) , o "mosaico" desse conjunto de polígonos, construindo-o por um critério de "região de influência" ... É como uma construção de Voronoi (ilustrada por (c) ): de fato, se os polígonos fossem pontos, as regiões de influência são Voronoi.
Resumindo: Eu preciso de um algoritmo SQL (ou algum específico do PostGIS) que gere o "mosaico" de um conjunto de polígonos disjuntos. (talvez um loop de pequenas operações ST_Buffer e ST_Difference)
PS: Eu preciso, como o de Voronoi, que a delimitação do espaço (uma moldura quadrada em (b) ) seja ignorada.
Esse problema é semelhante ao outro sobre linhas .
EDIT (após o comentário @FelixIP)
Prefiro permanecer no universo vetorial , sem perder a precisão (por exemplo, usando ST_DelaunayTriangles e adicionando e subtraindo interiores pelos polígonos originais, adaptando uma solução de gráfico duplo ) ... Alguns pacotes simples e automáticos como pprepair (assistido como ferramentas topológicas do QGIS não são automáticos). Mas o raster talvez seja mais simples e consome menos CPU.
Esta ilustração do "processo GRID" também é válida como solução, assumindo que pode permitir a mesma precisão e "região de influência euclidiana em crescimento".
No ARCGIS existe uma ferramenta de análise espacial conhecida como Alocação Euclidiana , portanto, talvez haja uma solução semelhante ao PostGIS , começando com o conjunto de polígonos (classificando, rasterizando e recuperando os polígonos).
fonte
Respostas:
Então, eu prepararei um bolo para você - bandeja de frutas, usando as ferramentas PostGis, conforme solicitado, se eu entendi corretamente a pergunta e, como mencionei, a responsabilidade pela operação do forno PostGIS é assumida por sua equipe criativa.
Pedirei para não ser ofendido por ninguém no meu estilo de humor e entendê-lo como um jogo!
O arquivo original é uma fatia de frutas e formas simples (doravante denominadas frutas), veja a Figura 1 abaixo.
Aqui está minha receita e serei ajudado por queridos programadores, sobre os quais você aprenderá mais tarde. Vamos começar e, para isso, criaremos uma massa na qual nossos frutos serão depositados, para a qual executamos o script:
create table poly_extent as SELECT ST_SetSRID(ST_Buffer(ST_Envelope(ST_Extent(geom)),0.05),4326) as geom FROM poly;
Veja o resultado na Figura 2 abaixo
Agora, se houver poucas frutas, como na minha foto, crie a borda do buffer externo na fruta, ou se houver muitas frutas, crie a borda do buffer negativo, para a qual o script é executado:
create table poly_buff_dump as SELECT ((ST_Dump(ST_Boundary(ST_Union(ST_Buffer((geom),0.01, 'join=mitre mitre_limit=5.0'))))).geom) geom FROM poly;
E corte as linhas de buffer em torno de cada fruta
UPDATE poly_buff_dump SET geom=ST_RemovePoint(geom, ST_NPoints(geom)-1) WHERE ST_IsClosed(geom)=true;
Veja o resultado na Figura 3 abaixo(Na verdade, pensei que, como resultado, obteria linhas quebradas (como em um círculo), mas se os números forem difíceis, às vezes são obtidas quebras, incorretas, por exemplo, um lado do retângulo caiu etc. )
Então você precisa dividir as linhas obtidas de maneira conveniente para você em segmentos iguais e extrair pontos delas
create table poly_buff_dump_pt as SELECT (ST_DumpPoints((geom))).geom geom FROM poly_buff_segm;
Resultado, veja a Figura 4 abaixo
Agora execute a ferramenta Voronoi, neste local usei a ferramenta sugerida pelo link MickyT: /gis//a/172246/120129 , como resultado, você criará tabelas com o nome “voronoi ”Pelo fato de que“ meu primeiro assistente ”é separado do chef, graças ao chef! :-).
A segunda maneira nesta etapa é executar a função ST_VoronoiPolygons.
Resultado, veja a Figura 5 abaixo
Agora, corte as partes extras executando o script:
create table poly_voronoi_cut as SELECT ST_Intersection(a.geom, b.geom) geom FROM voronoi a INNER JOIN poly_extent b ON ST_Intersects(a.geom, b.geom);
Resultado, veja a Figura 6 abaixo.Agora execute o script para alinhar o tipo de dados geográficos em LineString:
create table poly_voronoi_dump as SELECT (ST_Dump(geom)).geom as geom FROM poly_voronoi_cut;
E agora vou pedir ao "meu segundo companheiro" para assumir meus deveres e misturar bem o bolo (Jeff - /gis//a/785/120129 ), nivelando-o em uma única camada e por isso , obrigado por isso!CREATE TABLE poly_overlay_cut AS SELECT geom FROM ST_Dump(( SELECT ST_Polygonize(geom) AS geom FROM ( SELECT ST_Union(geom) AS geom FROM ( SELECT ST_ExteriorRing(geom) AS geom FROM poly_voronoi_dump) AS lines ) AS noded_lines ) );
Agora é hora de eu começar a trabalhar, para a qual eu executo o script:create table poly_voronoi_union as SELECT b.id, (ST_ConvexHull(ST_Union(a.geom, b.geom))) geom FROM poly_overlay_cut a INNER JOIN poly_buff_dump b ON ST_Intersects(a.geom, b.geom) GROUP BY b.id, a.geom, b.geom;
e outro script:create table poly_voronoi_union_area as SELECT ST_Union(ST_ConvexHull(ST_BuildArea(geom))) as geom FROM poly_voronoi_union GROUP BY id;
veja a figura 7 abaixoComo você pode ver na figura, nossos cortes têm pequenas camadas, que podem ser removidas, como opção usando ST_SnapToGrid (ou de outra maneira):
E, finalmente, cortaremos nossa fruta assada da torta, até me cansei de pé junto ao forno :-)
create table polygon_voronoi_result as SELECT (ST_Dump(ST_Difference(a.geom, b.geom))).geom as geom FROM poly_voronoi_union_area_snap as a JOIN poly b ON ST_Intersects(a.geom, b.geom);
Resultado veja figura 8Tudo a partir deste dia, agora todos aprenderão a assar tortas deliciosas - prato de frutas. Sirva-se de Tudo e escolha as peças que você gosta, o suficiente para todos.
(É uma pena que eu realmente não possa alimentar todas as pessoas, não com bolos eletrônicos, mas com bolos de verdade, talvez a fome acabe na Terra ...)
Edit: A cereja na torta pode ficar assim :-):
ou
Com você foi bom e justo Mr.Baker, obrigado a todos e boa sorte,: -) ...
Soluções originais.
Este script é chamado: ST_VoronoiDiagramsFromPolygons.
fonte
ST_Buffer
eST_ConvexHull
? Existe um algoritmo alternativo?ST_ConvexHull
, é apenas uma curiosidade, que tipo de resultados podemos obter após a Figura 6,poly_voronoi_union
sem ST_ConvexHull.O Postgis não possui uma função dedicada ao voronoi, mas o Qgis contém a função vornoi, que pode criar polígonos voronoi a partir de pontos, portanto, usando o qgis, segui as seguintes etapas para obter este resultado:
- faça pontos de polígonos usando
extract nodes
funções.-Faça polígonos vornoi usando funções voroi no Qgis.
-Faça uma junção espacial no Qgis.
-dissolver resultados.
fonte
OK - Pensei um pouco sobre isso e achei que era algo que eu tenho visto ultimamente.
Pegue suas políticas iniciais:
Gere um novo atributo com um número (100 no meu caso) Use a ferramenta Vetor-> Pesquisa -> Pontos aleatórios dentro dos polígonos, isso gerará (100) pontos dentro de cada polígono:
Então Vector-> Ferramentas de geometria -> Voronoi para gerar polys com base nessa camada de pontos.
Agora, você pode usar a ferramenta Vetor -> Consulta espacial: Selecione os pontos que pertencem a um polígono (ou um dos polígonos). Use a ferramenta de consulta espacial para gerar uma seleção dos seus polígonos voronoi que se aplicam a esse polígono. Adicione um atributo ao polígono de voroni que corresponda ao polígono de interesse. (Acabei de usar 1,2,3,4)
Agora você pode Vector-> Ferramentas de Geoprocessamento-> dissolver com base no seu novo atributo.
fonte
Pontos aleatórios são uma boa idéia para gerar um polígono de voronoi a partir de polígonos, funciona muito bem, mas é muito ruim para polígonos próximos um do outro:
ST_ApproximateMedialAxis é outra boa alternativa se estiver usando o PostGIS: calculando diagramas de Voronoi para polígonos
fonte