znlgis 博客

GIS开发与技术分享

第十一章:网络分析步骤详解

网络分析步骤(network.*)提供基于图论的路网分析和地理编码功能,共 3 个步骤,需要安装 [network] 可选依赖(networkx、geopy)。


11.1 安装依赖

pip install -e ".[network]"

11.2 步骤总览

步骤 ID 名称 功能 依赖
network.shortest_path 最短路径 计算两点间最短路径 networkx
network.service_area 服务区分析 计算可达服务区 networkx
network.geocode 地理编码 地址列表→坐标点 geopy

11.3 network.shortest_path:最短路径

在线矢量网络(道路、管线等)中计算两点之间的最短路径,使用 networkx 构建图论模型。

参数

参数 类型 必填 默认值 说明
input geodataframe 输入线矢量网络(道路、管线等)
origin list 起点坐标 [x, y]
destination list 终点坐标 [x, y]
weight string 权重字段名(如 "travel_time", "length");不指定则使用几何长度

输出

属性 类型 说明
output GeoDataFrame 最短路径线(LineString),含 path_costnode_count 属性
stats.path_cost float 路径总代价(权重之和或几何长度)
stats.node_count int 路径经过的节点数量
stats.path_length float 路径几何长度

实现原理

  1. 将线矢量网络的每条线段端点作为图节点,线段作为边
  2. 边权重默认为几何长度,也可使用指定属性字段
  3. 找到最近的图节点作为起终点
  4. 使用 networkx.shortest_path(Dijkstra 算法)计算最短路径
  5. 将路径节点序列构建为 LineString

示例

pipeline:
  name: "最短路径分析"

  steps:
    - id: load-network
      use: io.read_vector
      params: { path: "data/road_network.shp" }

    - id: reproject
      use: vector.reproject
      params:
        input: "$load-network"
        target_crs: "EPSG:3857"

    - id: find-path
      use: network.shortest_path
      params:
        input: "$reproject"
        origin: [12952000, 4835000]       # EPSG:3857 坐标
        destination: [12960000, 4840000]
        weight: "travel_time"              # 按行驶时间最短
      on_error: fail

    - id: save-path
      use: io.write_vector
      params:
        input: "$find-path"
        path: "output/shortest_path.geojson"
        format: "GeoJSON"

  outputs:
    path_cost: "$find-path.path_cost"
    path_length: "$find-path.path_length"

注意:若起终点之间没有连通路径,步骤会抛出 ValueError: No path found。建议配合 on_error: fail 快速发现网络连通性问题。


11.4 network.service_area:服务区分析

从指定起点出发,计算在给定代价限制内能到达的所有节点,并构建服务区多边形(等时圈或等距圈)。

参数

参数 类型 必填 默认值 说明
input geodataframe 输入线矢量网络
origin list 服务中心点坐标 [x, y]
max_cost number 最大代价(距离/时间上限)
weight string 权重字段名;不指定则使用几何长度

输出

属性 类型 说明
output GeoDataFrame 服务区多边形(Polygon),由可达节点的凸包构建
stats.reachable_nodes int 可达节点数量
stats.max_cost float 实际使用的最大代价

示例

pipeline:
  name: "医院 15 分钟步行服务区"

  steps:
    - id: load-network
      use: io.read_vector
      params: { path: "data/street_network.shp" }

    - id: reproject
      use: vector.reproject
      params:
        input: "$load-network"
        target_crs: "EPSG:3857"

    # 步行速度约 80 米/分钟,15 分钟 = 1200 米
    - id: service-area
      use: network.service_area
      params:
        input: "$reproject"
        origin: [12953000, 4836000]     # 医院坐标(EPSG:3857)
        max_cost: 1200                  # 1200 米

    - id: save-service-area
      use: io.write_vector
      params:
        input: "$service-area"
        path: "output/hospital_15min.geojson"
        format: "GeoJSON"

11.5 network.geocode:地理编码

将地址字符串列表批量转换为地理坐标,使用 geopy 库,目前支持 Nominatim(OpenStreetMap 数据)。

参数

参数 类型 必填 默认值 说明
addresses list 地址字符串列表
provider string nominatim 地理编码服务(当前仅支持 nominatim
user_agent string geopipe-agent HTTP User-Agent(Nominatim 要求非空且唯一)

输出

属性 类型 说明
output GeoDataFrame 地理编码结果点数据(CRS: EPSG:4326)。含 addressresolved_addresslatitudelongitude 字段
stats.total int 输入地址总数
stats.success int 成功编码数量
stats.failed int 失败数量
stats.failed_addresses list 失败的地址列表

示例

pipeline:
  name: "学校地理编码"

  steps:
    - id: geocode-schools
      use: network.geocode
      params:
        addresses:
          - "北京市海淀区清华大学"
          - "北京市海淀区北京大学"
          - "北京市朝阳区中国传媒大学"
        provider: "nominatim"
        user_agent: "my-gis-project"    # 自定义标识,避免被限速
      on_error: retry    # 网络问题时重试

    - id: save-locations
      use: io.write_vector
      params:
        input: "$geocode-schools"
        path: "output/schools.geojson"
        format: "GeoJSON"

  outputs:
    success_count: "$geocode-schools.success"
    failed_count: "$geocode-schools.failed"

使用限制:Nominatim 是开放服务,有使用速率限制(1 请求/秒)。批量地理编码时请设置合理的 user_agent 并注意请求频率。商业场景建议使用付费地理编码 API。


11.6 网络分析注意事项

6.1 网络数据质量要求

网络分析步骤将线矢量网络转换为图,网络数据质量直接影响分析结果:

  • 连通性:道路线必须在端点处精确相交,存在悬挂线或缺口会导致网络不连通
  • 方向性:当前实现为无向图,不区分单行道方向
  • 坐标系:建议使用投影坐标系(单位米)进行距离计算,使用 WGS84(度)时权重单位为度

6.2 数据预处理建议

# 最短路径分析前的数据准备
steps:
  - id: load-roads
    use: io.read_vector
    params: { path: "data/roads.shp" }

  # 过滤出可通行道路
  - id: filter-passable
    use: vector.query
    params:
      input: "$load-roads"
      expr: "road_class not in ['footway', 'cycleway']"

  # 转换为米制坐标
  - id: reproject
    use: vector.reproject
    params:
      input: "$filter-passable"
      target_crs: "EPSG:3857"

  - id: find-path
    use: network.shortest_path
    params:
      input: "$reproject"
      origin: [12952000, 4835000]
      destination: [12960000, 4840000]

11.7 本章小结

本章介绍了 3 个网络分析步骤(需安装 [network] 依赖):

  1. network.shortest_path:Dijkstra 最短路径算法,支持自定义权重字段,网络不连通时报错
  2. network.service_area:从起点出发的可达服务区,基于代价限制(距离/时间),结果为凸包多边形
  3. network.geocode:批量地址→坐标转换,使用 Nominatim,注意使用频率限制,建议配 on_error: retry

导航← 第十章:空间分析步骤第十二章:数据质检步骤 →