在 Shapely 中用两条线切割多边形
Cut a polygon with two lines in Shapely
我试图用两行将 shapely.geometry.Polygon
实例分成两部分。例如,在下面的代码中,polygon
是一个环,如果我们用 line1
和 line2
切割它,我们应该得到两个部分环,一个 270 度,一个 90 度.有没有一种干净的方法可以做到这一点?
from shapely.geometry import Point, LineString, Polygon
polygon = Point(0, 0).buffer(2).difference(Point(0, 0).buffer(1))
line1 = LineString([(0, 0), (3, 3)])
line2 = LineString([(0, 0), (3, -3)])
Ken Watford 回答了 here 关于使用 buffer
和 difference
来解决问题,但缺点是会损失一些区域。示例代码如下:
from shapely.geometry import Point, LineString, Polygon
polygon = Point(0, 0).buffer(2).difference(Point(0, 0).buffer(1))
line1 = LineString([(0, 0), (3, 3)])
line2 = LineString([(0, 0), (3, -3)])
line1_pol = line1.buffer(1e-3)
line2_pol = line2.buffer(1e-3)
new_polygon = polygon.difference(line1_pol).difference(line2_pol)
目前有效,我很想知道是否还有其他(可能 w/o 损失区域)方法!
from shapely.ops import linemerge, unary_union, polygonize
from shapely.geometry import LineString, Polygon
# Define the Polygon and the cutting line
line = LineString([(-5, -5), (5, 5)])
polygon = Polygon([(-1, -1), (1, -1), (1, 1), (-1, 1)])
def cut_polygon_by_line(polygon, line):
merged = linemerge([polygon.boundary, line])
borders = unary_union(merged)
polygons = polygonize(borders)
return list(polygons)
def plot(shapely_objects, figure_path='fig.png'):
from matplotlib import pyplot as plt
import geopandas as gpd
boundary = gpd.GeoSeries(shapely_objects)
boundary.plot(color=['red', 'green', 'blue', 'yellow', 'yellow'])
plt.savefig(figure_path)
result = cut_polygon_by_line(polygon, line)
print(result)
plot(result)
print(result[0].intersection(result[1]))
结果是
[<shapely.geometry.polygon.Polygon object at 0x7f50dcf46d68>,
<shapely.geometry.polygon.Polygon object at 0x7f50dcf46da0>]
LINESTRING (-1 -1, 1 1)
从 1.6.0 版(2017 年 8 月)开始,Shapely 中有一个将一个几何体分割成另一个几何体的功能,因此无需再自己动手。请参阅文档:shapely.ops.split(geom, splitter)
请注意,此线程上的旧答案是在 拆分函数出现在 Shapely 之前写的 - 它们现在实际上已经过时了。
我试图用两行将 shapely.geometry.Polygon
实例分成两部分。例如,在下面的代码中,polygon
是一个环,如果我们用 line1
和 line2
切割它,我们应该得到两个部分环,一个 270 度,一个 90 度.有没有一种干净的方法可以做到这一点?
from shapely.geometry import Point, LineString, Polygon
polygon = Point(0, 0).buffer(2).difference(Point(0, 0).buffer(1))
line1 = LineString([(0, 0), (3, 3)])
line2 = LineString([(0, 0), (3, -3)])
Ken Watford 回答了 here 关于使用 buffer
和 difference
来解决问题,但缺点是会损失一些区域。示例代码如下:
from shapely.geometry import Point, LineString, Polygon
polygon = Point(0, 0).buffer(2).difference(Point(0, 0).buffer(1))
line1 = LineString([(0, 0), (3, 3)])
line2 = LineString([(0, 0), (3, -3)])
line1_pol = line1.buffer(1e-3)
line2_pol = line2.buffer(1e-3)
new_polygon = polygon.difference(line1_pol).difference(line2_pol)
目前有效,我很想知道是否还有其他(可能 w/o 损失区域)方法!
from shapely.ops import linemerge, unary_union, polygonize
from shapely.geometry import LineString, Polygon
# Define the Polygon and the cutting line
line = LineString([(-5, -5), (5, 5)])
polygon = Polygon([(-1, -1), (1, -1), (1, 1), (-1, 1)])
def cut_polygon_by_line(polygon, line):
merged = linemerge([polygon.boundary, line])
borders = unary_union(merged)
polygons = polygonize(borders)
return list(polygons)
def plot(shapely_objects, figure_path='fig.png'):
from matplotlib import pyplot as plt
import geopandas as gpd
boundary = gpd.GeoSeries(shapely_objects)
boundary.plot(color=['red', 'green', 'blue', 'yellow', 'yellow'])
plt.savefig(figure_path)
result = cut_polygon_by_line(polygon, line)
print(result)
plot(result)
print(result[0].intersection(result[1]))
结果是
[<shapely.geometry.polygon.Polygon object at 0x7f50dcf46d68>,
<shapely.geometry.polygon.Polygon object at 0x7f50dcf46da0>]
LINESTRING (-1 -1, 1 1)
从 1.6.0 版(2017 年 8 月)开始,Shapely 中有一个将一个几何体分割成另一个几何体的功能,因此无需再自己动手。请参阅文档:shapely.ops.split(geom, splitter)
请注意,此线程上的旧答案是在 拆分函数出现在 Shapely 之前写的 - 它们现在实际上已经过时了。