Skip to content

Creare un mosaico come il diagramma di Voronoi da poligoni disgiunti

Dopo aver consultato esperti in materia, programmatori di diverse branche e professori, abbiamo trovato la risposta al problema e la presentiamo in questa pubblicazione.

Soluzione:

Postgis non ha una funzione dedicata al diagramma di Voronoi, ma Qgis contiene la funzione vornoi che può creare poligoni di Voronoi a partire da punti, quindi utilizzando Qgis ho seguito i seguenti passaggi per ottenere questi risultati:

-Creare punti da poligoni utilizzando extract nodes funzioni.

-Creare poligoni vornoi usando le funzioni voroi di Qgis.

-Creare un join spaziale in Qgis.

-Dissolvere i risultati.

enter image description here

OK - Ho riflettuto un po' su questo e ho scoperto che era simile a qualcosa che ho osservato di recente.

Prendete i vostri poli di partenza:

enter image description here

Generare un nuovo attributo con un numero (100 nel mio caso)
Utilizzare lo strumento Vettoriale-> Strumenti di ricerca -> Punti casuali all'interno di poligoni
questo genererà (100) punti all'interno di ogni poligono:
enter image description here

Poi Vector-> Strumenti geometria -> Voronoi per generare poligoni basati su quel livello di punti.

enter image description here

Ora è possibile utilizzare lo strumento Vector -> Spatial Query:
Selezionare i punti che appartengono a un poligono (o a uno dei poligoni).
Utilizzare lo strumento di interrogazione spaziale per generare una selezione dei poligoni di voronoi che si applicano a quel poligono.
Aggiungere un attributo al poligono di voronoi che corrisponde al poligono di interesse. (Io ho usato semplicemente 1,2,3,4)

Ora è possibile Vettoriale-> Strumenti di geoprocessing-> Dissolvi in base al nuovo attributo.

enter image description here

Quindi, preparerò una torta per lei - piatto di frutta, utilizzando gli strumenti PostGIS, come da lei richiesto, se ho capito bene la domanda, e come ho detto, la responsabilità del funzionamento del forno PostGIS è a carico del suo team creativo.

Chiedo di non offendere nessuno nel mio stile umoristico e di intenderlo come un gioco!

Il file originale è costituito da frutta tagliata a fette e forme semplici (di seguito denominata frutta), vedi Figura 1 qui sotto.

enter image description here

Ecco la mia ricetta, e in questo sarò aiutato da cari programmatori, che conoscerete più avanti.
Cominciamo, e per questo creeremo un impasto in cui saranno adagiati i nostri frutti, per i quali eseguiremo lo script:

create table poly_extent as
SELECT ST_SetSRID(ST_Buffer(ST_Envelope(ST_Extent(geom)),0.05),4326) as geom FROM poly;

Guardate il risultato nella Figura 2 qui sotto

enter image description here

Ora, se ci sono pochi frutti, come nella mia immagine, create il bordo del buffer esterno sul frutto, oppure se ci sono molti frutti, create il bordo del buffer negativo, per cui eseguite lo script:

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 tagliare le linee del buffer intorno a ogni frutto

UPDATE poly_buff_dump SET geom=ST_RemovePoint(geom, ST_NPoints(geom)-1)
WHERE ST_IsClosed(geom)=true;

Vedere il risultato nella Figura 3 qui sotto

enter image description here

(In realtà, pensavo che come risultato avrei ottenuto linee spezzate (come in un cerchio), ma se le figure sono difficili, a volte si ottengono delle interruzioni, non corrette, ad esempio, un lato del rettangolo è caduto, ecc.)

Quindi è necessario dividere le linee ottenute in modo conveniente per voi in segmenti uguali ed estrarre i punti da essi

create table poly_buff_dump_pt as
SELECT (ST_DumpPoints((geom))).geom geom FROM poly_buff_segm;

Risultato, vedi Figura 4

enter image description here

Ora eseguite lo strumento Voronoi, in questo caso ho usato lo strumento suggerito dal link di MickyT :https://gis.stackexchange.com/a/172246/120129
Come risultato avrete creato delle tabelle con il nome "voronoi" per il fatto che "il mio primo assistente" è separato dallo chef grazie allo chef!)

Il secondo modo in questo passaggio è quello di eseguire la funzione ST_VoronoiPolygons.

Risultato, vedi Figura 5 qui sotto

enter image description here

Ora, tagliate le parti extra eseguendo lo 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);

Risultato, vedere la Figura 6 qui sotto.

enter image description here

Eseguire ora lo script per allineare il tipo di geodati in LineString:

create table poly_voronoi_dump as
SELECT (ST_Dump(geom)).geom as geom
FROM poly_voronoi_cut;

E ora chiederò al "mio secondo compagno" di prendere il mio posto e di mescolare la torta (Jeff - https://gis.stackexchange.com/a/785/120129), livellandola in un unico strato, e per questo, grazie a me!

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
)
);

Ora è il momento di mettermi al lavoro, per cui eseguo lo 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 un altro 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;

vedere la figura 7 qui sotto

enter image description here

Come si può vedere nell'immagine, i nostri tagli hanno piccoli strati, che possono essere rimossi, come opzione, usando ST_SnapToGrid (o in altro modo):

E infine, tagliamo la frutta cotta dalla nostra torta, mi sono anche un po' stancato a stare vicino al 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);

Risultato vedi figura 8
enter image description here

Da oggi tutti impareranno a preparare deliziose torte - piatto di frutta. Servitevi Tutti, e scegliete i pezzi che vi piacciono, abbastanza per tutti.

(È un peccato che io non possa sfamare tutte le persone, non con torte elettroniche, ma con torte vere, forse la fame finirebbe sulla Terra...)

Modifica: La ciliegina sulla torta potrebbe essere così 🙂 :

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;

oppure

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;

Rivedere lo script 01.04.2020:

WITH tbla AS (
WITH atbl AS (SELECT id, (ST_ExteriorRing(((ST_Dump(geom)).geom))) geom FROM polygons),
intervals AS (SELECT generate_series (0, 501) as steps)
SELECT steps AS stp, ST_LineInterpolatePoint(geom, steps/(SELECT count(steps)::float-1 FROM intervals)) geom FROM atbl, intervals GROUP BY id, intervals.steps, geom),
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;

Con voi è stato buono e giusto Mr.Baker, grazie a tutti e buona fortuna, :-)...

Soluzioni originali.

Questo script si chiama: ST_VoronoiDiagrammiDaPoligoni.

Ricorda che ti diamo il privilegio di aggiungere una recensione.



Utilizzate il nostro motore di ricerca

Ricerca
Generic filters

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.