Shapely: Holen Sie sich den nächsten Punkt auf der Linienfolge

Erstellt am 18. Okt. 2014  ·  3Kommentare  ·  Quelle: Toblerity/Shapely

Hallo,
Bei einem gegebenen Punkt versuche ich, den nächsten Punkt auf einer Linienfolge zu erhalten. Es scheint gut zu funktionieren für eine einfache Linienfolge, zB
Python 3.4.0 (Standard, 11. April 2014, 13:05:11)
[GCC 4.8.2] unter Linux
Geben Sie "Hilfe", "Copyright", "Credits" oder "Lizenz" ein, um weitere Informationen zu erhalten.

from shapely.geometry import Point, LineString
line = LineString([(0,0),(5,7),(12,6)])
p = Punkt(4,8)
np = line.interpolate(line.project(p))
drucken (np)
PUNKT (5 7)

Für eine komplexe Linienfolge erhalte ich jedoch nicht die beabsichtigten Ergebnisse

route=LineString([(19.119318,72.902800),(19.119660,72.901455),(19.119673,72.901401),(19.119848,72.900553),(19.119975,72.899972),(19.120129,72.899675),(19.120308,72.899385),(19.120589, 72.899162),(19.121131,72.898909),(19.121597,72.898739),(19.122330,72.898471),(19.122696,72.898429),(19.123296,72.897991),(19.123680,72.897623),(19.124095.72.897035),(19.12644102,72.89644102,72.89644102) ( 19.125097.72.892666),(19.125214.72.892323),(19.125450,72.891802),(19.125757.72.891281),(19.125951.72.890874),(19.126170,72.890413),(19.126833,72.889417),(19.127319,19.88812893), 72.886714) ,(19.129382,72.880070),(19.129419,72.879849),(19.129509,72.879205),(19.129709,72. 877766) ,(19.123149,72.871568),(19.122517,72.871091),(19.122162,72.870822),(19.121981,72.870749),(19.121736,72.870651),(19.121013,72.870576),(19.119933,72.870464),(19.119596,72.870432)

list(route.coords)
[(19.119318, 72.9028), (19.11966, 72.901455), (19.119673, 72.901401), (19.119848, 72.900553), (19.119975, 72.899972), (19.120129, 72.899675), (19.120308, 72.899385), (19.120589, 72.899162), ( 19.121131, 72.898909), (19.121597, 72.898739), (19.12233, 72.898471), (19.122696, 72.898429), (19.123296, 72.897991), (19.12368, 72.897623), (19.124095, 72.897035), (19.124402, 72.896411, (19.1244) 72.896177), (19.124573, 72.895796), (19.124585, 72.89547), (19.124603, 72.895014), (19.124652, 72.894291), (19.124686, 72.894067), (19.124929, 72.893177), (19.124971, 72.893049), (19.125097, 72.892666) , (19.125214, 72.892323), (19.12545, 72.891802), (19.125757, 72.891281), (19.125951, 72.890874), (19.12617, 72.890413), (19.126833, 72.889417), (19.127319, 72.888873), (19.128909, 72.886714), ( 19.12906, 72.886402), (19.129109, 72.886299), (19.129238, 72.885913), (19.129302, 72.88537), (19.129372, 72.881686), (19.129396, 72.880652), (19.129413, 72.88054), (19.129366, 72.880167), (19.129382, 72.88007), (19 .129419, 72.879849), (19.129509, 72.879205), (19.129709, 72.877766), (19.129969, 72.876684), (19.130029, 72.876511), (19.128367, 72.875341), (19.127365, 72.874602), (19.125882, 72.873536), (19.12516 , 72.873014), (19.124815, 72.872761), (19.124413, 72.872457), (19.123149, 72.871568), (19.122517, 72.871091), (19.122162, 72.870822), (19.121981, 72.870749), (19.121736, 72.870651), (19.12057613, 72 ), (19.119933, 72.870464), (19.119596, 72.870432)]

Ende=Punkt(19.125150,72.893218)

np = route.interpolate(route.project(end))

drucken (np)
PUNKT (19.12493833590478 72.89314854771877)

Ich hatte erwartet, dass das Ergebnis 19.124929, 72.893177 lautet. Ist es etwas, was ich falsch mache? Jede Hilfe geschätzt.

Vielen Dank!

Hilfreichster Kommentar

Der zurückgegebene Punkt ist der dem ursprünglichen Punkt am nächsten liegende Punkt auf der Linie. Der nächste Punkt ist _nicht_ notwendigerweise ein vorhandener Scheitelpunkt im LineString, und in diesem Fall ist er es nicht.

end = Point(19.125150,72.893218)
np = Point(19.12493833590478, 72.89314854771877)
expected = Point(19.124929, 72.893177)

print end.distance(np) # 0.000222767386696
print end.distance(expected) # 0.000224770994572

Wenn Sie den nächsten Scheitelpunkt finden möchten, sollten Sie zuerst den LineString in eine MultiPoint-Geometrie konvertieren und dann die Operation nearest_points verwenden (beachten Sie den geringfügigen Gleitkommafehler):

from shapely.ops import nearest_points
from shapely.geometry import MultiPoint
mp = MultiPoint(route)
print nearest_points(mp, end)[0] # POINT (19.124929 72.89317699999999)

Diese Abfrage erfordert die Berechnung des Abstands zwischen dem ursprünglichen Punkt und jedem Scheitelpunkt in der ursprünglichen Linienfolge. Bei sehr komplexen Routen kann dies eher langsam sein. Wenn dies der Fall ist, sollten Sie das Modul rtree Betracht ziehen, das räumliche Indizierung verwendet, um diese Art von Abfrage sehr schnell zu machen:

http://toblerity.org/rtree/tutorial.html

Alle 3 Kommentare

Der zurückgegebene Punkt ist der dem ursprünglichen Punkt am nächsten liegende Punkt auf der Linie. Der nächste Punkt ist _nicht_ notwendigerweise ein vorhandener Scheitelpunkt im LineString, und in diesem Fall ist er es nicht.

end = Point(19.125150,72.893218)
np = Point(19.12493833590478, 72.89314854771877)
expected = Point(19.124929, 72.893177)

print end.distance(np) # 0.000222767386696
print end.distance(expected) # 0.000224770994572

Wenn Sie den nächsten Scheitelpunkt finden möchten, sollten Sie zuerst den LineString in eine MultiPoint-Geometrie konvertieren und dann die Operation nearest_points verwenden (beachten Sie den geringfügigen Gleitkommafehler):

from shapely.ops import nearest_points
from shapely.geometry import MultiPoint
mp = MultiPoint(route)
print nearest_points(mp, end)[0] # POINT (19.124929 72.89317699999999)

Diese Abfrage erfordert die Berechnung des Abstands zwischen dem ursprünglichen Punkt und jedem Scheitelpunkt in der ursprünglichen Linienfolge. Bei sehr komplexen Routen kann dies eher langsam sein. Wenn dies der Fall ist, sollten Sie das Modul rtree Betracht ziehen, das räumliche Indizierung verwendet, um diese Art von Abfrage sehr schnell zu machen:

http://toblerity.org/rtree/tutorial.html

Ah okay Danke für deine Antwort.

@snorfalorpagus . Ich habe nach so etwas gesucht. irgendwelche klugen Vorschläge, um den Gleitkommafehler loszuwerden? Das gleiche Problem besteht auch bei diesem Tool.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

ispmarin picture ispmarin  ·  3Kommentare

LostFan123 picture LostFan123  ·  5Kommentare

kannes picture kannes  ·  4Kommentare

doctor-ian picture doctor-ian  ·  4Kommentare

mikedh picture mikedh  ·  6Kommentare