Reputation: 11
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.
Do you have any idea what should happen?
Upvotes: 1
Views: 160
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
Upvotes: 0