11

Could anyone please explain this to me? The polygons all have valid geometry but the resulting multipolygon somehow doesn't. The following script:

from shapely.geometry import Polygon, MultiPolygon

polygon1 = Polygon([(0,0), (1,0), (1,1), (0,1), (0,0)])
polygon2 = Polygon([(1,1), (2,1), (2,2), (1,2), (1,1)])
polygon3 = Polygon([(1,0), (2,0), (2,1), (1,1), (1,0)])
polygon_list = [polygon1,polygon2, polygon3]

mpolygon = MultiPolygon(polygon_list)

for item in polygon_list:
    print(item.is_valid)
for item in mpolygon:
    print(item.is_valid)

print(mpolygon.is_valid)

returns the following:

True
True
True
True
True
True
False

I believe this is causing me problems as I need to intersect a multilinestring with a multipolygon, and the intersection method requires for all the polygon geometries to be valid.

Why are the individual polygons valid while the full multipolygon is not?

1
  • TL;DR - use item.buffer(0).is_valid Commented Nov 3, 2022 at 13:18

2 Answers 2

12

It's because polygon1 and polygon3 that you created intersect along an infinite amount of points. Taken here from the Shapely documentation:

enter image description here
...On the left, a valid MultiPolygon with 2 members, and on the right, a MultiPolygon that is invalid because its members touch at an infinite number of points (along a line). Link

To fix this, you need to shift polygon3 so that it will have a maximum of one intersecting point with the other polygons (or none at all).

Your polygons plotted:

enter image description here

11

In addition to @15Step's answer, If you want to fix the invalidity, use buffer method. But if polygons are adjacent, you get polygon instead of multipolygon.

mpolygon = mpolygon.buffer(0)
print(mpolygon.is_valid)
print(type(mpolygon))
# OUT:
#   True
#   <class 'shapely.geometry.polygon.Polygon'>

enter image description here

If you need multipolygon, you have to convert polygon to multipolygon.

if isinstance(mpolygon, Polygon):
    mpolygon = MultiPolygon([mpolygon])
1
  • I need an mpolygon, because I wish to do mpolygon.intersection(multilinestring) where mpolygon has many polygons and multilinestring has many LineStrings which may or may not share vertices
    – user32882
    Commented Oct 9, 2018 at 11:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.