1

I am looking to intersect two polygons. See picture below:

enter image description here

The intersection is between the pink polygon (the small one) and the purple polygon (the bigger one). My issue is when I do the intersection two purple polygons are kept (the one on the left where there is a full intersection and the one on the right where there is a very tiny intersection at the border).

Here is the code of the intersection.

geomap_iris_augmented=gpd.sjoin(left_df=geomap_iris_temp, right_df=all_quartiers_temp, how="left", predicate="intersects")

Is there a way to adapt the code in order to keep the polygon that has the highest intersection ? (meaning the purple polygon on the left)

I am thinking of shrinking the polygon by little but is it enough? see proposition below

all_quartiers_temp.geometry.buffer(-0.0001)

1 Answer 1

2

You can:

  1. Create a column where you save the larger polygon geometries,
  2. then spatial join the larger polygons to the smaller
  3. Calculate the overlap area (using the saved geometry and the spatial join geometry)
  4. Drop duplicates, keeping the largest area joined

Both my dataframes have columns named id with unique ids.

import geopandas as gpd
bigger = gpd.read_file(r"/home/bera/Desktop/gistest/buffers.shp")
smaller = gpd.read_file(r"/home/bera/Desktop/gistest/smaller.shp")

print(smaller["id"].duplicated().any())
#False

bigger["biggeom"] = bigger.geometry #Save the big polygon geometries, or they are lost in the spatial join
sj = gpd.sjoin(left_df=smaller, right_df=bigger, how="left", predicate="intersects")

#Now there are duplicated small polygons, for example id 1 is intersecting both 9 and 10:
#print(sj.smallid.duplicated().any())
#True
print(sj.loc[sj["id_left"]==1][["id_left", "id_right"]])
#    id_left  id_right
# 0        1       9.0
# 0        1      10.0

#Calculate overlap areas
sj["overlap_area"] = sj.apply(lambda x: x["geometry"].intersection(x["biggeom"]).area if x["biggeom"] is not None else 0, axis=1)

#Sort ascending by overlap_area, drop duplicates keeping the last/largest
sj = sj.sort_values(by=["id_left", "overlap_area"]).drop_duplicates(subset="id_left", keep="last")

# print(sj.loc[sj["id_left"]==1][["id_left", "id_right"]])
#    id_left  id_right
# 0        1      10.0

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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