Aggregate overlapping polygon geometry

Question:

I am creating Polygon geometry from Point in geopandas DataFrame using buffer.

https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoSeries.buffer.html

The polygons are overlapping in some instances and I am looking to aggregate the overlapping polygons.

import pandas as pd
import numpy as np
import geopandas as gpd

df = pd.DataFrame({
                   'yr': [2018, 2017, 2018, 2016],
                   'id': [0, 1, 2, 3],
                   'v': [10, 12, 8, 10],
                   'lat': [32.7418248, 32.8340583, 32.8340583, 32.7471895],
                   'lon':[-97.524066, -97.0805484, -97.0805484, -96.9400779]
                 })

df = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df['Long'], df['Lat']))

# set crs for buffer calculations
df.set_crs("ESRI:102003", inplace=True) 

# Buffer
df['geometry'] = df.geometry.buffer(0.2)

How do I merge / aggregate the DataFrame such that there are distinct polygon geometries only? I have looked at other responses to similar questions that encourage using dissolve, however, it requires me to specify the geometry explicitly.

https://geopandas.org/en/stable/docs/user_guide/aggregation_with_dissolve.html

Asked By: kms

||

Answers:

  • unary_union will merge all overlapping geometries and return a MULTIPOLYGON of distinct not overlapping geometries
  • explode() to generate a GeoDataFrame of distinct geometries
  • sjoin() to get attributes back from buffered points
  • dissolve() to be able to aggregate attributes associated with buffered points. e.g. sum v
import pandas as pd
import numpy as np
import geopandas as gpd

df = pd.DataFrame(
    {
        "id": [0, 1, 2, 3],
        "v": [10, 12, 8, 10],
        "lat": [32.7418248, 32.8340583, 32.8340583, 32.7471895],
        "lon": [-97.524066, -97.0805484, -97.0805484, -96.9400779],
    }
)

df = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df["lon"], df["lat"]))

# set crs for buffer calculations
df.set_crs("ESRI:102003", inplace=True)

# Buffer
df["geometry"] = df.geometry.buffer(0.2)

gpd.sjoin(
    df,
    # distinct geometries, overlapping ones are merged
    gpd.GeoDataFrame(
        geometry=gpd.GeoSeries(df.unary_union).explode(index_parts=False), crs=df.crs
    ).reset_index(drop=True),
).dissolve(
    "index_right", aggfunc={"v": "sum", "id": list, "lat": "first", "lon": "first"}
)

enter image description here

Answered By: Rob Raymond
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.