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 abaixo
Como 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 8
Tudo 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 :-):
WITH
tbla AS (SELECT (ST_DumpPoints(geom)).geom geom FROM poly),
tblb AS (SELECT ((ST_Dump(ST_VoronoiPolygons(ST_Collect(geom)))).geom) geom FROM tbla),
tblc AS (SELECT ST_Intersection(a.geom, b.geom) geom FROM tblb a JOIN poly_extent b ON ST_Intersects(a.geom,b.geom)),
tbld AS (SELECT id, ((ST_Dump(geom)).geom) geom FROM poly GROUP BY id, geom)
SELECT id, ST_Union(a.geom) as geom FROM tblc a JOIN tbld b ON ST_Intersects(a.geom, b.geom) GROUP BY id;
ou
WITH
tbla AS (SELECT (ST_DumpPoints(geom)).geom geom FROM polygons),
tblb AS (SELECT ((ST_Dump(ST_VoronoiPolygons(ST_Collect(geom)))).geom) geom FROM tbla),
tblc AS (SELECT id, ((ST_Dump(geom)).geom) geom FROM polygons GROUP BY id, geom)
SELECT id, ST_Union(a.geom) geom FROM tblb a JOIN tblc b ON ST_Intersects(a.geom, b.geom) GROUP BY id;
Com você foi bom e justo Mr.Baker, obrigado a todos e boa sorte,: -) ...
Soluções originais.
Este script é chamado: ST_VoronoiDiagramsFromPolygons.