Wie erreiche ich den nächsten Punkt auf einer Linienfolge zu einem bestimmten Punkt?

28

Ich benutze PostGIS schon lange, musste aber nie die LINESTRINGGeometrie verwenden ...! :)

Folgendes möchte ich tun: Ich habe eine Tabelle mit Linienfolgen (die Straßen einer bestimmten Stadt darstellen, SRID 3395) und möchte die nächsten Linienfolgen zu einem bestimmten Punkt finden (GPS-Position, SRID 4326).

Die Lösung, die ich gefunden habe, besteht darin, alle Linienfolgen in meinem Punkt mithilfe der expand()Methode auszuwählen und den Abstand zwischen den einzelnen Linienfolgen und meinem Punkt mithilfe der ST_Distance()Methode zu bestimmen .

Hier ist die SQL:

SELECT myLineId, myLineName, ST_Distance(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395),myLineGeom) AS myLineDistance
FROM myLines
WHERE myLineGeom && expand(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395), 100)
ORDER BY myLineDistance;

Die Ergebnisse sehen gut aus, aber ich habe das Gefühl, dass etwas in meiner Implementierung nicht stimmt.

1) Glaubt ihr, dass die expand()alle betroffenen Linestrings bekommen können?

2) Glaubt ihr, das ST_Distance()ist die richtige Methode? Ich denke, ich mache es falsch, da die Entfernung, die ich erhalten möchte, die kleinste Entfernung zwischen dem Punkt und meiner Linie ist und nicht die Entfernung zwischen dem Punkt und einem der Punkte der Linienfolge.

Illustration:

Alt-Text

Vivi
quelle

Antworten:

11

ad 1) In der Dokumentation Ihrer verwendeten Funktionen würde ich sagen: "Ja, alle betroffenen Linestrings werden gefunden."

expandieren (Geometrie, float)

Diese Funktion gibt einen in alle Richtungen erweiterten Begrenzungsrahmen aus dem Begrenzungsrahmen der Eingabegeometrie um einen im zweiten Argument angegebenen Betrag zurück. Sehr nützlich für distance () - Abfragen, um der Abfrage einen Indexfilter hinzuzufügen.

A && B

Der Operator "&&" ist der Operator "Überlappung". Wenn der Begrenzungsrahmen von A den Begrenzungsrahmen von B überlappt, gibt der Operator true zurück.

ad 2) Sie sollten in der Lage sein, das zu erreichen, was Sie wollen:

line_interpolate_point(linestring, line_locate_point(LineString, Point))

line_interpolate_point (linestring, location)

Interpoliert einen Punkt entlang einer Linie. Das erste Argument muss ein LINESTRING sein. Das zweite Argument ist ein float8 zwischen 0 und 1, der den Bruchteil der gesamten 2D-Länge darstellt, an der der Punkt lokalisiert werden muss.

line_locate_point (LineString, Point)

Gibt einen Gleitkommawert zwischen 0 und 1 zurück, der die Position des nächstgelegenen Punkts in LineString zu dem angegebenen Punkt als Bruchteil der gesamten 2D-Linienlänge darstellt. Sie können den zurückgegebenen Speicherort verwenden, um einen Punkt zu extrahieren (line_interpolate_point).

Quelle: http://main.merlin.com.ua/doc/postgis/docs/ch06.html

Underdunkel
quelle
Für Punkt 2) habe ich mich nur gefragt, ob ST_Distance zwischen einer POINT-Geometrie und einer LINESTRING-Geometrie den kleinstmöglichen Abstand zwischen diesen Thesen ergibt (auch bekannt als die Länge der senkrechten Linie zwischen POINT und LINGESTRING). Ich möchte Abstand von jeder LINESTRING Geometrie :)
Vivi
Und ich denke, es ist nicht die Entfernung, die ich suche, da "die line_locate_point-Funktion Ihnen einen Wert zwischen 0 und 1 gibt, der die Position des nächstgelegenen Punkts auf LineString zu dem angegebenen Punkt darstellt": /
Vivi
Ich fürchte, Sie haben mich in Ihrem letzten Kommentar verloren. Jetzt bin ich mir nicht mehr sicher, was du willst;)
Underdunkel
1
Entschuldigung :) Ich würde dies gerne tun: Wenn ich eine LINESTRING-Geometrie (die einen Pfad darstellt) und eine POINT-Geometrie gebe, möchte ich die nächstgelegene POINT-Geometrie auf dem Pfad haben (die möglicherweise kein Punkt der LINESTRING-Geometriedefinition ist). Ist das klar? Vielleicht sollte ich meinen Beitrag mit einer Zeichnung aktualisieren: D
Vivi
Ich kann meinen Beitrag nicht aktualisieren. Hier ist ein Link zu einer Zeichnung, die ich erhalten möchte: i.imgur.com/UwPxo.jpg
Vivi
7

Hallo

Zuerst die Frage, was ST_Distance zurückgibt. ST_Distance gibt den kürzesten Abstand zwischen der Linie und dem Punkt zurück (oder welche Geometrietypen eingegeben werden). Dies bedeutet, dass ST_Distance zwischen Punkt (1 3) und Linienfolge (0 0,0 10) 1 zurückgibt. Der Abstand zwischen wird nicht gemessen Punkt und (0 0) oder Punkt und (0 10), aber von Punkt (1 3) bis (0 3).

Soweit ich weiß, gibt Ihnen ST_Distance die gewünschte Antwort.

Wenn Sie den Punkt (0 3) im obigen Beispiel finden möchten, können Sie ST_Closestpoint verwenden, wenn Sie PostGIS 1.5 haben. In meinem Beispiel verwenden Sie ihn wie folgt: ST_Closestpoint ('LINESTRING (0 0,0 10)' :: geometry, ' POINT (1 3) ':: geometry), dann sollten Sie den Punkt (0 3) zurückgeben, den Punkt auf der Linie, der Ihrem Punkt am nächsten liegt.

HTH Nicklas

Nicklas Avén
quelle
5

Ich habe es gefunden :) (Nun, ich denke: P)

Mit ST_Line_Locate_Point()und habe ST_Line_Interpolate_point()ich es geschafft, einen Punkt zu erhalten, der NICHT Teil der LINESTRING-Definition ist, sondern auf der besagten Linie.

SELECT AsText(ST_Line_Interpolate_Point(myLineGeom,ST_Line_Locate_Point(myLineGeom,ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395))))
FROM myLines
WHERE myGeom && expand(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395), 100)

Die ST_Line_Locate_Point()Methode ermittelt die Position des nächstgelegenen Punkts auf der Linie zu dem angegebenen Punkt. Die ST_Line_Interpolate_PointMethode wandelt diese Position in einen Punkt um.

Vivi
quelle
1
St_distance zwischen dem Punkt und der Linie gibt Ihnen die gleiche Antwort. Warum denkst du, musst du das so machen?
Nicklas Avén
1
Ich denke, ST_Distance kann mit jedem Geometrietyp verwendet werden. postgis.refractions.net/docs/ST_Distance.html :ST_Distance(geometry g1, geometry g2)
Magno C
2

Dieser Postgis-Archiv-Thread kann Ihnen antworten: http://postgis.refractions.net/pipermail/postgis-users/2007-June/016045.html

ThomasG77
quelle
refractions.net funktioniert bei mir nicht: "refractions.net ist am 14.09.2010 abgelaufen und muss noch erneuert oder gelöscht werden."
underdark
@underdark es funktioniert für mich
dassouki
@dassouki: das ist komisch: |
Underdunkel
@underdark refractions.net arbeiten wieder
ThomasG77