使用Geopandas将道路线串几何数据聚合至固定网格遇问题
问题描述
我正尝试使用Geopandas将道路路段数据聚合到固定网格中。
道路数据结构
| Variable | geometry |
|---|---|
| 59 | LINESTRING (440735.351 4319767.843, 440733.320... |
| 48 | LINESTRING (440733.320 4319607.463, 440732.508... |
| 64 | LINESTRING (440858.641 4329887.089, 440853.551... |
| 64 | LINESTRING (440920.578 4330030.844, 440890.661... |
| 68 | LINESTRING (218573.705 4257347.137, 218586.697... |
固定网格数据结构
| geometry |
|---|
| POLYGON ((238749.978 4498509.611, 238898.825 4.. |
| POLYGON ((240086.217 4498360.636, 240234.824 4... |
| POLYGON ((241421.845 4498211.925, 21570.857 4.. |
| POLYGON ((242758.152 4498063.434, 242906.923 4... |
| POLYGON ((244094.479 4497914.762, 44243.009 4... |
当前实现代码
gdf_road['weighted_variable'] = gdf_road['Variable']/ gdf_road.geometry.legnth # 拼写错误:length写成legnth gdf_joined = gpd.sjoin(gdf_road, gdf_grid, how="inner", op='intersects') gdf_grid['agg_variable']=(gdf_joined['Weighted_Variable'] * gdf_joined.geometry.length).groupby(gdf_joined['index_right']).sum()
问题现象
结果保留了原道路数据的空间结构,但变量数值异常偏高,怀疑聚合逻辑存在疏漏(比如重复计数、加权方式不当等),需要改进建议。
问题分析与改进建议
1. 核心问题:未计算道路在网格内的实际相交长度
你的代码中使用gdf_joined.geometry.length调用的是整条道路的长度,而非道路落在对应网格内的片段长度。当一条道路穿过多个网格时,每个网格都会用整条道路长度计算,导致同一道路的变量值被重复累加,最终结果偏高。
2. 其他明显错误
- 拼写错误:
legnth应为length,会直接导致加权列计算失败 - 大小写不一致:计算的列是
weighted_variable,后续调用却用Weighted_Variable,会引发KeyError
3. 正确的聚合实现步骤
步骤1:获取道路与网格的相交片段
使用gpd.overlay工具提取每条道路在每个网格内的实际线段,同时保留必要字段:
# 给网格添加唯一索引,方便后续分组 gdf_grid['grid_id'] = gdf_grid.index # 执行空间叠加,得到道路与网格的相交部分 road_grid_intersect = gpd.overlay(gdf_road, gdf_grid, how='intersection') # 计算每个相交片段的长度 road_grid_intersect['segment_length'] = road_grid_intersect.geometry.length
步骤2:按网格加权聚合变量
按片段长度占整条道路的比例分配Variable值,再按网格分组求和:
# 计算每条道路的总长度 gdf_road['total_length'] = gdf_road.geometry.length # 合并道路总长度到相交结果 road_grid_intersect = road_grid_intersect.merge( gdf_road[['total_length']], left_on='index_left', right_index=True ) # 计算每个片段应分配的Variable值 road_grid_intersect['allocated_variable'] = ( road_grid_intersect['Variable'] * (road_grid_intersect['segment_length'] / road_grid_intersect['total_length']) ) # 按网格分组求和,得到聚合结果 grid_agg = road_grid_intersect.groupby('grid_id')['allocated_variable'].sum().reset_index() # 将聚合结果合并回原网格GeoDataFrame,空网格填充0 gdf_grid = gdf_grid.merge(grid_agg, on='grid_id', how='left') gdf_grid['allocated_variable'] = gdf_grid['allocated_variable'].fillna(0)
4. 优化建议
- 提前统一坐标系:检查道路和网格的CRS是否一致,不一致时先转换为同一坐标系:
if gdf_road.crs != gdf_grid.crs: gdf_road = gdf_road.to_crs(gdf_grid.crs) - 启用空间索引优化:大数据量下,提前初始化空间索引可加快计算速度:
gdf_road.sindex gdf_grid.sindex
内容的提问来源于stack exchange,提问作者VAL
相关产品推荐
相关产品推荐

