0

I'm trying to merge 2 geodataframes and combine all entities. So I use :

cloudNshadow = gpd.overlay(cloud, shadow, how='union')
cloudNshadow = cloudNshadow.unary_union()

But it returns me :

cloudNshadow = cloudNshadow.unary_union()
TypeError: 'MultiPolygon' object is not callable

So I insert a gdf.explode() :

cloudNshadow = gpd.overlay(cloud, shadow, how='union')
cloudNshadow = cloudNshadow.explode()
cloudNshadow = cloudNshadow.unary_union()

But same error... Explode() isn't supposed to explode multi-entities ??

  • 3
    unary_union is a property, not a method, so you can do cloudNshadow.unary_union instead of cloudNshadow.unary_union() – joris Apr 12 '18 at 11:35
  • Damn ! you're right – Tim C. Apr 12 '18 at 11:55
  • @joris But i'm still stucked by multipolygon. it doesn't work with gdf.to_file('gdf.shp) : AttributeError: 'MultiPolygon' object has no attribute 'to_file' – Tim C. Apr 12 '18 at 12:00
  • That's because a MultiPolygon is a single scalar geometry object (a shapely object), not a GeoDataFrame which has a to_file method. If you want to export it to a file, you need to put it again in a GeoDataFrame – joris Apr 12 '18 at 12:47
  • Somewhere in your script, you might have assigned gpd variable to MultiPolygon object or a method returning Multipolygon instead of GeoDataFrame – Kadir Şahbaz Apr 12 '18 at 12:54
1

Look at How to self union a GeoDataFrame?. unary_union is a Shapely function (GeoPandas uses Shapely)

With the example of GeoPandas (Set-Operations with Overlay)

from shapely.geometry import Polygon
polys1 = gpd.GeoSeries([Polygon([(0,0), (2,0), (2,2), (0,2)]),Polygon([(2,2), (4,2), (4,4), (2,4)])])
polys2 = gpd.GeoSeries([Polygon([(1,1), (3,1), (3,3), (1,3)]),Polygon([(3,3), (5,3), (5,5), (3,5)])])
df1 = gpd.GeoDataFrame({'geometry': poly1, 'df1':[1,2]})
df2 = gpd.GeoDataFrame({'geometry': polys2, 'df2':[1,2]})
# merge the two GeoDataframe
cloudNshadow = gpd.overlay(df1, df2, how='union')
print(cloudNshadow)
   df1  df2                          geometry
0  1.0  NaN            POLYGON ((2 1, 2 0, 0 0, 0 2, 1 2, 1 1, 2 1))
1  1.0  1.0            POLYGON ((2 1, 1 1, 1 2, 2 2, 2 1))
2  NaN  1.0            POLYGON ((2 1, 2 2, 3 2, 3 1, 2 1))
3  NaN  1.0            POLYGON ((2 2, 1 2, 1 3, 2 3, 2 2))
4  2.0  NaN            POLYGON ((3 2, 3 3, 4 3, 4 2, 3 2))
5  2.0  1.0            POLYGON ((3 3, 3 2, 2 2, 2 3, 3 3))
6  2.0  NaN            POLYGON ((3 3, 2 3, 2 4, 3 4, 3 3))
7  NaN  2.0            POLYGON ((4 3, 4 4, 3 4, 3 5, 5 5, 5 3, 4 3))
8  2.0  2.0            POLYGON ((3 4, 4 4, 4 3, 3 3, 3 4))  

Now, to apply unary_union you need a shapely geometry not a GeoDataFrame

print(cloudNshadow.geometry.unary_union.wkt) 
POLYGON ((2 1, 2 0, 0 0, 0 2, 1 2, 1 3, 2 3, 2 4, 3 4, 3 5, 5 5, 5 3, 4 3, 4 2, 3 2, 3 1, 2 1))

and same for explode()

# creation of a MuliPolygon
from shapely.geometry import MultiPolygon
multi = MultiPolygon(poly for poly in  cloudNshadow.geometry)
print(multi) 
MULTIPOLYGON (((2 1, 2 0, 0 0, 0 2, 1 2, 1 1, 2 1)), ((2 1, 1 1, 1 2, 2 2, 2 1)), ((2 1, 2 2, 3 2, 3 1, 2 1)), ((2 2, 1 2, 1 3, 2 3, 2 2)), ((3 2, 3 3, 4 3, 4 2, 3 2)), ((3 3, 3 2, 2 2, 2 3, 3 3)), ((3 3, 2 3, 2 4, 3 4, 3 3)), ((4 3, 4 4, 3 4, 3 5, 5 5, 5 3, 4 3)), ((3 4, 4 4, 4 3, 3 3, 3 4)))
multigs = gpd.GeoSeries(multi)
df3 = gpd.GeoDataFrame({'geometry': multigs, 'test':[1]})
print( df3.geometry.explode())
0      POLYGON ((2 1, 2 0, 0 0, 0 2, 1 2, 1 1, 2 1))
1      POLYGON ((2 1, 1 1, 1 2, 2 2, 2 1))
2      POLYGON ((2 1, 2 2, 3 2, 3 1, 2 1))
3      POLYGON ((2 2, 1 2, 1 3, 2 3, 2 2))
4      POLYGON ((3 2, 3 3, 4 3, 4 2, 3 2))
5      POLYGON ((3 3, 3 2, 2 2, 2 3, 3 3))
6      POLYGON ((3 3, 2 3, 2 4, 3 4, 3 3))
7      POLYGON ((4 3, 4 4, 3 4, 3 5, 5 5, 5 3, 4 3))
8      POLYGON ((3 4, 4 4, 4 3, 3 3, 3 4))
Name: geometry, dtype: object

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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