Ich möchte den Winkel zwischen zwei Linien berechnen, in denen sie sich in PostGIS schneiden.
Der Ausgangspunkt für Winkelberechnungen in PostGIS scheint ST_Azimuth zu sein - aber dafür werden Punkte als Eingabe verwendet. Mein erster Gedanke war, die Endpunkte der Schnittlinien zu nehmen und eine Azimutberechnung an diesen durchzuführen. Das ist nicht gut genug, da die meisten Linienmerkmale nicht gerade sind und mich der Winkel am Schnittpunkt interessiert. Ich habe mir also eine verschachtelte Operation ausgedacht, die folgende Schritte durchläuft:
- Identifizieren Sie alle Schnittpunkte zwischen den beiden Linien-Feature-Tabellen.
- Erstellen Sie einen sehr kleinen Puffer um den Schnittpunkt
- Identifizieren Sie die Punkte, an denen die Linienmerkmale die Pufferaußenseite schneiden (nehmen Sie den ersten Punkt, wenn es mehr als einen gibt - es interessiert mich wirklich nur, ob der Winkel in der Nähe von 0, 90 oder 180 Grad liegt).
- Berechnen Sie ST_Azimuth für diese beiden Punkte.
Das vollständige SQL ist ein bisschen lang, um es hier zu veröffentlichen, aber ich habe es hier aufgelistet, wenn Sie interessiert sind. (Übrigens, gibt es einen besseren Weg, als alle Felder der WITH-Anweisungen zu übernehmen?)
Die Ergebnisse sehen nicht richtig aus, also mache ich eindeutig etwas falsch:
BEARBEITEN Ich habe die Berechnungen in EPSG: 3785 überarbeitet und die Ergebnisse sind etwas anders, aber immer noch nicht richtig:
Meine Frage ist, wo die Mängel in diesem Prozess liegen. Verstehe ich falsch, was ST_Azimuth tut? Gibt es ein CRS-Problem? Sonst noch was? Oder gibt es einen viel einfacheren Weg, dies zu tun?
Antworten:
Ich hatte die Offenbarung. Es ist ziemlich banal. Ich habe eine wichtige Information für PostGIS ausgelassen, um den richtigen Winkel zu berechnen.
Was ich berechnet habe, war der Winkel zwischen nur den zwei Punkten, die das kleine Pufferäußere schneiden. Um den Schnittwinkel zu berechnen, muss ich beide Winkel zwischen den beiden Punkten auf der Pufferaußenseite und dem Schnittpunkt der beiden Linienmerkmale berechnen und diese subtrahieren.
Ich habe die vollständige SQL aktualisiert , aber hier ist das Wesentliche:
quelle
ST_IntersectionAngle(...
?Ich musste kürzlich dasselbe berechnen, entschied mich jedoch für einen einfacheren und wahrscheinlich schnelleren Ansatz.
Um die zusätzlichen Punkte für die Azimutberechnung zu finden, überprüfe ich einfach mit ST_Line_Locate_Point und ST_Line_Interpolate_Point eine Permyriade der Länge hinter dem Schnittpunkt (oder in dem seltenen Fall, dass sie ganz am Anfang der Linie auftritt) :
Die Permyriade war willkürlich und für konsistentere Ergebnisse wäre es besser, einen absoluten Offset zu verwenden. Um 20m Beispiel Scheck im Voraus, dann würden Sie 0,0001 ändern
20/ST_Length(line1)
und20/ST_Length(line2)
jeweils.quelle