2

I have a GeoPandas dataframe where the features have a Geometry type of 'GeometryCollection'.

It looks like each feature is in fact just a simple polygon, so I'd like to convert the GeometryCollection geometries to Polygon or MultiPolygon.

What's the simplest way to achieve this?

2 Answers 2

2

You can access the individual geometries in the collection with .geoms. List them, explode to rows:

import shapely
import geopandas as gpd

#Create a test df
poly1 = shapely.MultiPolygon([(((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)), [((0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1))])])
poly2 = shapely.MultiPolygon([(((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)), [((0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1))])])
poly3 = shapely.MultiPolygon([(((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)), [((0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1))])])
gc1 = shapely.GeometryCollection([poly1, poly2])
gc2 = shapely.GeometryCollection([poly2, poly3])
df = gpd.GeoDataFrame(geometry=[gc1, gc2])
# df.geometry
# 0    GEOMETRYCOLLECTION (MULTIPOLYGON (((0.00000 0....
# 1    GEOMETRYCOLLECTION (MULTIPOLYGON (((0.00000 0....

#Create a list of all geometries in each collection
df["geometries"] = df.apply(lambda x: [g for g in x.geometry.geoms], axis=1)
# df
#                                             geometry                                         geometries
# 0  GEOMETRYCOLLECTION (MULTIPOLYGON (((0.00000 0....  [MULTIPOLYGON (((0 0, 0 1, 1 1, 1 0, 0 0), (0....
# 1  GEOMETRYCOLLECTION (MULTIPOLYGON (((0.00000 0....  [MULTIPOLYGON (((0 0, 0 1, 1 1, 1 0, 0 0), (0....

#Explode each list to rows, one row for each geometry in the list.
#  Then drop the geometry column with the geometrycollections, set the geometry to the exploded ones,
#    and rename it to geometry
df = df.explode(column="geometries").drop(columns="geometry").set_geometry("geometries").rename_geometry("geometry")

# df
#                                            geometry
# 0  MULTIPOLYGON (((0.00000 0.00000, 0.00000 1.000...
# 0  MULTIPOLYGON (((0.00000 0.00000, 0.00000 1.000...
# 1  MULTIPOLYGON (((0.00000 0.00000, 0.00000 1.000...
# 1  MULTIPOLYGON (((0.00000 0.00000, 0.00000 1.000...
2

I worked out an answer after I posted this which similarly to the answer shared by BERA uses explode.

gdf.geometry = gdf.geometry.explode()[0:].values

The original GeometryCollection gets converted into MultiPolygon (since each geometry collection only had a single multipolygon in it).

Based on the info given in this GeoPandas GitHub ticket

1
  • Alot simpler than mine, nice!
    – BERA
    Jul 31, 2023 at 13:53

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.