There is a polyline with a list of coordinates of the vertices = [(x1,y1), (x2,y2), (x3,y3),...] and a point(x,y). In Shapely, geometry1.distance(geometry2)
returns the shortest distance between the two geometries.
>>> from shapely.geometry import LineString, Point >>> line = LineString([(0, 0), (5, 7), (12, 6)]) # geometry2 >>> list(line.coords) [(0.0, 0.0), (5.0, 7.0), (12.0, 6.0)] >>> p = Point(4,8) # geometry1 >>> list(p.coords) [(4.0, 8.0)] >>> p.distance(line) 1.4142135623730951
But I also need to find the coordinate of the point on the line that is closest to the point(x,y). In the example above, this is the coordinate of the point on the LineString
object that is 1.4142135623730951 unit distant from Point(4,8)
. The method distance()
should have the coordinates when calculating the distance. Is there any way to get it returned from this method?
The basic algorithm is to check every segment of the polygon and find the closest point for it. This will either be the perpedicular point (if it is on the segment) or one of the endpoints. After doing this for all segments, pick the point with the smallest total difference.
Hint: The closest distance from point to line is on the line perpendicular to the first line through that point. Therefore, the perpendicular line has a reciprocal, opposite slope. The opposite of -1/2 is 1/2, and the reciprocal of 1/2 is 2. Therefore, the perpendicular line you are constructing has a slope of 2.
Shapely is an offshoot of the GIS-Python project that provides spatial geometry functions independent of any geo-enabled database. In particular, it makes python point-in-polygon calculations very easy.
The GIS term you are describing is linear referencing, and Shapely has these methods.
# Length along line that is closest to the point print(line.project(p)) # Now combine with interpolated point on line p2 = line.interpolate(line.project(p)) print(p2) # POINT (5 7)
An alternative method is to use nearest_points
:
from shapely.ops import nearest_points p2 = nearest_points(line, p)[0] print(p2) # POINT (5 7)
which provides the same answer as the linear referencing technique does, but can determine the nearest pair of points from more complicated geometry inputs, like two polygons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With