使用Shapely在多边形上切割两条线

23

我正在尝试使用两条线将一个shapely.geometry.Polygon实例切成两部分。例如,在下面的代码中,polygon是一个环,如果我们用line1line2切割它,我们应该得到两个部分,一个是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)])
3个回答

15
自2017年8月份的 Shapely 版本1.6.0 开始,已经有一个可以将一个几何图形分割成另一个的函数了,所以现在不需要再自己编写代码实现分割功能了。请参阅文档:shapely.ops.split(geom, splitter)。请注意,该主题中旧的答案是在 Shapely 中还没有添加分割函数之前编写的,它们现在已经过时了。

7

Ken Watford在这里提到使用bufferdifference来实现,但会损失一些面积。以下是一个示例代码:

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)

暂时可以使用,我很想看到是否有另一种方法(可能不会丧失面积)!


2
我认为任何精确的解决方案都需要从头开始实现数学问题,并编写大量代码。特别是在您设置问题的一般术语中。 - eguaio

5
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)

enter image description here


如果你有两条线,你可以像这样在 linemerge() 中添加第二条线:merged = linemerge([polygon.boundary, line1, line2]) - tsveti_iko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接