Lucas Melo
Lucas Melo

Reputation: 11

Python Geopandas - Overlay function is not working accordingly with visual evidence

I have generated two geodataframes:

    df1=gpd.read_file("~/rede_cicloviaria.shp") # A series of Linetrings of a cycling network
    df2=gpd.read_file("~/zonas.shp") # Each line represents a traffic zone as a polygon structure

My final objective is to calculate the total length of the cycling network in each line in df2. So I used the overlay function in a for loop to account for the cycling network (df1) overlaying each polygon (df2) and then sum the existing cycling network length for each polygon.

    df3={}
    for i in range(len(zonas)):
        df3[i]=geopandas.overlay(df1,df2[df2["index"]==i], how='intersection')
        df2.at[i,"cycling_length"]=df3[i]["length"].sum()

Then, I plotted a map to visually confirm the results, where Blue means zones with cycling infrastructure and white means no cycling infrastructure available. However, I realized that for one specific zone (in orange), the overlay function did not work. Visually we can see that there exists cycling infrastructure but its correspondent geodataframe (df3[178]) is empty, meaning that the overlay function did not find a linestring inside this polygon.

enter image description here

Do you have any idea what should happen?

Upvotes: 1

Views: 160

Answers (1)

Bera
Bera

Reputation: 1949

Use .overlay, and groupby to calculate line length per polygon:

import geopandas as gpd
poly_df = gpd.read_file(r"C:/Users/bera/Desktop/gistest/zones.shp")

line_df = gpd.read_file(r"C:/Users/bera/Desktop/gistest/roads.gpkg")

xmin, ymin, xmax, ymax = poly_df.total_bounds
line_df = line_df.cx[xmin:xmax, ymin:ymax]

# poly_df.info()
# <class 'geopandas.geodataframe.GeoDataFrame'>
# RangeIndex: 3 entries, 0 to 2
# Data columns (total 2 columns):
#  #   Column    Non-Null Count  Dtype   
# ---  ------    --------------  -----   
#  0   id        3 non-null      int64   
#  1   geometry  3 non-null      geometry

intersection = gpd.overlay(df1=poly_df, df2=line_df[["geometry"]], how="intersection", keep_geom_type=False)

ax = poly_df.plot(figsize=(10,10), column="id", cmap="Pastel2", zorder=1)
line_df.plot(ax=ax, color="black", zorder=2)
intersection.plot(ax=ax, color="red", zorder=3)

length_per_polygon = intersection.groupby("id").apply(lambda x: sum(x.geometry.length))

# print(length_per_polygon)
# id
# 1     19483.69997
# 3    102053.51016

enter image description here

Upvotes: 0

Related Questions