在Shapely中查找多边形上最近点的坐标

问题描述 投票:0回答:4

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

>>> poly = Polygon([(0, 0), (2, 8), (14, 10), (6, 1)])
>>> point = Point(12, 4)

enter image description here

我可以计算该点到多边形的距离...

>>> dist = point.distance(poly)
>>> print(dist)
2.49136439561

...但我想知道最短距离测量到的多边形边界上的点的坐标。

我最初的方法是通过点到多边形的距离来缓冲该点,并找到该圆与多边形相切的点:

>>> buff = point.buffer(dist) 

enter image description here 但是,我不确定如何计算该点。两个多边形不相交,所以

list(poly.intersection(buff))
不会给我那个点。

我的方向正确吗?有没有更简单的方法?

python shapely
4个回答
67
投票

虽然 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

36
投票

请不要对这个答案进行投票,正确的答案是下面@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]

值得一提的是,只有当您知道该点位于多边形外部之外时,此方法才有效。如果该点位于其内环之一内,则需要针对这种情况调整代码。

如果多边形没有内环,则即使对于多边形内部的点,代码也将起作用。这是因为我们实际上将外环视为线串,并忽略线串是否来自多边形。

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

enter image description here


0
投票

我喜欢将多边形poly与以点point为中心的圆buff相交的想法,就像您在问题中所写的那样。我建议:

poly.boundary.intersection(buff.boundary)


0
投票

正如@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)
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.