Search code examples
pythongeometryshapely

How to split/cut multipolygon region by multiple line segments?


I have a polygon region poly1 and another polygon region poly2 ( both are polygon in shapely), then I am taking their symmetric difference which is a multipolygon.

There are line segments which join the vertices of poly1 and poly2. I want to split the multipolygon obtained by the symmetric difference by line segements(these line segments lie on the multipolygon itself).

The code I am running gives error:

File "/home/runner/Python/.pythonlibs/lib/python3.10/site-packages/shapely/ops.py", line 511, in split
    [i for part in geom.geoms for i in SplitOp.split(part, splitter).geoms]
  File "/home/runner/Python/.pythonlibs/lib/python3.10/site-packages/shapely/ops.py", line 511, in <listcomp>
    [i for part in geom.geoms for i in SplitOp.split(part, splitter).geoms]
  File "/home/runner/Python/.pythonlibs/lib/python3.10/site-packages/shapely/ops.py", line 535, in split
    raise GeometryTypeError(
shapely.errors.GeometryTypeError: Splitting a Polygon with a MultiLineString is not supported

Code-

from shapely.geometry import MultiPolygon, Polygon, MultiLineString, LineString
from shapely.ops import split

multipolygon = MultiPolygon([
      Polygon([(7, 10), (8, 11), (9, 11), (8, 10), (7, 9.5), (7, 10)]),
      Polygon([(9.5, 8.5), (10, 9), (10, 10), (11, 9), (9.5, 8.5)])
])
multiline = MultiLineString([
    LineString([(7, 10), (8, 10)]),
    LineString([(8, 10), (8, 11)]),
    LineString([(10, 9), (11, 9 )]),
    LineString([(8, 9), (10, 9)])
])

# Divide multipolygon by lines
divided_multipolygon = split(multipolygon, multiline)

print("Divided MultiPolygon:", divided_multipolygon)

How can I achieve my task? Any suggestions or help would be greatly appreciated!


Solution

  • You can loop over the individual lines in the MultiLine and split the MultiPolygon in multiple passes...

    from shapely.geometry import MultiPolygon, Polygon, MultiLineString, LineString
    from shapely.ops import split
    
    multipolygon = MultiPolygon(
        [
            Polygon([(7, 10), (8, 11), (9, 11), (8, 10), (7, 9.5), (7, 10)]),
            Polygon([(9.5, 8.5), (10, 9), (10, 10), (11, 9), (9.5, 8.5)]),
        ]
    )
    multiline = MultiLineString(
        [
            LineString([(7, 10), (8, 10)]),
            LineString([(8, 10), (8, 11)]),
            LineString([(10, 9), (11, 9)]),
            LineString([(8, 9), (10, 9)]),
        ]
    )
    
    # Divide multipolygon by lines
    for line in multiline.geoms:
        multipolygon = MultiPolygon(split(multipolygon, line).geoms)
    
    print("Divided MultiPolygon:", multipolygon)