如何使用 Python 合并几乎接触的多边形?例如,给定这些多边形和一些距离阈值 T:

输入多边形

该算法将产生如下内容:

结果多边形

所以基本上我需要删除两个多边形之间小于 T 的任何间隙。

不应不必要地修改多边形的原始顶点。因此,例如简单地缓冲两个多边形然后将它们合并是不好的。

已经实现此功能的库也可以。

编辑:作为另一个例子,ArcGIS 多边形聚合似乎正是这样做的。然而,没有太多关于它是如何实现的提示,并且使用 ArcGIS 不是一个选项。


这是我尝试过的:

我已经用你的阈值 T画了一个圆,圆心是基于polygon_1ad 中所有点之间最近的点polygon_2然后找到交点,并找到交点区域的凸包。然后找到三个多边形的并集,代码:

import numpy as np
import matplotlib.pyplot as plt
from shapely.ops import unary_union
from shapely.geometry import Polygon
from scipy.spatial import ConvexHull


polygon_1 = np.array([[1, 6, 7.8, 7.8, 1, 1], [4, 4, 6, 11, 11, 4]]).T
polygon_2 = np.array([[6, 14, 14, 11, 8.2, 9, 6, 6], [0.5, 0.5, 12, 12, 10, 4.2, 3.5, 0.5]]).T

poly_1 = Polygon(polygon_1)
poly_2 = Polygon(polygon_2)

# define threshold T
T = 2.5

#Initialize a variable to create a circle
theta = np.linspace(0, 2*np.pi, 100)



intersection_points  = []
coord_circles = np.zeros((0, 2))
for poly in polygon_1:
    # Calculate the distance between the points in polygon_1 ad all points in polygon_2
    norm = np.sqrt((poly[0] - polygon_2[:, 0])**2 + (poly[1] - polygon_2[:, 1])**2)
    
    # If the distance is smaaller than the threshold
    if np.min(norm) < T:
        # Find the nearest point in polygon_2
        point_near =polygon_2[ np.argmin(norm)]
        x = T*np.cos(theta) + point_near[0]
        y = T*np.sin(theta) + point_near[1]
        
        # Crear a polygon for the circle and find intersection points with polygon_1 and polygon_2
        poly_circle = Polygon(np.array([x, y]).T)
        intersec_1 = poly_1.boundary.intersection(poly_circle.boundary)
        intersection_points.append(intersec_1.geoms[0].coords._coords[0])
        intersection_points.append(intersec_1.geoms[1].coords._coords[0])
        intersec_2 = poly_2.boundary.intersection(poly_circle.boundary)
        intersection_points.append(intersec_2.geoms[0].coords._coords[0])
        intersection_points.append(intersec_2.geoms[1].coords._coords[0])
        
intersection_points = np.array(intersection_points)   

# Find the Convex hulls 
hull = ConvexHull(intersection_points)

# Creat a polygon for the convex hull of the intersections 
poly_3 = Polygon(np.c_[intersection_points[hull.vertices,0], intersection_points[hull.vertices,1]])


# Find the union of the these three polygon
a = unary_union([poly_1, poly_2, poly_3])

result_x, result_y = a.exterior.coords.xy
result_x = result_x.tolist()
result_y = result_y.tolist()

plt.subplot(121) 
plt.plot(polygon_1[:, 0], polygon_1[:, 1], 'b')
plt.plot(polygon_2[:, 0], polygon_2[:, 1], 'r')
plt.axis('equal')
plt.title("Before merging")
plt.subplot(122) 
plt.plot(result_x, result_y, 'k-o')
plt.axis('equal')
plt.title("After merging") 

你得到的数字:

在此处输入图像描述


您可以定义一个“合并”距离,并合并每两个小于合并距离的顶点。

不幸的是,那行不通。取多边形 P1 和 P2。如果 P1 的顶点 V 位于 P2 的任何边的中心点旁边,则它可以无限接近 P2,但仍不在算法的合并距离内。

还会考虑边缘距离来解决这个问题吗?

也许使用形态膨胀stackoverflow.com/a/74997349/2836621

@WillemHendriks 我想它可以解决这个特定问题。然而,仍有许多问题。一旦合并了所有此类顶点(我猜合并顶点意味着在它们之间添加一条边)和边(拆分边、插入顶点然后合并?),您就会在两个多边形之间混合边。其中一些应该被删除,一些应该代表最终结果的外部,有些甚至可能代表最终结果的内部(引入的孔)。不知道从那里去哪里。

Thank you for taking the time to come up with this. But the convex part breaks down if it is given a suitable concave polygon. For example poly_1 = LineString([(1, 1), (3, 3), (1, 5)]).buffer(0.2) and poly_2 = LineString([(2, 1), (4, 3), (2, 5)]).buffer(0.2).

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部