Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

geopandas AttributeError: 'MultiPolygon' object has no attribute 'exterior'

I have two GeoDataFrame. One is of the state of Iowa, while the other is of foretasted rain over the next 72 hours for North America. I want to create a GeoDataFrame of the rain forecast where it overlies the state of Iowa. But I get an error.

state_rain = gpd.overlay(NA_rain,iowa,how='intersection')      

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-39-ba8264ed63c2> in <module>()
  3 #ws_usa[['WTRSHD_ID','QPF']].groupby('WTRSHD_ID').max().reset_index()
  4 #state_rain = sjoin(usa_r,usa,how='inner',op='intersects')
----> 5 state_rain = gpd.overlay(usa_r,joined_states,how='intersection')
  6 ws_state = gpd.overlay(ws,joined_states,how='intersection')
  7 #print ws_usa.loc[ws_usa.WTRSHD_ID == 'IA-04']['QPF']

C:\Anaconda2\lib\site-packages\geopandas\tools\overlay.pyc in overlay(df1, df2, how, use_sindex)
 95 
 96     # Collect the interior and exterior rings
---> 97     rings1 = _extract_rings(df1)
 98     rings2 = _extract_rings(df2)
 99     mls1 = MultiLineString(rings1)

C:\Anaconda2\lib\site-packages\geopandas\tools\overlay.pyc in     _extract_rings(df)
 50                 # geom from layer is not valid attempting fix by buffer 0"
 51                 geom = geom.buffer(0)
---> 52             rings.append(geom.exterior)
 53             rings.extend(geom.interiors)
 54 

AttributeError: 'MultiPolygon' object has no attribute 'exterior'

I checked for type == 'MultiPolygon', but neither GeoDataFrame contain any.

print NA_rain[NA_rain.geometry.type == 'MulitPolygon']
print iowa[iowa.geometry.type == 'MultiPolygon']

Empty GeoDataFrame
Columns: [END_TIME, ID, ISSUE_TIME, PRODUCT, QPF, START_TIME, UNITS, VALID_TIME, geometry]
Index: []
Empty GeoDataFrame
Columns: [sid, AFFGEOID, ALAND, AWATER, GEOID, LSAD, NAME, STATEFP, STATENS, STUSPS, geometry]
Index: []

If I do the following, the intersection works.

NA_rain.geometry = NA_rain.geometry.map(lambda x: x.convex_hull)

My question is twofold: 1.Why don't any MultiPolygons show up in my NA_rain GeoDataFrame, and 2. Besides turning every Polygon into a convex_hull, which ruins detailed contours of the Polygon, how would you suggest dealing with the MultiPolygon issue.

like image 450
O.D.P Avatar asked Dec 13 '25 06:12

O.D.P


1 Answers

I agree with @jdmcbr. I suspect that at least one of the features in NA_rain is a MultiPolygon which did not get detected since the condition you showed is misspelled (MulitPolygon instead of MultiPolygon).

If your dataframe has MultiPolygons, you can convert all of them to Polygons. One dirty was is by passing the list() function to each MultiPolygon and then exploding into multiple rows:

geom = NA_rain.pop('geometry')
geom = geom.apply(lambda x: list(x) if isinstance(x, MultiPolygon) else x).explode())
NA_rain = NA_rain.join(geom, how='inner')

Note that the joining in line 3 duplicates the other attributes of the dataframe for all Polygons of the MultiPolygon, including feature identifiers, which you may want to change later, depending on your task.

like image 74
emphasent Avatar answered Dec 15 '25 18:12

emphasent