You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Geopandas将道路线串几何数据聚合至固定网格遇问题

问题描述

我正尝试使用Geopandas将道路路段数据聚合到固定网格中。

道路数据结构

Variablegeometry
59LINESTRING (440735.351 4319767.843, 440733.320...
48LINESTRING (440733.320 4319607.463, 440732.508...
64LINESTRING (440858.641 4329887.089, 440853.551...
64LINESTRING (440920.578 4330030.844, 440890.661...
68LINESTRING (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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 13:20:40