How to extract Polygons from Multipolygons in Shapely?
Asked Answered
J

4

27

I'm trying to extract the polygons from multipolygons in Shapely. I can transform a list of polygons into multipolygons using MultiPolygon from Shapely.

>>> Multi = MultiPolygon([shape(pol['geometry']) for pol in fiona.open('data.shp')]) 

And,

>>> Multi.wkt
'MULTIPOLYGON (((249744.2315302934148349 142798.1643468967231456, 250113.7910872535139788 142132.9571443685272243, 250062.6213024436729029 141973.7622582934272941, 249607.7787708004761953 141757.7120557629095856, 249367.7742475979903247 142304.6840291862317827, 249367.7742475979903247 142304.6840291862317827, 249744.2315302934148349 142798.1643468967231456)), 
               ((249175.7899173096520826 142292.5352640640921891, 249367.7742475979903247 142304.6840291862317827, 249607.7787708004761953 141757.7120557629095856, 249014.4539607730694115 141876.1348429077770561, 249175.7899173096520826 142292.5352640640921891)))'

Does anybody know how can I reverse the process i.e. given a multipolygon how can I convert it to separate polygons?

Jon answered 13/8, 2016 at 7:7 Comment(2)
Did you try polygons = [polygon for polygon in Multi]?Maxima
I tried your solution but i had this error TypeError: string indices must be integers. You have an idea ?Grassofparnassus
H
37

Simply do

Polygons = list(Multi)

This extracts the polygons and puts them in a list.

Homophile answered 8/5, 2018 at 2:22 Comment(2)
I get TypeError: 'MultiPolygon' object is not iterable when using this. I tried list(gdf['geom'].iloc[0].geoms) and it worked for meYellows
for shapely 2.0+ list(Multi.geoms) worksCockade
G
28

To avoid Deprecation Warning when using this othwerwise ok answer, do:

Polygons = list(Multipolygon.geoms)
Garceau answered 24/1, 2022 at 12:20 Comment(1)
When using Shapely 2.0 this is the correct answerAsquint
A
21

According to documentation on collections, which include such classes as MultiPoint, MultiLineString and MultiPolygon, their members can be "accessed via the geoms property or via the iterator protocol using in or list()":

from shapely.geometry import MultiPolygon, Polygon

multipolygon = MultiPolygon([Polygon([(0, 0), (1, 1), (1, 0)]),
                             Polygon([(0, 0), (1, 1), (0, 1)])])

polygons = list(multipolygon)
print(*polygons)
# POLYGON ((0 0, 1 1, 1 0, 0 0)) POLYGON ((0 0, 1 1, 0 1, 0 0))

polygons = list(multipolygon.geoms)
print(*polygons)
# POLYGON ((0 0, 1 1, 1 0, 0 0)) POLYGON ((0 0, 1 1, 0 1, 0 0))

for polygon in multipolygon:  # same for multipolygon.geoms
    print(polygon)
# POLYGON ((0 0, 1 1, 1 0, 0 0))
# POLYGON ((0 0, 1 1, 0 1, 0 0))

You can also extract individual geometries by their index:

print(multipolygon[0])
POLYGON ((0 0, 1 1, 1 0, 0 0))

Slicing them will give you a collection though:

print(multipolygon[:1])
MULTIPOLYGON (((0 0, 1 1, 1 0, 0 0)))
Abeokuta answered 4/6, 2019 at 9:44 Comment(1)
As of version 2.0.1, this answer is unfortunately no longer correct. The documentation states "Members of a GeometryCollection are accessed via the geoms property."Motherland
W
1

As other have already noted from shapely 1.8 onwards iterating upon the Multipolygon class is deprecated. The following code will work in 1.8 but won't in 2.0.

for poly in multipolygon:
  print(poly)

The correct way of doing it since 2.0 as follows:

for poly in multipolygon.geoms:
  print(poly)

Also if you are not specifically iterating through the polygons it might have to do with other libraries being outdated and calling a shapely 2.0 version.

Wilbur answered 8/11, 2023 at 11:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.