假设我有以下多边形和点:
>>> poly = Polygon([(0, 0), (2, 8), (14, 10), (6, 1)])
>>> point = Point(12, 4)
我可以计算该点到多边形的距离...
>>> dist = point.distance(poly)
>>> print(dist)
2.49136439561
...但我想知道最短距离测量到的多边形边界上的点的坐标。
我最初的方法是通过点到多边形的距离来缓冲该点,并找到该圆与多边形相切的点:
>>> buff = point.buffer(dist)
list(poly.intersection(buff))
不会给我那个点。
我的方向正确吗?有没有更简单的方法?
虽然 eguaio 的答案可以完成这项工作,但有一种更自然的方法可以使用
shapely.ops.nearest_points
函数来获取最近的点:
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)
结果与其他答案相同:
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
请不要对这个答案进行投票,正确的答案是下面@Georgy 的答案。
我的回答供参考:
有一种简单的方法可以依靠 Shapely 函数来做到这一点。 首先,您需要获取多边形的外环并将点投影到环上。由于多边形,必须将外部设置为
LinearRing
不具备投影功能。与直觉相反,这给出了一个距离,即从环的第一个点到环中最接近给定点的点的距离。然后,您只需使用该距离即可通过插值函数获取点。请参阅下面的代码。
from shapely.geometry import Polygon, Point, LinearRing
poly = Polygon([(0, 0), (2,8), (14, 10), (6, 1)])
point = Point(12, 4)
pol_ext = LinearRing(poly.exterior.coords)
d = pol_ext.project(point)
p = pol_ext.interpolate(d)
closest_point_coords = list(p.coords)[0]
值得一提的是,只有当您知道该点位于多边形外部之外时,此方法才有效。如果该点位于其内环之一内,则需要针对这种情况调整代码。
如果多边形没有内环,则即使对于多边形内部的点,代码也将起作用。这是因为我们实际上将外环视为线串,并忽略线串是否来自多边形。
很容易将此代码扩展到计算任意点(多边形内部或外部)到多边形边界中最近点的距离的一般情况。您只需要计算从该点到所有线环的最近点(和距离):外环和多边形的每个内环。然后,您只需保留其中的最小值即可。
我喜欢将多边形poly与以点point为中心的圆buff相交的想法,就像您在问题中所写的那样。我建议:
poly.boundary.intersection(buff.boundary)
正如@SoHei的评论所指出的,如果该点位于多边形内部,则必须利用多边形的边界,否则
shapely
将返回该点本身作为最近点。这是代码:
poly = Polygon([(0, 0), (2, 8), (14, 10), (6, 1)])
point = Point(4, 2)
boundary = poly.boundary
nearest_point = nearest_points(point, boundary)[1]
print(nearest_point.wkt)
# POINT (4.216216216216216 0.7027027027027026)