Python 按形状查找多边形上最近点的坐标

Python 按形状查找多边形上最近点的坐标,python,shapely,Python,Shapely,假设我有以下多边形和点: >>> poly = Polygon([(0, 0), (2, 8), (14, 10), (6, 1)]) >>> point = Point(12, 4) 我可以计算点到多边形的距离 >>> dist = point.distance(poly) >>> print(dist) 2.49136439561 …但我想知道多边形边界上最短距离测量到的点的坐标 我的初始方法是按点到多边形的距离缓

假设我有以下多边形和点:

>>> 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) 
然而,我不知道如何计算这一点。两个多边形不相交,因此
列表(poly.intersection(buff))
不会给出该点


我做得对吗?有更直接的方法吗?

有两种情况需要考虑:(1)最近点位于边上,(2)最近点是顶点。案例(2)很容易检查-只需计算到每个顶点的距离并找到最小值。案例(1)涉及更多的数学知识,但仍然不算太糟糕。对于情况(1),您需要做两件事:(a)找到从点到边的法线与边相交的位置,以及(b)验证它是否位于线段内(而不是延伸超过一个端点)。如果它不在线段上,则忽略它(其中一个顶点将是该边上最近的点)。

请不要向上投票此答案,正确答案是下面@Georgy的答案

我的答覆供参考:

有一种简单的方法可以依靠Shapely函数来实现这一点。 首先,需要获取多边形的外环,并将点投影到环上。必须将外部作为
线性化
多边形获取 没有投影功能。与直觉相反,这给出了一个距离,从环的第一个点到环中最靠近给定点的点的距离。然后,您只需使用该距离通过插值函数获得点。请参阅下面的代码

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]
必须指出的是,只有当您知道该点位于多边形外部时,此方法才有效。如果该点位于其一个内环内,则需要根据该情况调整代码

如果多边形没有内环,则该代码甚至适用于多边形内的点。这是因为我们实际上将外环作为线串处理,而忽略线串是否来自多边形

很容易将此代码扩展到计算任意点(多边形内部或外部)到多边形边界中最近点的距离的一般情况。您只需要计算从该点到所有线环的最近点(和距离):多边形的外环和每个内环。然后,你只需要保持这些的最小值

虽然答案是这样的,但有一种更自然的方法可以使用函数获得最近点:

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

复制品@奥列格,我不相信这是复制品。如上所述,计算到多边形的最小距离没有问题。我试图在多边形边界上找到最小距离的测量点。这可能是完美的复制。我不熟悉那些漂亮的功能。如果外部点改为多边形,这也可以工作吗?我尝试对多边形和线字符串使用pol_ext.project(),但得到错误消息“GEOSProject的第三个参数必须是Point*”。有什么建议吗?我不知道。我认为你别无选择,只能自己实施。Tome Karzes的答案可以很容易地添加到该场景中(但使用其中一个多边形作为“点”,因为您有上述方法)。在问题的答案中,您可以找到Tom Karzes建议的算法的实现,以获得两条不相交的线串之间的距离。那里的代码可以很容易地调整以获得线字符串和点之间的距离,并且不依赖于shapely函数。谢谢,这很有帮助。你能不能更详细地解释一下,当点在多边形内时,为什么它不起作用?我用不同的点运行了几次这段代码,结果看起来是正确的。我会完成答案的。我假设你的多边形没有内环,在这种情况下,代码确实可以工作。这应该是正确的答案了。这个函数在我写原始答案时不可用。看来我现在应该重新阅读库文档了。@eguaio并说最近的点是在2014年添加的。我应该更仔细地阅读文档@Georgy感谢您的贡献。如果您的点位于多边形内,您可以使用:
p1,p2=最近的点(多边形边界,点)
@ZeeshanEqbal这应该可以回答您的问题: