3

I refer to this example notebook resource that shows how to identify intersection regions between polygons: https://nbviewer.org/gist/jorisvandenbossche/3a55a16fda9b3c37e0fb48b1d4019e65

Here in this example, with credit going to the author of that example notebook above, we start with 3 circles that happen to all overlap:

enter image description here

We then try to find all of the new intersected polygons made up by these overlapping polygons via this code:

all_intersections = [a.intersection(b) for a, b in list(itertools.combinations(s, 2))]
s_all = pd.concat([s, geopandas.GeoSeries(all_intersections)])
polys = list(shapely.ops.polygonize(s_all.boundary.unary_union))
polys = geopandas.GeoSeries(polys)
polys.plot(cmap='Set1')

to get this plot of our three overlapping circles with each new intersected polygon identified, and so we now have 7 polygons identified, just what I want:

enter image description here

And then just running polys I see the geometries for each of these 7 newly intersected polygons printed, great:

enter image description here

Though what I am trying to figure out how to do is how to loop through each unique polygon in the initial GeoDataFrame and identify only the polygon intersections within that specific polygon.

So going with this new example:

enter image description here

For circle A would just get the geometry for circle A itself returned, and then for circle B, I would just get the intersections within circle B returned:

enter image description here

And for circle E, I would get just the intersections within circle E returned:

enter image description here

And so on, repeating this process for each unique circle.

How can I augment my above polygon intersection code to accommodate a for loop to iterate through each unique circle and only identify the intersected polygons within that specific polygon?

I have tried this:

for index, row in polygons.iterrows():
    
    all_intersections = [a.intersection(b) for a, b in list(itertools.combinations(row['geometry'], 2))]
    polygons_all = pd.concat([polygons, gpd.GeoSeries(all_intersections)])
    polys = list(shapely.ops.polygonize(polygons_all.boundary.unary_union))
    polys = gpd.GeoSeries(polys)

but am just getting errors, specifically:

TypeError: 'Polygon' object is not iterable

1 Answer 1

4

I am no expert on GeoPandas, not having used it all that much, so my adaptation of the code in your question may not be the cleanest or most efficient but, testing on a made-up data set, this seems to do what you are after:

import geopandas as gpd
import pandas as pd
import itertools
import shapely

# Path to your polygons file
shp_path = '/home/path/to/polygons.shp'
gdf = gpd.read_file(shp_path)
gdf.boundary.plot()

def get_intersections(i):
    # Current polygon
    current = gdf.iloc[i]
    # All other polygons with current dropped
    others = gdf.drop(i)
    # Get all other intersections with current
    ix = [current.geometry.intersection(other) for other in others.geometry if current.geometry.intersects(other)]
    if ix:
        s = pd.concat([gpd.GeoSeries(current.geometry), gpd.GeoSeries(ix)])
        # Get all combinations of intersections
        all_ix = [a.intersection(b) for a, b in list(itertools.combinations(s, 2))]
        return pd.concat([gpd.GeoSeries(current.geometry), gpd.GeoSeries(all_ix)])
    else:
        return gpd.GeoSeries(current.geometry)


for i in range(gdf.shape[0]):
    s = get_intersections(i)
    polys = list(shapely.ops.polygonize(s.boundary.unary_union))
    polys = gpd.GeoSeries(polys)
    polys.plot(cmap='Set2')

Resulting plots:

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

8
  • Hello thanks for this incredible suggestion, you totally understand what I was going for here! Though in trying our your code on my polygons, where some overlap with others, and some do not overlap at all, on the line s = get_intersections(i) I receive this error message: TypeError: 'method' object is not iterable. Do you know why that would be since it seems totally fine to me that I would "iterate" over each row in my geodataframe to run the get_intersections function on each unique polygon. I know that this error means I am iterating over a "method", but I don't see why I get this. Sep 12, 2022 at 21:58
  • 1
    @LostinSpatialAnalysis, I'm not sure. Did you modify the script? Would you be able to share your shapefile so that I could test it?
    – Ben W
    Sep 13, 2022 at 1:21
  • Actually I just fixed it, just had to tidy up my code a bit, your code suggestion works great! Thank you very much! Sep 13, 2022 at 20:05
  • 1
    @LostinSpatialAnalysis, great! Glad it's working.
    – Ben W
    Sep 14, 2022 at 0:40
  • 1
    @LostinSpatialAnalysis, I will try to have a look later.
    – Ben W
    Sep 21, 2022 at 5:47

Your Answer

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

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