Shapely: Obtener el punto más cercano en la cadena de líneas

Creado en 18 oct. 2014  ·  3Comentarios  ·  Fuente: Toblerity/Shapely

Hola,
Dado un punto, estoy tratando de obtener el punto más cercano en una cadena lineal. Parece funcionar bien para una cadena de líneas simple, p. Ej.
Python 3.4.0 (predeterminado, 11 de abril de 2014, 13:05:11)
[GCC 4.8.2] en Linux
Escriba "ayuda", "derechos de autor", "créditos" o "licencia" para obtener más información.

desde shapely.geometry import Point, LineString
línea = LineString ([(0,0), (5,7), (12,6)])
p = Punto (4,8)
np = línea.interpolar (línea.proyecto (p))
imprimir (np)
PUNTO (5 7)

Sin embargo, para una cadena de líneas compleja no obtengo los resultados esperados.

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.12020308,72 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.123680,72.897623), (19.1270644011,72.89.72.897623) , (19.124483,72.896177), (19.124573,72.895796), (19.124585,72.895470), (19.124603,72.895014), (19.124652,72.894291), (19.124686,72.894067), (19.124929,72.894067), (19.124929,72.894067), (19.124929,72.82.895470) 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.890413), (19.126833,72.890413), (19.126833,72.890413), (19.126833,72.8988.12873), ( 72.886714), (19.129060,72.886402), (19.129109,72.886299), (19.129238,72.885913), (19.129302,72.885370), (19.129372,72.881686), (19.129396,72.880652), (19.129396,72.880652), (19.12.82980167,72. , (19.129382,72.880070), (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.125160,72.873014), (19.12482457), (197.172457), 772.87 ;

lista (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.899382058), (19.899382058), (19.119848, 72.899972) 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.19244048), (19.124644048) 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.1924966), (19.1924966) , (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.8 (1988.182873), 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.880652), (19.129413, 72.88029362), (19.129302), 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.17252536), (19.1725252) , 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), (1970.12571), 72 ), (19.119933, 72.870464), (19.119596, 72.870432)]

end = Punto (19.125150,72.893218)

np = ruta.interpolar (ruta.proyecto (final))

imprimir (np)
PUNTO (19.12493833590478 72.89314854771877)

Esperaba que el resultado fuera 19.124929, 72.893177. ¿Es algo que estoy haciendo mal? Cualquier ayuda apreciada.

¡Gracias!

Comentario más útil

El punto devuelto es el punto más cercano en la línea al punto original. El punto más cercano _no_ es necesariamente un vértice existente en LineString, y en este caso no lo es.

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

Si desea encontrar el vértice más cercano, primero debe convertir LineString a una geometría MultiPoint, luego use la operación nearest_points (tenga en cuenta el error menor de punto flotante):

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)

Esta consulta requiere calcular la distancia entre el punto original y cada vértice en la cadena de líneas original. Para rutas muy complejas, esto podría ser bastante lento. Si este es el caso, debería considerar usar el módulo rtree , que usa indexación espacial para hacer que este tipo de consulta sea muy rápida:

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

Todos 3 comentarios

El punto devuelto es el punto más cercano en la línea al punto original. El punto más cercano _no_ es necesariamente un vértice existente en LineString, y en este caso no lo es.

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

Si desea encontrar el vértice más cercano, primero debe convertir LineString a una geometría MultiPoint, luego use la operación nearest_points (tenga en cuenta el error menor de punto flotante):

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)

Esta consulta requiere calcular la distancia entre el punto original y cada vértice en la cadena de líneas original. Para rutas muy complejas, esto podría ser bastante lento. Si este es el caso, debería considerar usar el módulo rtree , que usa indexación espacial para hacer que este tipo de consulta sea muy rápida:

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

Oh ok Gracias por tu respuesta.

@snorfalorpagus . Estaba buscando algo como esto. ¿Alguna sugerencia inteligente para deshacerse del error de punto flotante? El mismo problema también existe con esta herramienta.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

mrocklin picture mrocklin  ·  12Comentarios

dashesy picture dashesy  ·  8Comentarios

LostFan123 picture LostFan123  ·  9Comentarios

sgillies picture sgillies  ·  14Comentarios

TheSy picture TheSy  ·  8Comentarios