如何在shapely中简化边界几何图形
我正在使用shapely进行地理信息系统(GIS)相关的工作,但在加载每个邮政编码的几何形状时遇到了内存错误,因为这些几何形状非常复杂且边缘不规则。
我想通过减少边界点的数量来减小内存占用,尽量不让形状变形太多。使用凸包(convex hull)似乎是一个可能的解决办法,或者直接丢掉很多边界上的点。我在想是否已经有现成的解决方案可以解决这个问题。
2 个回答
2
我看到这个旧帖子,因为我遇到了类似的问题。我的解决方案是根据Mike T的链接得出的:
从区域掩码生成多边形。
这里有两个区域。
import matplotlib.pyplot as plt
import shapely.geometry
import cv2
import numpy as np
# gen. mask
mask=np.zeros((600,600),dtype=bool)
mask[300:500,300:500]=True
mask[:150,30:120]=True
mask[70:120,30:220]=True
mask[100:200,200:260]=True
# get contours == polygon
contours, _ = cv2.findContours(mask.astype(np.uint8), # cv2 requires special types
cv2.RETR_TREE,
cv2.CHAIN_APPROX_NONE)
contours = [i.reshape((-1, 2)) for i in contours]
简化多边形
def simplify(polygon, tolerance = .1):
""" Simplify a polygon with shapely.
Polygon: ndarray
ndarray of the polygon positions of N points with the shape (N,2)
tolerance: float
the tolerance
"""
poly = shapely.geometry.Polygon(i)
poly_s = poly.simplify(tolerance=tolerance)
# convert it back to numpy
return np.array(poly_s.boundary.coords[:])
# Simplify all contours
contours_s = []
for i in contours:
contours_s.append(simplify(i))
绘图
plt.figure(figsize=(4,4))
plt.imshow(mask, label='2D mask')
for i, c_i in enumerate(contours_s):
plt.plot(*c_i.T, '-', label=f'cv2 contours {i}')
for i, c_i in enumerate(contours_s):
plt.plot(*c_i.T, 'o', label=f'shapely simplify {i}')
plt.legend()
plt.tight_layout()
14
试试使用几何图形的 简化方法,并设置一个容差距离。