Try using the geometry's simplify method, specifying a tolerance distance.
How to simplify boundary geometries in shapely
题
I'm working with shapely to do GIS, but I'm running into memory errors when loading the geometry of each zip code into memory because the geometry is so jagged and complicated.
I'd like to make the shape smaller in memory by reducing the number of boundary points as low as possible without distorting the shape too much. Using the convex hull seems like one potential answer, as could simply throwing away lots of points from the boundary. I'm wondering if there's something already out there that solves this problem.
解决方案
其他提示
Came across this old post, as I had a similar problem. My solution was as follows:
Generate polygons from an area mask.
Here it's two areas.
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, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
contours = [i.reshape((-1, 2)) for i in contours]
Simplified the polygon(s)
simplify_tolerance = .1
# simplify contours with shapely
contours_s = []
for i in contours:
poly = shapely.geometry.Polygon(i.reshape((-1, 2)))
poly_s = poly.simplify(tolerance=simplify_tolerance)
# store the boundary coordinates as a numpy array
contours_s.append(np.array(poly_s.boundary.coords[:]))
Plot
plt.figure(figsize=(4,4))
plt.imshow(mask, label='2D mask')
for i, c_i in enumerate(contours_s):
plt.plot(*c_i.reshape((-1, 2)).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()
不隶属于 StackOverflow