Reputation: 59
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
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....
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....
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, ...
Upvotes: 4