我正在寻找一种平滑多边形的方法,使相邻/接触的多边形保持接触。单个多边形可以很容易地进行平滑处理,例如使用PAEK或Bezier插值(https://pro.arcgis.com/en/pro-app/latest/tool-reference/cartography/smooth-polygon.htm),这自然会改变它们的边界。但是如何平滑所有多边形,使接触的多边形保持不变呢?
我正在寻找一个Python解决方案,这样可以轻松地进行自动化。我在Arcgis中找到了一个等效的问题(https://gis.stackexchange.com/questions/183718/how-to-smooth-adjacent-polygons),其中最佳答案概述了一个好的策略(将多边形边缘从多边形交点转换为线条,平滑这些线条,然后重建多边形)。也许这是最好的策略,但我不知道如何在Python中将共享的多边形边界转换为单独的折线。
这里有一些示例代码,仅显示了2个多边形的操作(但我已经手动创建了“平滑”的多边形):
import matplotlib.pyplot as plt
import geopandas as gpd
from shapely import geometry
x_min, x_max, y_min, y_max = 0, 20, 0, 20
## Create original (coarse) polygons:
staircase_points = [[(ii, ii), (ii, ii + 1)] for ii in range(x_max)]
staircase_points_flat = [coord for double_coord in staircase_points for coord in double_coord] + [(x_max, y_max)]
list_points = {1: staircase_points_flat + [(x_max, y_min)],
2: staircase_points_flat[1:-1] + [(x_min, y_max)]}
pols_coarse = {}
for ind_pol in [1, 2]:
list_points[ind_pol] = [geometry.Point(x) for x in list_points[ind_pol]]
pols_coarse[ind_pol] = geometry.Polygon(list_points[ind_pol])
df_pols_coarse = gpd.GeoDataFrame({'geometry': pols_coarse.values(), 'id': pols_coarse.keys()})
## Create smooth polygons (manually):
pols_smooth = {1: geometry.Polygon([geometry.Point(x) for x in [(x_min, y_min), (x_max, y_min), (x_max, y_max)]]),
2: geometry.Polygon([geometry.Point(x) for x in [(x_min, y_min), (x_min, y_max), (x_max, y_max)]])}
df_pols_smooth = gpd.GeoDataFrame({'geometry': pols_smooth.values(), 'id': pols_smooth.keys()})
## Plot
fig, ax = plt.subplots(1, 2, figsize=(10, 4))
df_pols_coarse.plot(column='id', ax=ax[0])
df_pols_smooth.plot(column='id', ax=ax[1])
ax[0].set_title('Original polygons')
ax[1].set_title('Smoothed polygons');
更新: 使用Mountain的建议和这篇文章,我认为问题可以分解成以下步骤:
- 找到每对相邻多边形之间的边界边缘(例如,使用这个建议)。
- 将它们转换为numpy数组并根据Mountain的bspline建议进行平滑处理。
- 使用更新/平滑的边缘重构多边形。
还要注意,对于单个(shapely.geometry
)多边形,可以使用pol.simplify()
使用Douglas-Peucker算法进行平滑处理。