Polygonlänge entlang einer Linie berechnen?


8

Ich muss die Länge von Polygonen entlang / projiziert auf eine Linie berechnen. Ein Bild, um die Idee zu zeigen:

Geben Sie hier die Bildbeschreibung ein

Ich habe Tausende von Polygonen, die auf Linien "projiziert" werden müssen, um zu überprüfen, zu wie vielen Metern der Linie sie gehören. Die Polygone sind unregelmäßig, mit unterschiedlicher Ausrichtung, ein Teil von ihnen schneidet die Linie, ein Teil von ihnen nicht.

Ich habe es versucht:

  1. Suchen Sie Features in ArcGIS Pro entlang des Linienwerkzeugs , es wird jedoch nur die Linienlänge für überlappende Teile eines Polygons angegeben (Werkzeugbeschreibung hier ESRI-Hilfe )

  2. Minimale Begrenzungsgeometrie mit der Option 'Konvexer Rumpf', gibt jedoch nur den Abstand zwischen den Antipodenpunkten eines Polygons an, der nicht parallel zur Linie my ist (Werkzeugbeschreibung hier ESRI-Hilfe)

Vermisse ich ein Tool dafür in ArcGIS oder QGIS? Hätten Sie eine Lösung dafür?


Ist Ihre Linie eine gerade Linie?
JiyuuSensei

Da Sie eine eindeutige Anforderung haben, erscheint es nicht unangemessen, dass ein solches Tool nicht vorhanden ist. Sie könnten ein solches Tool sicherlich mit Triggerfunktionen und verschiedenen Geometrie-Hilfsfunktionen codieren, aber zuerst müssen Sie eine Softwareplattform auswählen.
Vince

@JiyuuSensei nein, eigentlich ist es ein Polyliniennetz - wie ein Straßennetz oder ein Pipelinenetz. Dies sollte also so funktionieren, als würde man diese "Polygonlänge" für das nächstgelegene Liniensegment des Netzwerks berechnen. Es ist also im Grunde die Idee, wie das Suchen von Features entlang des Linienwerkzeugs funktioniert.
Konrad Gje

Antworten:


7

Verwenden von QGIS:

(1) Erstellen Sie die Punktebene der Polygonscheitelpunkte mit dem Werkzeug Scheitelpunkte extrahieren (in der QGIS-Verarbeitungs-Toolbox> Vektorgeometrie).

Geben Sie hier die Bildbeschreibung ein

(2) Öffnen Sie die Attributtabelle der neu erstellten Vertices- Ebene.

(3) Starten Sie den Feldrechner und;

(3A) Erstellen Sie ein neues Feld. Nennen wir es min_poly , um den Mindestabstand zu speichern und einen Ausdruck anzugeben :

minimum(
 line_locate_point(
  geometry:=geometry(get_feature_by_id('Lines', '1')), point:=$geometry), 
 group_by:="fid")

NB: Sie müssen zu 'Lines'Ihrem tatsächlichen Zeilenlayernamen und '1'zu der Zeilen-ID wechseln, die Sie in Ihrer Attributtabelle haben.

(3B) Erstellen Sie ein weiteres neues Feld. Nennen wir es max_poly , um die maximale Entfernung zu speichern und einen Ausdruck zu geben:

maximum(
 line_locate_point(
  geometry:=geometry(get_feature_by_id('Lines', '1')), point:=$geometry), 
 group_by:="fid")

Geben Sie hier die Bildbeschreibung ein

Da der Vertices- Layer das FID- Feld von den ursprünglichen Polygon-IDs fernhält , finden Sie min_poly und max_poly ist der minimale / maximale Abstand entlang der Linie für jedes Polygon.

(Das obige Beispiel zeigt, dass das erste Polygon fid = 1 von 8,688 bis 24,45 reicht, während das zweite Polygon fid = 2 von 35,062 bis 42,496 reicht.)


5

Ich weiß nicht, wie es mit QGIS oder ArcGIS geht, aber was Sie wollen, fühlt sich an wie die Breite eines orientierten Begrenzungsrahmens. Als Proof of Concept habe ich Ihr Beispielbild so gedreht, dass die Projektionslinie horizontal ist.

Geben Sie hier die Bildbeschreibung ein

Dann habe ich die Polygone aus dem Bild digitalisiert und Umschläge für sie generiert. Die Breite des Umschlags beantwortet Ihre Frage.

Geben Sie hier die Bildbeschreibung ein

Was fehlt, ist ein Werkzeug, das einen Begrenzungsrahmen in einem bestimmten Winkel erstellt. QGIS verfügt zwar über ein Werkzeug für orientierte Mindestbegrenzungsrahmen, der Benutzer kann jedoch keinen festen Winkel dafür angeben. Wahrscheinlich könnten Sie die PostGIS-Lösung aus der akzeptierten Antwort auf diese Frage übernehmen. Erstellen eines "schrägen Begrenzungsrahmens" mit maximalem Verhältnis von Breite zu Höhe? .


Diese Antwort wäre der beste Ansatz, da es sehr einfach ist, einen orientierten Begrenzungsrahmen in QGIS zu erhalten (mit Breite und Höhe des Umschlags), aber zwei Seiten dieses orientierten Begrenzungsrahmens müssen notwendigerweise Parallelen zur Referenzlinie sein, und diese Bedingung ist nicht garantiert . Dies ist das Problem bei unregelmäßigen Polygonen.
Xunilk

2

Basierend auf der Antwort von @ kazuhito habe ich im QGIS-Feldrechner einen einzelnen, hackigen Ausdruck zusammengestellt, der in einem Schritt dasselbe tun sollte.

Ich kann mir jedoch vorstellen, dass dies bei größeren Datensätzen sehr ressourcenintensiv sein wird. Ich denke, das Problem eignet sich am besten für eine Python-Implementierung, die Referenzierung und Iteration offensichtlich weitaus besser handhabt als der Feldrechner.

array_last(array_sort(array_foreach(
generate_series(1,num_points($geometry)-1),
line_locate_point(aggregate('lines','collect',$geometry),
point_n($geometry,@element))),1)) 
- array_first(array_sort(array_foreach(
generate_series(1,num_points($geometry)-1),
line_locate_point(aggregate('lines','collect',$geometry),
point_n($geometry,@element))),1))

Dadurch wird zunächst ein 'Array' von Knotennummern erstellt generate_series(), wobei das Maximum als Anzahl der Knoten in jedem Polygon angegeben wird. Dies ist num_points($geometry)minus 1, um den wiederholten ersten / letzten Knoten zu überspringen.

Sie können dann die Werte dieses Arrays durch eine Funktion übergeben, um mit ein anderes Array zu generieren array_foreach(). Hier übergeben wir die Polygonknotennummer (dargestellt als @element) an point_n(), die die tatsächliche Geometrie dieses Knotens zurückgibt, und geben diese ein line_locate_point(), um seine Länge entlang der angegebenen Linie zu bestimmen (siehe Wichtiger Hinweis unten).

Das resultierende Array wird dann in aufsteigender Reihenfolge sortiert mit array_sort()der dann läßt uns die „ganz links“ und „ganz rechts“ Abstände entlang der Linie erhalten mit array_last()und array_first(). Subtrahieren Sie die beiden und das Ergebnis ist die "Länge" des Polygons entlang der Linie.

Unten finden Sie ein Beispiel für den obigen Ausdruck, der in den Polygonen als Beschriftung angezeigt wird (plus Linienabstände "ganz links" und "ganz rechts", die vom obigen Ausdruck getrennt sind). Zum Vergleich habe ich auch extrahierte Eckpunkte und relevante Linienabstandswerte aufgenommen. Grüne Scheitelpunkte sind die Scheitelpunkte "ganz links" und "ganz rechts" entlang der Linie. Beachten Sie das Polygon oben links, bei dem der grüne Punkt aufgrund des Winkels der Linie tatsächlich weiter entlang der Linie liegt als der Punkt rechts darunter ...

Wichtiger Hinweis :

Auf die Linienebenengeometrie wird hier mit verwiesen aggregate(). Sie müssen den Ebenennamen ( 'lines') nach Bedarf ändern. Wenn Sie mehrere Zeilen haben, sollten Sie einen Filter hinzufügen, um anzugeben, mit welcher Zeile Sie ihn vergleichen möchten, z aggregate('lines','collect',$geometry,"name"='TrainLine1'). Damit dies automatisch in der nächsten Zeile funktioniert, empfehle ich SQL oder Python gegenüber Field Calc.

Außerdem wird die "Länge" des Polygons entlang der Linie berechnet, einschließlich der Frage, ob die Linie gemäß meinem Beispiel geknickt ist. Wenn Sie den geradlinigen Abstand wollen ... berechnen Sie vielleicht den Abstand distance()zwischen den relevanten Knoten?

Geben Sie hier die Bildbeschreibung ein


1

Der beste Ansatz in QGIS, um dies zu erreichen (unter Berücksichtigung von Tausenden von Polygonen, die auf eine Referenzlinie "projiziert" werden sollen), besteht darin, den Begrenzungsrahmen zu bestimmen, der um den Winkel zwischen Referenzlinie und X-Achse gedreht wird. Dieser Winkel kann mithilfe des Werkzeugs "Scheitelpunkte extrahieren" (in der QGIS-Verarbeitungs-Toolbox -> Vektorgeometrie) als Referenzlinie leicht bestimmt werden. Aus dem Beispiel des folgenden Bildes wird der erforderliche Winkel mit dem Wert in der Attributtabelle der Vertices- Ebene unter Verwendung dieser Formel bestimmt:

90 - 63.91873763467915 = 26.081262365320853 Grad.

Geben Sie hier die Bildbeschreibung ein

Einführung des obigen Winkels in das Werkzeug "Drehen" der Verarbeitungs-Toolbox und Ausführen:

Geben Sie hier die Bildbeschreibung ein

Es wird eine gedrehte Ebene erzeugt, deren Begrenzungsrahmen in ihrer Attributtabelle die Länge des auf die Referenzlinie projizierten Polygons enthält. Es kann schließlich beobachtet werden, indem dieses Tool der Processing Toolbox ausgeführt wird:

Geben Sie hier die Bildbeschreibung ein

Im folgenden Bild entspricht die Länge des auf eine Linie projizierten Polygons dem Wert in der Feldbreite .

Geben Sie hier die Bildbeschreibung ein

Bei der folgenden Abbildung ist zu erkennen, dass die projizierte Länge des betrachteten Polygons erwartungsgemäß ist, da die um 26,081262365320853 Grad gedrehte Referenzlinie (erhalten mit dem Drehwerkzeug der Verarbeitungs-Toolbox) parallel zur X-Achse verläuft.

Geben Sie hier die Bildbeschreibung ein

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.