Die folgende Abbildung zeigt das Problem :
Wie in (a) habe ich eine Reihe von disjunkten Polygonen als Geometrien in PostGIS. Ich brauche so etwas wie (b) , das "Mosaik" dieses Satzes von Polygonen, das nach einem "Einflussbereich" -Kriterium erstellt wird ... Ist wie eine Voronoi-Konstruktion (dargestellt durch (c) ): in der Tat, wenn die Polygone waren Punkte sind die Einflussregionen Voronoi.
Zusammenfassend: Ich benötige einen SQL-Algorithmus (oder einen speziellen für PostGIS), der das "Mosaik" einer Menge von disjunkten Polygonen erzeugt. (Vielleicht eine Schleife mit kleinen ST_Buffer- und ST_Difference-Operationen)
PS: Ich brauche, wie Voronos, dass die Raumbegrenzung (ein quadratischer Rahmen in (b) ) ignoriert wird.
Dieses Problem ähnelt dem anderen in Bezug auf Linien .
EDIT (nach @FelixIP Kommentar)
Ich preffer bleiben Vektor Universum, nicht verloren Präzision (ex. Mit ST_DelaunayTriangles und Addieren und Subtrahieren Innenräume durch die ursprünglichen Polygone, so dass sie eine Anpassung der dualen Graphen Lösung ) ... Einige einfache und automatische Pakete wie pprepair (unterstützt wie QGIS topologischen Werkzeuge sind nicht automatisch). Aber Raster ist vielleicht einfacher und verbraucht weniger CPU.
Diese "GRID-Prozess" -Darstellung ist auch als Lösung gültig, vorausgesetzt, dass sie die gleiche Präzision und das "Wachstum der euklidischen Einflussregion" ermöglicht.
In ARCGIS gibt es ein räumliches Analyse-Tool, das als Euklidische Allokation bezeichnet wird. Daher gibt es möglicherweise eine PostGIS-ähnliche Lösung , die mit der Menge der Polygone beginnt (Klassifizieren, Rastern und Zurücksetzen der Polygone).
quelle
Antworten:
Wenn ich die Frage richtig verstanden habe und wie bereits erwähnt, trägt ihr Kreativteam die Verantwortung für den Betrieb des PostGIS-Ofens.
Ich werde darum bitten, mich von niemandem in meinem humorvollen Stil beleidigen zu lassen und es als Spiel zu verstehen!
Die Originaldatei besteht aus geschnittenen Früchten und einfachen Formen (im Folgenden als Frucht bezeichnet), siehe Abbildung 1 unten.
Hier ist mein Rezept und ich werde dabei von lieben Programmierern unterstützt, die Sie später kennenlernen werden. Beginnen wir, und dafür werden wir einen Teig herstellen, in den unsere Früchte gelegt werden, für den das Skript ausgeführt wird:
create table poly_extent as SELECT ST_SetSRID(ST_Buffer(ST_Envelope(ST_Extent(geom)),0.05),4326) as geom FROM poly;
Siehe das Ergebnis in Abbildung 2 unten
Wenn es nur wenige Früchte gibt, wie in meinem Bild, erstellen Sie den Rand des externen Puffers auf der Frucht, oder wenn es viele Früchte gibt, erstellen Sie den Rand des negativen Puffers, für den das Skript ausgeführt wird:
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;
Und schneiden Sie die Pufferlinien um jede Frucht
UPDATE poly_buff_dump SET geom=ST_RemovePoint(geom, ST_NPoints(geom)-1) WHERE ST_IsClosed(geom)=true;
Siehe das Ergebnis in Abbildung 3 unten(Eigentlich dachte ich, dass ich als Ergebnis unterbrochene Linien bekommen würde (wie in einem Kreis), aber wenn die Figuren schwierig sind, werden manchmal Brüche erhalten, falsche, zum Beispiel eine Seite des Rechtecks fiel ab usw. )
Dann müssen Sie die erhaltenen Linien auf eine für Sie bequeme Weise in gleiche Segmente unterteilen und Punkte daraus extrahieren
create table poly_buff_dump_pt as SELECT (ST_DumpPoints((geom))).geom geom FROM poly_buff_segm;
Ergebnis, siehe Abbildung 4 unten
Führen Sie nun das Voronoi-Tool aus. An dieser Stelle habe ich das von MickyT vorgeschlagene Tool verwendet: /gis//a/172246/120129 , wodurch Sie Tabellen mit dem Namen „voronoi“ erstellt haben "Für die Tatsache, dass" mein erster Assistent "vom Küchenchef getrennt ist, danke vom Küchenchef!" :-).
Die zweite Möglichkeit in diesem Schritt besteht darin, die Funktion ST_VoronoiPolygons auszuführen.
Ergebnis, siehe Abbildung 5 unten
Schneiden Sie nun die zusätzlichen Teile aus, indem Sie das Skript ausführen:
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);
Ergebnis, siehe Abbildung 6 unten.Führen Sie nun das Skript aus, um den Geodatentyp in LineString auszurichten:
create table poly_voronoi_dump as SELECT (ST_Dump(geom)).geom as geom FROM poly_voronoi_cut;
Und jetzt werde ich "meinen zweiten Kumpel" bitten, meine Pflichten zu übernehmen und den Kuchen zu mixen (Jeff - /gis//a/785/120129 ), und zwar in einer einzigen Schicht und dafür , danke mir dafür!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 ) );
Jetzt ist es Zeit für mich, mich an die Arbeit zu machen, für die ich das Skript ausführe: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;
und ein weiteres Skript:create table poly_voronoi_union_area as SELECT ST_Union(ST_ConvexHull(ST_BuildArea(geom))) as geom FROM poly_voronoi_union GROUP BY id;
siehe Abbildung 7 untenWie Sie auf dem Bild sehen können, haben unsere Schnitte kleine Ebenen, die optional mit ST_SnapToGrid (oder auf andere Weise) entfernt werden können:
Und zum Schluss werden wir unsere gebackenen Früchte aus unserer Torte herausschneiden, ich bin sogar ein bisschen müde geworden, als ich am Ofen stand :-)
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);
Ergebnis siehe Abbildung 8Alles von diesem Tag an wird jetzt jeder lernen, leckere Kuchen zu backen - Obstteller. Hilf dir selbst, und wähle die Teile aus, die dir gefallen, genug für alle.
(Es ist schade, dass ich wirklich nicht alle Menschen ernähren kann, nicht mit elektronischen Kuchen, sondern mit echten Kuchen, vielleicht würde der Hunger auf der Erde enden ...)
Edit: Die Kirsche auf dem Kuchen könnte so aussehen :-):
oder
Mit dir war gut und fair Mr.Baker, vielen Dank und viel Glück, :-) ...
Originelle Lösungen.
Dieses Skript heißt: ST_VoronoiDiagramsFromPolygons.
quelle
ST_Buffer
undST_ConvexHull
? Gibt es einen alternativen Algorithmus?ST_ConvexHull
, ist nur eine Kuriosität, welche Art von Ergebnissen wir nach Abbildung 6poly_voronoi_union
erzielen können, ohne ST_ConvexHull.Postgis haben keine dedizierte Funktion für voronoi, aber Qgis enthält eine vornoi-Funktion, mit der aus Punkten voronoi-Polygone erstellt werden können. Mit qgis habe ich die folgenden Schritte ausgeführt, um diese Ergebnisse zu erzielen:
- Erstelle Punkte aus Polygonen mit
extract nodes
Funktionen.-Erstelle Vornoi-Polygone mit Voroi-Funktionen in Qgis.
-Erstelle einen räumlichen Join in Qgis.
Ergebnisse auflösen.
quelle
OK - Ich habe ein wenig darüber nachgedacht und festgestellt, dass es etwas ist, was ich mir in letzter Zeit angesehen habe.
Nimm deine Start-Polys:
Generieren Sie ein neues Attribut mit einer Zahl (in meinem Fall 100). Verwenden Sie das Werkzeug Vektor-> Recherchieren -> Zufällige Punkte innerhalb von Polygonen. Dadurch werden (100) Punkte innerhalb jedes Polygons generiert:
Dann Vektor-> Geometriewerkzeuge -> Voronoi, um Polys basierend auf dieser Punktebene zu generieren.
Jetzt können Sie das Werkzeug Vektor -> räumliche Abfrage verwenden: Wählen Sie die Punkte aus, die zu einem Polygon (oder einem der Polygone) gehören. Verwenden Sie das Werkzeug für räumliche Abfragen, um eine Auswahl Ihrer Voronoi-Polygone zu generieren, die für dieses Polygon gelten. Fügen Sie dem Voroni-Polygon ein Attribut hinzu, das dem gewünschten Polygon entspricht. (Ich habe gerade 1,2,3,4 verwendet)
Jetzt können Sie Vektor-> Geoverarbeitungswerkzeuge-> basierend auf Ihrem neuen Attribut auflösen.
quelle
Zufällige Punkte sind eine gute Idee, um ein Voronoi-Polygon aus Polygonen zu generieren. Es funktioniert ziemlich gut, aber für Polygone, die nahe beieinander liegen, ist es ziemlich schlecht:
ST_ApproximateMedialAxis ist eine weitere gute Alternative, wenn PostGIS verwendet wird: Berechnung von Voronoi-Diagrammen für Polygone
quelle