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

GeoDataFrame中构建100米分辨率可顺序索引米制网格的实现方法

100m分辨率米制空间网格实现方案

核心逻辑说明

经纬度坐标系(EPSG:4326)以角度为单位,既无法精准换算100m对应的实际边长,也不符合“不依托经纬度构建网格”的要求。整套实现流程完全基于米制投影坐标系完成,全程不涉及经纬度间隔的换算逻辑。

步骤1:转换为米制投影坐标系

osmnx内置了自动匹配UTM投影的工具,无需手动计算研究区域对应的投影带号,直接将路网节点转换为米制单位的投影坐标系:

# 自动将经纬度格式的路网节点转换为匹配研究区域的UTM投影
nodes_proj = ox.projection.project_gdf(nodes)
# 获取投影后的整体空间边界(单位:米)
xmin, ymin, xmax, ymax = nodes_proj.total_bounds

转换完成后,所有坐标的数值单位为米,后续网格计算全部基于该坐标系开展,完全脱离经纬度单位的约束。

步骤2:生成100m×100m均匀网格

直接在投影坐标系的空间边界内,按100m的固定边长切分网格:

grid_resolution = 100  # 网格边长,单位米
# 生成x、y方向的网格线坐标序列
x_lines = np.arange(xmin, xmax + grid_resolution, grid_resolution)
y_lines = np.arange(ymin, ymax + grid_resolution, grid_resolution)

# 批量生成网格面要素
grid_geoms = []
for x_start in x_lines:
    for y_start in y_lines:
        # 构建单个100m×100m的矩形网格
        grid_poly = Polygon([
            (x_start, y_start),
            (x_start + grid_resolution, y_start),
            (x_start + grid_resolution, y_start + grid_resolution),
            (x_start, y_start + grid_resolution)
        ])
        grid_geoms.append(grid_poly)

# 构建网格GeoDataFrame,与路网节点保持一致的投影坐标系
grid_gdf = gpd.GeoDataFrame(geometry=grid_geoms, crs=nodes_proj.crs)

步骤3:按规则分配连续Cell_ID

编号逻辑严格匹配需求:最左上角的网格Cell_ID为1,同一排内从左到右ID依次递增,排完最上方一整排后,向下一排继续延续连续编号。
实现排序时以两个维度为依据:

  • 第一优先级:网格中心点的y值,按从大到小排序(UTM投影坐标系中y值越大,位置越靠北,对应可视化视图中越靠上的位置)
  • 第二优先级:网格中心点的x值,按从小到大排序(UTM投影坐标系中x值越小,位置越靠西,对应可视化视图中越靠左的位置)

对应代码:

# 计算每个网格的中心点坐标作为排序依据
grid_gdf["center_x"] = grid_gdf.geometry.centroid.x
grid_gdf["center_y"] = grid_gdf.geometry.centroid.y

# 按指定规则排序
grid_gdf = grid_gdf.sort_values(
    by=["center_y", "center_x"],
    ascending=[False, True]  # y值降序、x值升序
).reset_index(drop=True)

# 生成连续唯一ID,从1开始计数
grid_gdf["Cell_ID"] = grid_gdf.index + 1

效果校验:排序结果中第一个单元格就是位置最靠上、最靠左的网格,即左上角单元格,ID为1;它右侧相邻的同排网格为第二个排序项,ID为2,与需求示例完全一致。

步骤4:可视化验证

将网格与路网节点叠合展示,可选择在网格中心标注Cell_ID,检查排序逻辑是否符合预期:

fig, ax = plt.subplots(figsize=(12, 8))
# 绘制半透明红色虚线边框的网格
grid_gdf.plot(ax=ax, facecolor="none", edgecolor="tab:red", linestyle="--", lw=0.5)
# 绘制黑色路网节点
nodes_proj.plot(ax=ax, color="tab:black", markersize=4)
# 可选:在网格中心标注Cell_ID
for _, cell in grid_gdf.iterrows():
    ax.text(
        cell["center_x"], cell["center_y"],
        str(cell["Cell_ID"]),
        fontsize=7, ha="center", va="center"
    )
ax.set_title("100m分辨率空间网格(带连续编号)")
plt.tight_layout()
plt.show()

原有实现的问题说明:之前直接通过经纬度间隔切分网格的逻辑,本质仍依托经纬度坐标开展计算,且不同纬度下经纬度1度对应的实际地面距离差异极大,无法精准实现100m×100m的网格尺寸要求。

内容的提问来源于stack exchange,提问作者Peter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 07:45:09