Rekursive PostGIS-Abfrage basierend auf Leitungskonnektivität

9

Ich habe Schwierigkeiten mit einer Abfrage. Ich habe ein Netzwerk von Linestrings mit jeweils einem Wert in der Spalte n_type. Dies kann eine von wenigen Optionen sein. Ich möchte eine neue Tabelle erstellen, die alle Linestrings des gleichen Typs gruppiert und eine durchgehende Linie bildet.

Vor:

Geben Sie hier die Bildbeschreibung ein

Nach dem:

Geben Sie hier die Bildbeschreibung ein

Folgendes habe ich bisher. Es gibt Ergebnisse zurück, aber sie ergeben keinen Sinn - die Typen stimmen nicht überein und es werden zu viele Funktionen zurückgegeben.

Bitte beachten Sie auch, dass ich "durchgehend" als eine Linie innerhalb von 5 Fuß von ihrem Nachbarn definiert habe, die sich in einem Winkel von weniger als 30 Grad trifft.

WITH RECURSIVE all_links (i, pk_uid, n_type, geom) AS (
    SELECT  1 AS i,
            pk_uid,
            n_type,
            geom
    FROM    network
    WHERE   n_type != 'none'

    UNION ALL

    SELECT  a.i + 1,
            b.pk_uid,
            b.n_type,
            b.geom
    FROM    network b, all_links a
    WHERE   b.n_type = a.n_type
    AND     b.geom <#> a.geom <= 5  --lines are continuous if within 5 feet of neighbor
    AND     ABS( DEGREES( 3*pi() - st_azimuth(st_startpoint(a.geom),st_endpoint(a.geom)) + st_azimuth(st_startpoint(b.geom),st_endpoint(b.geom)))::int % 360 - 180) <= 30 )  --only take links within 30 degrees of the same angle

SELECT i, n_type, ST_Union(the_geom) FROM all_links GROUP BY i, n_type

Ich habe angenommen, dass eine rekursive Abfrage der richtige Weg ist, aber ich bin froh, dass ich mich darin geirrt habe. Rekursive sind etwas schwer zu verstehen.

Bearbeiten: Ich sollte auch hinzufügen, dass ich bereits versucht habe, mit ST_Union und ST_Linemerge zu aggregieren und dann das Ergebnis zu sichern. Dies funktioniert ein bisschen, berücksichtigt jedoch keine Kreuzungen von> 30 Grad und kann auch die 5-Fuß-Toleranz für Konnektivität nicht einhalten.

spencerrecneps
quelle
Ohne zu tief in diese zu graben, ein paar Beobachtungen. Sie müssen a.geom und b.geom in Ihrer select-Klausel vereinen. Sie sollten wahrscheinlich sicherstellen, dass Sie nicht versuchen, eine Linie mit sich selbst zu verbindena.pk_uid != b.pk_uid
MickyT
@ MickyT danke. Ich hätte erwähnen sollen, dass ich die Vereinigung in der letzten SELECT-Klausel durchführen kann, aber vorerst nur * ausgewählt habe, damit ich alle Ergebnisse sehen kann. Ich werde mein Code-Snippet ändern, um zu zeigen, wie es irgendwann aussehen sollte.
Spencerrecneps
Rekursive Abfragen sind schwer zu erfassen. Lol und +1
John Powell
Ein kurzer Blick deutet darauf hin, dass Sie möglicherweise Probleme mit Ihrer Basis- / Ankerabfrage haben. Sie müssen den Startpunkt für jede Linie A, B, C usw. auswählen, die Sie dann im rekursiven Teil aufbauen. Möglicherweise müssen Sie der Ankerabfrage eine Art Reihenfolge hinzufügen (möglicherweise in x- oder y-Richtung - schwer zu erkennen, ohne die Daten zu sehen). Ich würde dies aufschlüsseln und sicherstellen, dass ich zuerst vernünftige Startpunkte bekomme, bevor ich mit dem rekursiven Teil fortfahre. Ich habe kürzlich eine rekursive Abfrage verwendet, um Streifen in Zeitreihen zu finden, und nachdem ich die Ankerpunkte korrekt identifiziert hatte, war der Rest einfach (ish)
John Powell
@dbaston. Guter Punkt, aber Sie können dies auch mit einer rekursiven Abfrage tun, und das hat noch nicht jeder installiert.
John Powell

Antworten:

1

Ihrer Lösung fehlt zumindest eine Vorbestellung von Leitungskomponenten, wie John Barça sagte.

Rekursive Abfragen sind sehr, sehr schwer zu bearbeiten, würde ich sagen.

Sie müssen versuchen, das Verhalten von ST_Linemerge in einer neuen Datenbankfunktion zu replizieren. Ich würde zuerst versuchen, die Quelle einer ST_Linemerge-Implementierung zu untersuchen und zu replizieren und sie zu ändern, um das 30-Grad-Winkelzucken zu erzeugen.

Um die Segmente, die sich nicht in einem Winkel von <30 Grad befinden, aus der Aggregation zu entfernen, müssen Sie sie INNERHALB einer Aggregationsschleife vergleichen.

rpcavaco
quelle