第十章:高级分析与网络分析步骤
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 实现原理
- 将线要素 GeoDataFrame 转换为 NetworkX 图(Graph)
- 找到距离起点和终点最近的图节点
- 使用 Dijkstra 算法计算最短路径
- 将路径转换回 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"