Say I have the following Polygon and Point:
>>> poly = Polygon([(0, 0), (2, 8), (14, 10), (6, 1)]) >>> point = Point(12, 4)
I can calculate the point's distance to the polygon...
>>> dist = point.distance(poly) >>> print(dist) 2.49136439561
...but I would like to know the coordinate of the point on the polygon border where that shortest distance measures to.
My initial approach is to buffer the point by its distance to the polygon, and find the point at which that circle is tangent to the polygon:
>>> buff = point.buffer(dist)
However, I'm not sure how to calculate that point. The two polygon's don't intersect so list(poly.intersection(buff))
will not give me that point.
Am I on the right track with this? Is there a more straightforward 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.
The closest pair is the minimum of the closest pairs within each half and the closest pair between the two halves. To split the point set in two, we find the x-median of the points and use that as a pivot. Finding the closest pair of points in each half is subproblem that is solved recursively.
Shapely is a Python package for set-theoretic analysis and manipulation of planar features using (via Python's ctypes module) functions from the well known and widely deployed GEOS library. GEOS, a port of the Java Topology Suite (JTS), is the geometry engine of the PostGIS spatial extension for the PostgreSQL RDBMS.
Shapely is a BSD-licensed Python package for manipulation and analysis of planar geometric objects. It is based on the widely deployed GEOS (the engine of PostGIS) and JTS (from which GEOS is ported) libraries.
While the answer of eguaio does the job, there is a more natural way to get the closest point using shapely.ops.nearest_points
function:
from shapely.geometry import Point, Polygon from shapely.ops import nearest_points poly = Polygon([(0, 0), (2, 8), (14, 10), (6, 1)]) point = Point(12, 4) # The points are returned in the same order as the input geometries: p1, p2 = nearest_points(poly, point) print(p1.wkt) # POINT (10.13793103448276 5.655172413793103)
The result is the same as in the other answer:
from shapely.geometry import LinearRing pol_ext = LinearRing(poly.exterior.coords) d = pol_ext.project(point) p = pol_ext.interpolate(d) print(p.wkt) # POINT (10.13793103448276 5.655172413793103) print(p.equals(p1)) # True
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