Search code examples
areageopandasconvex-hull

calculate overlapping areas


I am following the example here and successfully created convex hulls. But I have a question on how to calculate the shared areas between each convex hull in the following figure: enter image description here

Thanks!


Solution

  • Here's an example to get the intersection of Manhattan and the Bronx. You could use pd.concat() before .overlay() if you want to combine boroughs.

    import geopandas as gpd
    nybb_path = gpd.datasets.get_path('nybb')
    
    boros = gpd.read_file(nybb_path)
    boros.set_index('BoroCode', inplace=True)
    boros.sort_index(inplace=True)
    
    boros['geometry'] = boros['geometry'].convex_hull
    
    print(boros)
        BoroName    Shape_Leng  Shape_Area  geometry
    BoroCode                
    1   Manhattan   359299.096471   6.364715e+08    POLYGON ((977855.445 188082.322, 971830.134 19...
    2   Bronx   464392.991824   1.186925e+09    POLYGON ((1017949.978 225426.885, 1015563.562 ...
    3   Brooklyn    741080.523166   1.937479e+09    POLYGON ((988872.821 146772.032, 983670.606 14...
    4   Queens  896344.047763   3.045213e+09    POLYGON ((1000721.532 136681.776, 994611.996 2...
    5   Staten Island   330470.010332   1.623820e+09    POLYGON ((915517.688 120121.881, 915467.035 12...
    
    manhattan_gdf = boros.iloc[0:1, :]
    bronx_gdf = boros.iloc[1:2, :]
    
    manhattan_bronx_intersecetion_polygon = gpd.overlay(manhattan_gdf, bronx_gdf, 
    how='intersection')
    
    #SPCS83 New York Long Island zone (US Survey feet)
    print(manhattan_bronx_intersecetion_polygon.geometry[0].area)
    164559574.89341027
    
    ax = manhattan_bronx_intersecetion_polygon.plot(figsize=(6,6))
    boros.plot(ax=ax, facecolor='none', edgecolor='k');
    

    enter image description here

    Here is a loop solution like you asked for in your comment.

    import geopandas as gpd
    nybb_path = gpd.datasets.get_path('nybb')
    
    boros = gpd.read_file(nybb_path)
    boros.set_index('BoroCode', inplace=True)
    boros.sort_index(inplace=True)
    
    boros['geometry'] = boros['geometry'].convex_hull
    
    intersection_polygons_list = []
    
    for idx, row in boros.iterrows():
    
        main_boro_gdf = boros.iloc[idx-1:idx, :]
    
        print('\n' + 'main boro:', main_boro_gdf['BoroName'].values.tolist()[:])
    
        other_boro_list = boros.index.tolist()
    
        other_boro_list.remove(idx)
    
        other_boro_gdf = boros[boros.index.isin(other_boro_list)]
    
        print('other boros:',other_boro_gdf['BoroName'].values.tolist()[:])
    
        intersection_polygons = gpd.overlay(main_boro_gdf, other_boro_gdf, how='intersection')
    
        intersection_polygons['intersection_area'] = intersection_polygons.geometry.area
    
        print('intersecton area sum:', intersection_polygons['intersection_area'].sum())
    
        intersection_polygons_list.append(intersection_polygons)
    

    output:

    main boro: ['Manhattan']
    other boros: ['Bronx', 'Brooklyn', 'Queens', 'Staten Island']
    intersecton area sum: 279710750.6116526
    
    main boro: ['Bronx']
    other boros: ['Manhattan', 'Brooklyn', 'Queens', 'Staten Island']
    intersecton area sum: 216638786.2669542
    
    main boro: ['Brooklyn']
    other boros: ['Manhattan', 'Bronx', 'Queens', 'Staten Island']
    intersecton area sum: 1506573115.3550038
    
    main boro: ['Queens']
    other boros: ['Manhattan', 'Bronx', 'Brooklyn', 'Staten Island']
    intersecton area sum: 1560297426.3563197
    
    main boro: ['Staten Island']
    other boros: ['Manhattan', 'Bronx', 'Brooklyn', 'Queens']
    intersecton area sum: 0.0
    

    You can plot using the intersection_polygons_list index values. For example here are the overlapping areas for the Bronx:

    intersection_polygons_list[1].plot()
    

    enter image description here