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!
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:
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.
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.
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):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