Search code examples
pythongisgeopandas

Create distinct non-overlapping polygons from overlapping polygons in Geopandas/Python


Given a GeoDataFrame with some overlapping polygons (buffers), I would like to create unique, non overlapping polygons where there are overlaps and also retain the non-overlapping polygons. The output would have no overlapping polygons. This functionality is available in ArcMap/ArcGIS Desktop using the feature-to-polygon tool:

https://pro.arcgis.com/en/pro-app/3.1/tool-reference/data-management/feature-to-polygon.htm

I have tried many different things, but cannot seem to get it quite right. Thanks for any help.

Edit to add example:

#example
import geopandas as gpd
from shapely.geometry import Point
import matplotlib.pyplot as plt
import numpy as np

polys = gpd.GeoDataFrame(geometry=[Point(0, 0), Point(1, 1), Point(1, 2), Point(2, 1)])
polys['geometry'] = polys.buffer(1)

ax2 = polys.plot(figsize=(5,5), edgecolor=u'white', color='gray')

colors = [1,2,3,4]
for name in (colors):
    polys.loc[polys['id'].eq(name)].plot(edgecolor=u'white', color=np.random.rand(3,), ax=ax2)

ax2.axis('scaled')
plt.show()

Output:

enter image description here

Desired Output:

enter image description here


Solution

  • IIUC, you can polygonize the unary_union of the exterior of each separate polygon :

    from shapely.ops import polygonize    
    
    nonov_polys = gpd.GeoDataFrame(geometry=list(
            polygonize(polys.exterior.unary_union)))
    
    print(nonov_polys.shape[0]) # 9 polygons
    
    nonov_polys.plot(ec="w", cmap="plasma"); # + plt.text for annotations
    

    enter image description here