znlgis 博客

GIS开发与技术分享

第十章:高级分析与网络分析步骤

10.1 概述

除了基础的矢量和栅格操作,GeoPipeAgent 还提供了高级空间分析和网络分析步骤。这些步骤依赖可选的第三方库(SciPy、scikit-learn、NetworkX、geopy),需要额外安装。

高级分析步骤(analysis 类别)

Step ID 名称 依赖
analysis.voronoi 泰森多边形 scipy
analysis.heatmap 热力图 scipy
analysis.interpolate 空间插值 scipy
analysis.cluster 空间聚类 scikit-learn

网络分析步骤(network 类别)

Step ID 名称 依赖
network.shortest_path 最短路径 networkx
network.service_area 服务区分析 networkx
network.geocode 地理编码 geopy

安装可选依赖:

pip install geopipe-agent[analysis]    # SciPy + scikit-learn + matplotlib
pip install geopipe-agent[network]     # NetworkX + geopy
pip install geopipe-agent[analysis,network]  # 全部安装

10.2 analysis.voronoi — 泰森多边形

10.2.1 功能说明

根据输入的点数据生成泰森多边形(Voronoi Diagram),也称为 Thiessen 多边形。泰森多边形将空间划分为若干区域,每个区域内的任意点到对应输入点的距离最近。

常用场景:

  • 气象站观测区域划分
  • 服务设施的最近服务区分析
  • 空间分区

10.2.2 参数

参数 类型 必需 默认值 说明
input geodataframe 输入点数据
boundary geodataframe 裁剪边界(可选)

10.2.3 使用示例

pipeline:
  name: "泰森多边形分析"
  steps:
    - id: read-stations
      use: io.read_vector
      params:
        path: "data/weather_stations.shp"
    - id: voronoi
      use: analysis.voronoi
      params:
        input: "$read-stations.output"
    - id: save
      use: io.write_vector
      params:
        input: "$voronoi.output"
        path: "output/voronoi.geojson"

10.2.4 实现原理

使用 scipy.spatial.Voronoi 算法计算泰森多边形,然后通过 Shapely 将结果转换为 Polygon 几何对象。如果提供了裁剪边界,会用边界裁剪泰森多边形。

10.3 analysis.heatmap — 热力图

10.3.1 功能说明

从点数据生成核密度热力图(Kernel Density Estimation),输出为栅格数据。

10.3.2 参数

参数 类型 必需 默认值 说明
input geodataframe 输入点数据
resolution number 100 输出栅格分辨率
bandwidth number 核函数带宽(自动计算)

10.3.3 使用示例

- id: heatmap
  use: analysis.heatmap
  params:
    input: "$read-incidents.output"
    resolution: 50

10.3.4 实现原理

使用 scipy.ndimage 的高斯核密度估计计算热力图。输出是一个栅格数据字典,可以用 io.write_raster 保存为 GeoTIFF。

10.4 analysis.interpolate — 空间插值

10.4.1 功能说明

从散点观测数据进行空间插值,生成连续的栅格表面。支持反距离加权(IDW)和其他 SciPy 插值方法。

10.4.2 参数

参数 类型 必需 默认值 说明
input geodataframe 输入点数据
value_field string 插值属性字段名
method string idw 插值方法(idw/linear/cubic)
resolution number 100 输出栅格分辨率
power number 2 IDW 的幂参数

10.4.3 使用示例

IDW 温度插值:

pipeline:
  name: "温度空间插值"
  steps:
    - id: read-stations
      use: io.read_vector
      params:
        path: "data/temperature_stations.shp"
    - id: interpolate
      use: analysis.interpolate
      params:
        input: "$read-stations.output"
        value_field: "temperature"
        method: "idw"
        resolution: 100
        power: 2
    - id: save
      use: io.write_raster
      params:
        input: "$interpolate.output"
        path: "output/temperature_surface.tif"

10.4.4 插值方法

方法 说明 特点
idw 反距离加权 简单直观,适合均匀分布点
linear 线性插值 SciPy griddata,适合密集采样
cubic 三次插值 平滑结果,需要更多计算资源

10.5 analysis.cluster — 空间聚类

10.5.1 功能说明

对空间数据进行聚类分析,将空间上邻近的要素归为同一类。支持 DBSCAN 和 KMeans 两种算法。

10.5.2 参数

参数 类型 必需 默认值 说明
input geodataframe 输入矢量数据
method string dbscan 聚类算法
eps number 0.01 DBSCAN 邻域半径
min_samples number 5 DBSCAN 最小样本数
n_clusters number 5 KMeans 聚类数

10.5.3 使用示例

DBSCAN 聚类:

- id: cluster
  use: analysis.cluster
  params:
    input: "$read-points.output"
    method: "dbscan"
    eps: 0.01
    min_samples: 5

KMeans 聚类:

- id: cluster
  use: analysis.cluster
  params:
    input: "$read-points.output"
    method: "kmeans"
    n_clusters: 8

10.5.4 输出

聚类结果会在输入数据中新增一个 cluster 列,包含每个要素的聚类标签。DBSCAN 中 -1 表示噪声点。

10.6 network.shortest_path — 最短路径

10.6.1 功能说明

在路网图上计算两点之间的最短路径。使用 NetworkX 图论算法实现。

10.6.2 参数

参数 类型 必需 默认值 说明
input geodataframe 路网数据(线要素)
origin dict/list 起点坐标
destination dict/list 终点坐标
weight string length 权重字段

10.6.3 使用示例

pipeline:
  name: "最短路径分析"
  steps:
    - id: read-roads
      use: io.read_vector
      params:
        path: "data/road_network.shp"
    - id: shortest-path
      use: network.shortest_path
      params:
        input: "$read-roads.output"
        origin: [116.39, 39.91]
        destination: [116.46, 39.92]
        weight: "length"
    - id: save
      use: io.write_vector
      params:
        input: "$shortest-path.output"
        path: "output/shortest_path.geojson"

10.6.4 实现原理

  1. 将线要素 GeoDataFrame 转换为 NetworkX 图(Graph)
  2. 找到距离起点和终点最近的图节点
  3. 使用 Dijkstra 算法计算最短路径
  4. 将路径转换回 GeoDataFrame

10.7 network.service_area — 服务区分析

10.7.1 功能说明

计算从中心点出发在给定距离或时间内可达的服务区范围(等时圈/等距圈)。

10.7.2 参数

参数 类型 必需 默认值 说明
input geodataframe 路网数据
center dict/list 中心点坐标
distance number 服务区距离/时间
weight string length 权重字段

10.7.3 使用示例

- id: service-area
  use: network.service_area
  params:
    input: "$read-roads.output"
    center: [116.39, 39.91]
    distance: 5000            # 5 公里服务区
    weight: "length"

10.7.4 实现原理

使用 NetworkX 的 ego_graph 或距离限制的遍历算法,找到从中心点出发在给定距离内可达的所有节点和边,然后将可达的边转换为 GeoDataFrame。

10.8 network.geocode — 地理编码

10.8.1 功能说明

将地址文本转换为地理坐标(经纬度),使用 geopy 的 Nominatim 服务。

10.8.2 参数

参数 类型 必需 默认值 说明
input geodataframe 输入数据(含地址字段)
address_field string 地址字段名
provider string nominatim 地理编码服务

10.8.3 使用示例

- id: geocode
  use: network.geocode
  params:
    input: "$read-addresses.output"
    address_field: "address"

10.8.4 注意事项

  • Nominatim 服务有请求频率限制,大批量地理编码需要注意间隔
  • 地理编码结果的准确性取决于地址的标准化程度
  • 建议在使用前先对地址数据进行清洗和标准化

10.9 高级分析综合案例

10.9.1 城市犯罪热点分析

pipeline:
  name: "犯罪热点分析"
  description: "使用核密度估计和聚类分析识别犯罪热点"
  steps:
    # 读取犯罪数据
    - id: read-crimes
      use: io.read_vector
      params:
        path: "data/crime_incidents.shp"

    # 生成热力图
    - id: heatmap
      use: analysis.heatmap
      params:
        input: "$read-crimes.output"
        resolution: 50

    # DBSCAN 聚类
    - id: cluster
      use: analysis.cluster
      params:
        input: "$read-crimes.output"
        method: "dbscan"
        eps: 0.005
        min_samples: 10

    # 保存聚类结果
    - id: save-clusters
      use: io.write_vector
      params:
        input: "$cluster.output"
        path: "output/crime_clusters.geojson"

    # 保存热力图
    - id: save-heatmap
      use: io.write_raster
      params:
        input: "$heatmap.output"
        path: "output/crime_heatmap.tif"

  outputs:
    cluster_count: "$cluster.stats"
    heatmap: "$save-heatmap.output"

10.9.2 气象站插值分析

pipeline:
  name: "气象站温度插值"
  steps:
    # 读取气象站数据
    - id: read-stations
      use: io.read_vector
      params:
        path: "data/weather_stations.shp"

    # 生成泰森多边形
    - id: voronoi
      use: analysis.voronoi
      params:
        input: "$read-stations.output"

    # IDW 温度插值
    - id: interpolate
      use: analysis.interpolate
      params:
        input: "$read-stations.output"
        value_field: "temperature"
        method: "idw"
        resolution: 100

    # 生成等温线
    - id: contour
      use: raster.contour
      params:
        input: "$interpolate.output"
        interval: 2

    # 保存结果
    - id: save-voronoi
      use: io.write_vector
      params:
        input: "$voronoi.output"
        path: "output/voronoi.geojson"

    - id: save-contour
      use: io.write_vector
      params:
        input: "$contour.output"
        path: "output/iso_temperature.geojson"

  outputs:
    voronoi: "$save-voronoi.output"
    contour: "$save-contour.output"