第八章:矢量分析步骤详解
矢量分析步骤(vector.*)是 GeoPipeAgent 中使用最频繁的一类步骤,共 7 个,覆盖了日常 GIS 矢量分析的核心操作。所有矢量步骤的默认后端为 native_python(GeoPandas + Shapely)。
8.1 步骤总览
| 步骤 ID |
名称 |
功能 |
支持后端 |
vector.buffer |
缓冲区分析 |
生成指定距离的缓冲区 |
native_python, qgis_process |
vector.clip |
矢量裁剪 |
用裁剪范围裁剪输入数据 |
native_python, qgis_process |
vector.reproject |
投影转换 |
坐标系转换 |
native_python, gdal_cli, qgis_process |
vector.dissolve |
融合 |
按字段融合要素 |
native_python, qgis_process |
vector.simplify |
几何简化 |
Douglas-Peucker 算法简化几何 |
native_python |
vector.query |
属性查询 |
Pandas query 表达式过滤要素 |
native_python |
vector.overlay |
叠加分析 |
两图层叠加(交、并、差等) |
native_python |
8.2 vector.buffer:缓冲区分析
参数
| 参数 |
类型 |
必填 |
默认值 |
说明 |
input |
geodataframe |
✅ |
— |
输入矢量数据 |
distance |
number |
✅ |
— |
缓冲距离(单位取决于 CRS) |
cap_style |
string |
❌ |
round |
端点样式:round(圆形)/flat(平头)/square(方形) |
输出
| 属性 |
类型 |
说明 |
output |
GeoDataFrame |
缓冲区多边形数据 |
stats.total_area |
float |
缓冲区总面积 |
⚠️ 坐标系注意:使用 EPSG:4326(度)时,distance 单位是度(约 1 度 ≈ 111 公里)。要用米为单位,需先用 vector.reproject 转换到投影坐标系(如 EPSG:3857 或当地区域 CRS)。
示例
# 基础缓冲
- id: buffer
use: vector.buffer
params:
input: "$load-roads"
distance: 500 # EPSG:3857 下为 500 米
cap_style: "round"
# 使用变量
- id: buffer-dynamic
use: vector.buffer
params:
input: "$reproject"
distance: "${buffer_dist}"
cap_style: "${cap_style}"
8.3 vector.clip:矢量裁剪
参数
| 参数 |
类型 |
必填 |
默认值 |
说明 |
input |
geodataframe |
✅ |
— |
被裁剪数据 |
clip |
geodataframe |
✅ |
— |
裁剪范围(掩膜)数据 |
输出
| 属性 |
类型 |
说明 |
output |
GeoDataFrame |
裁剪后的数据 |
stats.feature_count |
int |
裁剪后要素数量 |
示例
- id: load-data
use: io.read_vector
params: { path: "data/national_roads.shp" }
- id: load-boundary
use: io.read_vector
params: { path: "data/city_boundary.shp" }
- id: clip-to-city
use: vector.clip
params:
input: "$load-data"
clip: "$load-boundary"
8.4 vector.reproject:投影转换
参数
| 参数 |
类型 |
必填 |
默认值 |
说明 |
input |
geodataframe |
✅ |
— |
输入矢量数据 |
target_crs |
string |
✅ |
— |
目标坐标系(EPSG 代码) |
输出
| 属性 |
类型 |
说明 |
output |
GeoDataFrame |
转换后的数据 |
stats.source_crs |
str |
源坐标系 |
stats.target_crs |
str |
目标坐标系 |
常用坐标系参考
| EPSG |
说明 |
单位 |
| EPSG:4326 |
WGS84 地理坐标系 |
度 |
| EPSG:3857 |
Web Mercator(全球) |
米 |
| EPSG:4549 |
CGCS2000 / 3度带(中国) |
米 |
| EPSG:32650 |
WGS84 UTM Zone 50N |
米 |
示例
# WGS84 → Web Mercator(用于距离缓冲)
- id: reproject-to-3857
use: vector.reproject
params:
input: "$load-data"
target_crs: "EPSG:3857"
# 支持 gdal_cli 后端(适合大文件)
- id: reproject-large
use: vector.reproject
params:
input: "$load-big-data"
target_crs: "EPSG:4549"
backend: gdal_cli
8.5 vector.dissolve:融合
参数
| 参数 |
类型 |
必填 |
默认值 |
说明 |
input |
geodataframe |
✅ |
— |
输入矢量数据 |
by |
string |
❌ |
— |
融合字段名(不指定则将所有要素融合为一个) |
agg |
dict |
❌ |
— |
聚合函数字典(如 {"population": "sum", "name": "first"}) |
输出
| 属性 |
类型 |
说明 |
output |
GeoDataFrame |
融合后的数据 |
stats.feature_count |
int |
融合后要素数量 |
示例
# 按城市融合街道数据
- id: dissolve-by-city
use: vector.dissolve
params:
input: "$load-districts"
by: "city_id"
agg:
population: "sum" # 人口求和
name: "first" # 取第一个名称
# 全部融合为一个多边形
- id: dissolve-all
use: vector.dissolve
params:
input: "$load-polygons"
# 不设置 by,融合所有要素
8.6 vector.simplify:几何简化
参数
| 参数 |
类型 |
必填 |
默认值 |
说明 |
input |
geodataframe |
✅ |
— |
输入矢量数据 |
tolerance |
number |
✅ |
— |
简化容差(单位取决于 CRS) |
preserve_topology |
boolean |
❌ |
true |
是否保持拓扑关系 |
输出
| 属性 |
类型 |
说明 |
output |
GeoDataFrame |
简化后的数据 |
stats.feature_count |
int |
要素数量(不变) |
示例
# 在 EPSG:3857 坐标系下,5 米容差简化
- id: simplify-roads
use: vector.simplify
params:
input: "$reproject"
tolerance: 5.0
preserve_topology: true
on_error: skip # 简化失败时用原始数据继续
8.7 vector.query:属性查询
参数
| 参数 |
类型 |
必填 |
默认值 |
说明 |
input |
geodataframe |
✅ |
— |
输入矢量数据 |
expr |
string |
✅ |
— |
Pandas query 表达式 |
输出
| 属性 |
类型 |
说明 |
output |
GeoDataFrame |
过滤后的数据 |
stats.feature_count |
int |
过滤后要素数量 |
stats.original_count |
int |
原始要素数量 |
Pandas Query 表达式语法
"field == 'value'" # 字符串等值
"field > 100" # 数值比较
"field in ['a', 'b', 'c']" # 枚举
"field1 == 'x' and field2 > 0" # 复合条件
"not field.isna()" # 空值过滤
示例
# 过滤主要道路
- id: filter-major
use: vector.query
params:
input: "$load-roads"
expr: "road_class in ['highway', 'primary', 'secondary']"
# 过滤高层建筑
- id: filter-tall
use: vector.query
params:
input: "$load-buildings"
expr: "height > 100 and type == 'commercial'"
# 过滤非空几何(避免空几何导致后续步骤失败)
- id: filter-valid
use: vector.query
params:
input: "$load-data"
expr: "not geometry.is_empty"
8.8 vector.overlay:叠加分析
参数
| 参数 |
类型 |
必填 |
默认值 |
说明 |
input |
geodataframe |
✅ |
— |
输入矢量数据 |
overlay_layer |
geodataframe |
✅ |
— |
叠加图层 |
how |
string |
❌ |
intersection |
叠加方式(见下表) |
how 叠加方式
| 值 |
说明 |
intersection |
求交集:保留两图层重叠部分 |
union |
求并集:合并两图层所有要素 |
difference |
求差集:input 中去掉与 overlay_layer 重叠的部分 |
symmetric_difference |
对称差集:两图层各自非重叠部分 |
identity |
恒等叠加:保留 input 全部,叠加 overlay 属性 |
输出
| 属性 |
类型 |
说明 |
output |
GeoDataFrame |
叠加分析结果 |
stats.overlay_method |
str |
使用的叠加方式 |
stats.feature_count |
int |
结果要素数量 |
示例
- id: load-parcels
use: io.read_vector
params: { path: "data/parcels.shp" }
- id: load-flood-zone
use: io.read_vector
params: { path: "data/flood_zone.shp" }
# 求取洪泛区内的地块
- id: overlay-intersection
use: vector.overlay
params:
input: "$load-parcels"
overlay_layer: "$load-flood-zone"
how: "intersection"
# 保留洪泛区外的地块
- id: overlay-difference
use: vector.overlay
params:
input: "$load-parcels"
overlay_layer: "$load-flood-zone"
how: "difference"
8.9 矢量步骤综合示例:土地利用分析
pipeline:
name: "城市扩张分析"
description: "分析某城市 2020-2024 年建设用地扩张,计算新增建设用地面积"
variables:
base_path: "data/landuse_2020.shp"
new_path: "data/landuse_2024.shp"
output_path: "output/new_construction.geojson"
target_crs: "EPSG:4549"
steps:
- id: load-2020
use: io.read_vector
params: { path: "${base_path}" }
- id: load-2024
use: io.read_vector
params: { path: "${new_path}" }
# 统一坐标系(投影坐标,单位米)
- id: reproject-2020
use: vector.reproject
params: { input: "$load-2020", target_crs: "${target_crs}" }
- id: reproject-2024
use: vector.reproject
params: { input: "$load-2024", target_crs: "${target_crs}" }
# 过滤出建设用地
- id: filter-2020
use: vector.query
params: { input: "$reproject-2020", expr: "landuse == 'construction'" }
- id: filter-2024
use: vector.query
params: { input: "$reproject-2024", expr: "landuse == 'construction'" }
# 新增建设用地 = 2024建设用地 - 2020建设用地
- id: new-construction
use: vector.overlay
params:
input: "$filter-2024"
overlay_layer: "$filter-2020"
how: "difference"
- id: save-result
use: io.write_vector
params:
input: "$new-construction"
path: "${output_path}"
format: "GeoJSON"
outputs:
result: "$save-result"
new_area_count: "$new-construction.feature_count"
8.10 本章小结
本章介绍了 7 个矢量分析步骤:
vector.buffer:缓冲区分析,注意 CRS 单位(地理坐标用度,投影坐标用米)
vector.clip:用掩膜图层裁剪数据
vector.reproject:坐标系转换,支持 gdal_cli 后端处理大文件
vector.dissolve:按字段融合要素,支持聚合函数
vector.simplify:几何简化,减少顶点数量
vector.query:Pandas query 表达式属性过滤
vector.overlay:两图层叠加(交、并、差等 5 种方式)
导航:← 第七章:IO 步骤 | 第九章:栅格分析步骤 →