第八章:矢量分析步骤详解

矢量分析步骤(vector.*)是 GeoPipeAgent 中使用最频繁的一类步骤,共 7 个,覆盖了日常 GIS 矢量分析的核心操作。所有矢量步骤的默认后端为 native_python(GeoPandas + Shapely)。


8.1 步骤总览

步骤 ID 名称 功能 声明后端(backends)
vector.buffer 缓冲区分析 生成指定距离的缓冲区 native_python, qgis_process
vector.clip 矢量裁剪 用裁剪范围裁剪输入数据 native_python, qgis_process
vector.reproject 投影转换 坐标系转换 native_python, qgis_process
vector.dissolve 融合 按字段融合要素 native_python
vector.simplify 几何简化 Douglas-Peucker 算法简化几何 native_python
vector.query 属性查询 Pandas query 表达式过滤要素 —(不经过后端)
vector.overlay 叠加分析 两图层叠加(交、并、差等) native_python

说明:backends 列取自步骤注册声明(geopipe-agent list-steps 的 Backends 列)。运行时通过步骤的 backend 字段可显式指定任何已安装的后端(如 gdal_cli、gdal_python,它们同样实现了这些矢量算子);若指定的后端未安装则抛出 BackendNotAvailableError。vector.query 未声明后端,直接由步骤函数调用 GeoPandas 完成过滤。


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_geometry 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_geometry: "$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 ❌ — 融合字段名(不指定则将所有要素融合为一个)
aggfunc string ❌ first 属性聚合函数(first、sum、mean、count 等,应用于非分组字段)

输出

属性 类型 说明
output GeoDataFrame 融合后的数据
stats.feature_count int 融合后要素数量

示例

# 按城市融合街道数据(非分组字段取首个值,或对数值字段求和)
- id: dissolve-by-city
  use: vector.dissolve
  params:
    input: "$load-districts"
    by: "city_id"
    aggfunc: "sum"          # 各属性字段求和

# 全部融合为一个多边形
- 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 ✅ — 输入矢量数据
expression string ✅ — Pandas query 表达式

输出

属性 类型 说明
output GeoDataFrame 过滤后的数据
stats.output_count int 过滤后要素数量
stats.input_count int 原始要素数量
stats.expression str 实际使用的表达式

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"
    expression: "road_class in ['highway', 'primary', 'secondary']"

# 过滤高层建筑
- id: filter-tall
  use: vector.query
  params:
    input: "$load-buildings"
    expression: "height > 100 and type == 'commercial'"

# 过滤非空几何(避免空几何导致后续步骤失败)
- id: filter-valid
  use: vector.query
  params:
    input: "$load-data"
    expression: "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", expression: "landuse == 'construction'" }

    - id: filter-2024
      use: vector.query
      params: { input: "$reproject-2024", expression: "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 个矢量分析步骤:

  1. vector.buffer:缓冲区分析,注意 CRS 单位(地理坐标用度,投影坐标用米)
  2. vector.clip:用掩膜图层裁剪数据
  3. vector.reproject:坐标系转换,支持 gdal_cli 后端处理大文件
  4. vector.dissolve:按字段融合要素,支持聚合函数
  5. vector.simplify:几何简化,减少顶点数量
  6. vector.query:Pandas query 表达式属性过滤
  7. vector.overlay:两图层叠加(交、并、差等 5 种方式)

导航:← 第七章:IO 步骤 | 第九章:栅格分析步骤 →