Ich habe eine Reihe von Polygonen, die große Gebiete darstellen, beispielsweise Stadtviertel. Ich möchte die großen überlappenden Bereiche zwischen ihnen identifizieren.
Aber es gibt ein Problem: Manchmal überlappen sich diese Polygone entlang ihres Umfangs (weil sie mit geringer Genauigkeit gezeichnet wurden). Dies erzeugt lange und enge Überlappungen, die mir egal sind.
In anderen Fällen kommt es jedoch zu großen Überlappungen robuster Polygone, dh zu großen Bereichen, in denen das Polygon eines Stadtviertels ein anderes überlappt. Ich möchte nur diese auswählen.
Siehe das Bild unten nur der Überlappungen. Stellen Sie sich vor, ich wollte nur das blaue Polygon in der unteren linken Ecke auswählen.
Ich könnte mir Bereiche ansehen, aber manchmal sind die schmalen so lang, dass sie Bereiche haben, die so groß sind wie das blaue Polygon. Ich habe versucht, ein Verhältnis von Fläche / Umfang zu erreichen, aber das hat auch zu gemischten Ergebnissen geführt.
Ich habe es sogar versucht ST_MinimumClearance
, aber manchmal ist an den großen Flächen ein schmaler Teil oder zwei sehr enge Eckpunkte angebracht.
Irgendwelche Ideen für andere Ansätze?
Am Ende funktionierte für mich am besten ein negativer Puffer, wie von @Cyril und @FGreg unten vorgeschlagen.
Ich habe so etwas benutzt wie:
ST_Area(ST_Buffer(geom, -10)) as neg_buffer_area
In meinem Fall waren Einheiten Meter, also 10 m negativer Puffer.
Bei schmalen Polygonen gab dieser Bereich Null zurück (außerdem wäre die Geometrie leer). Dann habe ich diese Spalte verwendet, um die schmalen Polygone herauszufiltern.
Antworten:
Ich würde versuchen, einen negativen Puffer zu erstellen. Wenn er dünne Polygone frisst, ist er gut. Wenn er das Polygon nicht frisst, gehört er mir ... :-)
Führen Sie dieses Skript aus, nachdem Sie zuvor 2/3 der Breite der linearen Polygone festgelegt haben ...
Betriebssystem: -) ...
quelle
ST_Area(ST_Buffer(geom, -10))
, wobei -10 in meinem Fall -10 Meter sind. Wenn irgendetwas von diesem Ausdruck 0 zurückgibt, kann ich es herausfiltern.Anstelle von Fläche / Umfang ist es besser, die Fläche zu verwenden, die durch das Quadrat des Umfangs (oder dessen Umkehrung) geteilt wird.
Dies wird auch als "Formindex" bezeichnet. Das Quadrat des Umfangs geteilt durch die Fläche hat einen Mindestwert von 4 * Pi () (im Fall einer Scheibe, bei der es sich um die kompakteste 2D-Geometrie handelt), sodass es zur Vereinfachung durch 4 * Pi () normalisiert werden kann Interpretation (normalisierte Werte nahe 1 bedeuten dann, dass Sie sehr kompakte Objekte haben und Quadrate Werte von ungefähr 1,27 haben).
BEARBEITEN: Ein Schwellenwert für den Bereich wäre nützlich, um die sehr kleinen Artefakte zu entfernen, die kompakt sein könnten. Dann würde der Formindex einen besseren Kontrast zeigen. BEARBEITEN: Zusätzlich zu dieser Antwort kann die Verwendung von ST_Snap Ihnen helfen, das Problem zu lösen, bevor es auftritt.
quelle
(o.overlap_perimeter^2 / o.overlap_area) / (4 * Pi()) as overlap_ratio
? Dies hat für mich schlechtere Ergebnisse als nur Fläche / Umfang.o.overlap_perimeter / (4 * sqrt(o.overlap_area)) as overlap_ratio
nach diesem Artikel, aber noch schlechtere Ergebnisse (obwohl das schwer zu quantifizieren ist, was ich mit schlechter meine) isprs-ann-photogramm-remote-sens-spatial-inf-sci.net/I-7/135/… , Seite 183.Eine Möglichkeit wäre, das Verhältnis der Fläche des Polygons zur längsten Linie zu verwenden, die mit ihren Enden gezeichnet werden kann. Lange schmale Polygone identifizieren.
select * from polygons where ST_Length(ST_LongestLine(geom, geom)) < ST_Area(geom) * 4
Dies funktioniert ziemlich gut für Splitterpolygone. Sie können das Verhältnis (mit dem Sie die Fläche multiplizieren) an Ihre Bedürfnisse und Ihre Projektion anpassen.
quelle
Es hört sich so an, als würde dies Ihrem Anwendungsfall entsprechen: Beseitigen Sie ausgewählte Polygone
Es hört sich so an, als ob Sie die Option "Größte gemeinsame Grenze" ausprobieren möchten.
quelle
Dies scheint mir ein perfekter Anwendungsfall für die PostGIS-Topologieerweiterung zu sein . Der Toleranzparameter der Topologie bestimmt, wie weit Scheitelpunkte an anderen vorhandenen Polygonen ausgerichtet werden können, um mit der geringen Genauigkeit der Quelldaten fertig zu werden und diese zu bereinigen.
Kurz gesagt lautet die Strategie:
1. Aktivieren Sie die Topologieerweiterung
2. Erstellen Sie eine neue leere Topologie
Der dritte Parameter ist die Toleranz in den Einheiten des CRS; wähle es mit Bedacht aus. Idealerweise möchten Sie ein CRS, bei dem die Einheit Meter ist. Wenn die CRS-Einheit keine Messgeräte ist, wie bei WGS 84 aka 4326, verwenden Sie
ST_Transform
diese Option, um Ihre Polygone neu zu projizieren.3. Fügen Sie der Polygontabelle eine TopoGeometry-Spalte hinzu
Dies gibt eine neue zurück
layer_id
. Speichern Sie es, es wird später benötigt. Es wird eine Ebene sein,1
wenn Sie von vorne beginnen, und bei jedem neuen Anruf erhöht.4. Fügen Sie der Polyologie alle Polygone hinzu
Dies kann für einen großen Datensatz mehrere Stunden dauern. Seien Sie geduldig.
1
ist die zuvor zurückgegebene layer_id.5. Finden Sie Gesichter, die in mehreren Stadtteilen erscheinen
Finden Sie alle Gesichter aus der Topologie, die in 2 oder mehr Topogeometrien vorhanden sind. Ich werde die Abfrage als Übung verlassen. Am einfachsten ist es wahrscheinlich mit der
GetTopoGeomElements
Funktion, dann nach Gesichts-ID zu gruppieren und diejenigen mit einer Anzahl von 2 oder mehr zu betrachten. Alternativ können Sie eine neue Tabelle mit der bereinigten Geometrie aus der Topogeom-Spalte erstellen, sie einfach in die Standardgeometrie umwandelntopogeom::geometry
und das wiederholen, was Sie bereits jetzt haben, aber jetzt mit einem sauberen Datensatz, ohne dass sich die Faserbandüberlappungen ergeben.quelle