Miko
Miko

Reputation: 59

How to find intersecting polygons and union them using geopandas?

I have a geo dataframe with coordinates and I would like to check if polygons intersect with each other. If yes union these intersecting polygons. How can I handle with geopandas?

 geom                                                  index
0  POLYGON ((68.19900 54.75696, 68.17856 54.75425...     6
1  POLYGON ((68.15779 54.83775, 68.15851 54.83540...     7
2  POLYGON ((68.13169 54.81037, 68.14262 54.80948...     8
3  POLYGON ((68.13895 54.82565, 68.13897 54.82237...     9
4  POLYGON ((68.19696 54.75934, 68.17838 54.75674...    10
5  POLYGON ((68.19454 54.84803, 68.19473 54.84899...     1
6  POLYGON ((68.03500 54.76356, 68.04866 54.75895...     2
7  POLYGON ((67.96892 54.78627, 67.97568 54.78423...     3
8  POLYGON ((68.01496 54.75251, 68.01477 54.74690...     4
9  POLYGON ((68.17951 54.86391, 68.17650 54.85733...     5

for example index 6 intersects with index 10 and index 4 intersects with index 2. Further, I want to union 6 with 10 and 2 with 4. Finally, I will have 8 rows instead of 10.

Upvotes: 2

Views: 1845

Answers (1)

antoine
antoine

Reputation: 578

Given a GeoDataFrame with multiple Polygons where p1 and p2 intersect:

import geopandas as gpd
from shapely.geometry import Point
p1 = Point(1, 0).buffer(1)
p2 = Point(0, 0).buffer(1)
p3 = Point(0.5, 3).buffer(1)

gdf = gpd.GeoDataFrame(dict(id=[1, 2, 3]), geometry=[p1, p2, p3])

Looks like that:

   id                                           geometry
0   1  POLYGON ((2.00000 0.00000, 1.99518 -0.09802, 1...
1   2  POLYGON ((1.00000 0.00000, 0.99518 -0.09802, 0...
2   3  POLYGON ((1.50000 3.00000, 1.49518 2.90198, 1....

enter image description here

Then create a merged GeoDataFrame where all data is lost but every overlapping geometry is merged :

gdf_merge = gdf.dissolve().explode(index_parts=True)

Gives you this :

   id                                           geometry
0   1  POLYGON ((0.47140 -0.88192, 0.38268 -0.92388, ...
1   1  POLYGON ((1.48079 2.80491, 1.45694 2.70972, 1....

enter image description here

And finally, join new simplified GeoDataFrame with old one to recover data. The duplicates are found by AREA attribute that is dropped later :

gdf_clean = gpd.sjoin(gdf_merge, gdf, how='inner', predicate='intersects')
gdf_clean['AREA'] = gdf_clean['geometry'].apply(lambda x: x.area)
gdf_clean = gdf_clean.groupby('AREA')
gdf_clean = gdf_clean.agg({'geometry': 'first', 'id_right': 'min'})
gdf_clean['id'] = gdf_clean['id_right']
gdf_clean = gdf_clean[['id', 'geometry']].reset_index(level='AREA').drop(columns=['AREA'])

Ouputs:

   id                                           geometry
0   3  POLYGON ((1.48079 2.80491, 1.45694 2.70972, 1....
1   1  POLYGON ((0.47140 -0.88192, 0.38268 -0.92388, ...

enter image description here

Upvotes: 4

Related Questions