0

I have a simple MultiLinestring and example points as follows:

from shapely.geometry import Point, MultiLineString
my_route = MultiLineString([
    [(24.142982, 54.329322), (24.142753, 54.328542)],
    [(24.142753, 54.328542), (24.142638, 54.327449)],
    [(24.142638, 54.327449), (24.142256, 54.325755)],
    [(24.142256, 54.325755), (24.141682, 54.323280)],
    [(24.141682, 54.323280), (24.141529, 54.322232)],
])

A = Point(24.143747, 54.329344)
B = Point(24.140764, 54.323414)

Note that my_route doesnt contains both of the points.

Now, I want to find a point A' belonging to the my_route that will be closest to point A, and a point B' that belongs to my_route and is closest to point B. I am trying to do that using interpolate method on my_route object:

nearest_point_A = my_route.interpolate(my_route.project(A))
nearest_point_B = my_route.interpolate(my_route.project(B))

If I print out the result, it turns out, that nearest_point_A has been found correctly, but the problem is with point nearest_point_B, because it doesn't belong to my_route:

print(nearest_point_A.coords[0])
print(nearest_point_B.coords[0])

You can even check if results points are on my_route using intersects method:

print(my_route.intersects(nearest_point_A))
print(my_route.intersects(nearest_point_B))

Could you tell me what I am doing wrong and why I can find only nearest_point_A, but nearest_point_B has been found not correct?

2
  • You want to find the nearest line vertex to point A and B? (not the coordinate on the line which is nearest to point A and B)
    – BERA
    Feb 28 at 17:47
  • I don't want to find vertex, just the two coordinates on the line which first is nearest to point A and second to B.
    – szaki
    Feb 28 at 17:55

1 Answer 1

0

You can use nearest_points:

Returns a tuple of the nearest points in the input geometries. The points are returned in the same order as the input geometries.

from shapely.geometry import Point, MultiLineString
from shapely.ops import nearest_points

my_route = MultiLineString([
    [(24.142982, 54.329322), (24.142753, 54.328542)],
    [(24.142753, 54.328542), (24.142638, 54.327449)],
    [(24.142638, 54.327449), (24.142256, 54.325755)],
    [(24.142256, 54.325755), (24.141682, 54.323280)],
    [(24.141682, 54.323280), (24.141529, 54.322232)],
])

A = Point(24.143747, 54.329344)
B = Point(24.140764, 54.323414)

nearest_point_A = nearest_points(my_route, A)[0]
nearest_point_B = nearest_points(my_route, B)[0]

for p in [nearest_point_A, nearest_point_B]:
    print(p.wkt)

#POINT (24.142982 54.329322)
#POINT (24.141681996999232 54.32327997944572)

enter image description here

3
  • Note that #POINT (24.141681996999232 54.32327997944572) isn't on the line. you can chceck that using print(my_route.intersects(nearest_point_B)) - it returns False
    – szaki
    Feb 28 at 18:00
  • I believe it is a "floating point error". nearest_point_B.distance(my_route) #4.226324459710306e-16
    – BERA
    Feb 28 at 18:04
  • Which means it is on the line
    – BERA
    Feb 28 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.