在多边形上找到最近点的坐标

AJG*_*519 20 python shapely

说我有以下多边形和点:

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

在此输入图像描述

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

>>> dist = point.distance(poly)
>>> print(dist)
2.49136439561
Run Code Online (Sandbox Code Playgroud)

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

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

>>> buff = point.buffer(dist) 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 但是,我不确定如何计算这一点.两个多边形不相交,所以list(poly.intersection(buff))不会给我这一点.

我是否在正确的轨道上?有更简单的方法吗?

egu*_*aio 29

有一种简单的方法可以在形状函数上进行中继.首先,您需要获取多边形的外环,并将该点投影到环上.由于多边形没有投影功能,因此必须将外部设为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]
Run Code Online (Sandbox Code Playgroud)

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

如果多边形没有内环,则代码甚至可以用于多边形内的点.这是因为我们实际上使用外环作为线串,并忽略线串是否来自多边形.

很容易将此代码扩展到计算任何点(多边形内部或外部)到多边形边界中最近点的距离的一般情况.您只需计算从点到所有线环的最近点(和距离):外环和多边形的每个内环.然后,你只保留最低限度.

在此输入图像描述


Geo*_*rgy 9

尽管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)
Run Code Online (Sandbox Code Playgroud)

结果与其他答案相同:

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
Run Code Online (Sandbox Code Playgroud)

  • 这应该是现在的正确答案。在我写原始答案时,此功能不可用。看来我现在应该重新阅读图书馆文档了。 (2认同)
  • 如果你的点在多边形内部,你可以使用:`p1, p2 =nearest_points(poly.boundary, point)` (2认同)