第七章:IO 步骤详解

IO 步骤(io.*)负责地理数据的读取和写入,是每个流水线的入口和出口。GeoPipeAgent 内置 4 个 IO 步骤,支持主流矢量和栅格格式。


7.1 步骤总览

步骤 ID 名称 功能
io.read_vector 读取矢量数据 从文件读取矢量数据为 GeoDataFrame
io.write_vector 写入矢量数据 将 GeoDataFrame 写入矢量文件
io.read_raster 读取栅格数据 从文件读取栅格数据为数组+元信息
io.write_raster 写入栅格数据 将栅格数组写入 GeoTIFF

7.2 io.read_vector:读取矢量数据

参数

参数 类型 必填 默认值 说明
path string ✅ — 矢量文件路径
layer string ❌ — 图层名(多图层文件,如 GPKG)
encoding string ❌ utf-8 文件编码(Shapefile 中文乱码时设为 gbk)

输出(StepResult)

属性 类型 说明
output GeoDataFrame 读取的矢量数据
stats.feature_count int 要素数量
stats.crs str 坐标参考系(如 "EPSG:4326")
stats.geometry_types list 几何类型列表(如 ["Polygon"])
stats.columns list 属性字段名列表

支持格式

格式 文件扩展名
GeoJSON .geojson, .json
Shapefile .shp(需配套 .dbf、.shx)
GeoPackage .gpkg
KML/KMZ .kml, .kmz
其他 GDAL/Fiona 支持格式 见 GDAL 文档

示例

# 基础读取
- id: load-vector
  use: io.read_vector
  params:
    path: "data/buildings.shp"

# 指定编码(中文 Shapefile)
- id: load-cn-data
  use: io.read_vector
  params:
    path: "data/roads_cn.shp"
    encoding: "gbk"

# 读取 GeoPackage 的特定图层
- id: load-layer
  use: io.read_vector
  params:
    path: "data/city.gpkg"
    layer: "buildings"

# 使用变量
- id: load-data
  use: io.read_vector
  params:
    path: "${input_path}"

常用引用

# 后续步骤引用读取结果
- id: buffer
  use: vector.buffer
  params:
    input: "$load-data"            # 引用 GeoDataFrame
    distance: 100

# 在 when 中引用统计信息
- id: check
  use: qc.geometry_validity
  params:
    input: "$load-data"
  when: "$load-data.feature_count > 0"  # 有数据时才执行检查

# 引用字段列表(用于 QC 步骤)
outputs:
  columns: "$load-data.columns"

7.3 io.write_vector:写入矢量数据

参数

参数 类型 必填 默认值 说明
input geodataframe ✅ — 输入矢量数据
path string ✅ — 输出文件路径
format string ❌ GeoJSON 输出格式(见下表)
encoding string ❌ utf-8 文件编码

支持的 format 值

format 值 GDAL Driver 输出格式
GeoJSON GeoJSON .geojson 文件
Shapefile / shp ESRI Shapefile .shp 文件组
GPKG / GeoPackage GPKG .gpkg 文件

输出(StepResult)

属性 类型 说明
output str 输出文件路径(字符串)
stats.feature_count int 写入的要素数量
stats.output_path str 输出路径(与 output 相同)
stats.format str 实际使用的 GDAL Driver 名

示例

# 保存为 GeoJSON
- id: save-geojson
  use: io.write_vector
  params:
    input: "$buffer"
    path: "output/buffer_result.geojson"
    format: "GeoJSON"

# 保存为 Shapefile
- id: save-shapefile
  use: io.write_vector
  params:
    input: "$dissolve"
    path: "output/dissolved.shp"
    format: "Shapefile"

# 保存为 GeoPackage
- id: save-gpkg
  use: io.write_vector
  params:
    input: "$process"
    path: "output/result.gpkg"
    format: "GPKG"

# 使用变量控制格式
- id: save-result
  use: io.write_vector
  params:
    input: "$process"
    path: "${output_path}"
    format: "${output_format}"

说明

  • 自动创建目录:输出路径的父目录不存在时会自动创建(mkdir -p)
  • 覆盖行为:若目标文件已存在,默认覆盖
  • write_vector 输出:output 字段是字符串(文件路径),而非 GeoDataFrame。outputs 声明中引用此步骤得到的是路径字符串。

7.4 io.read_raster:读取栅格数据

参数

参数 类型 必填 默认值 说明
path string ✅ — 栅格文件路径

输出(StepResult)

output 是一个 raster_info 字典(不是裸数组),供后续 raster.* 步骤直接引用:

键 类型 说明
output.data ndarray 像素数组(shape: [bands, height, width])
output.transform Affine 仿射变换矩阵
output.crs CRS 坐标参考系
output.profile dict rasterio 完整写入参数(含 dtype、nodata、count 等)
output.path str 源文件路径

统计信息位于 stats(可通过 $step.<key> 引用):

属性 类型 说明
stats.width / stats.height int 栅格尺寸(像素)
stats.crs str 坐标参考系
stats.band_count int 波段数量
stats.dtype str 数据类型(如 uint8、float32)
stats.bounds list 地理范围

示例

# 读取 GeoTIFF
- id: load-dem
  use: io.read_raster
  params:
    path: "data/dem.tif"

# 后续步骤使用栅格数据(raster_info 字典整体传递)
- id: calc-ndvi
  use: raster.calc
  params:
    input: "$load-multispectral"
    expression: "(B4 - B3) / (B4 + B3)"

- id: get-stats
  use: raster.stats
  params:
    input: "$load-dem"

7.5 io.write_raster:写入栅格数据

参数

参数 类型 必填 默认值 说明
input raster_info ✅ — 输入栅格数据(包含 data、profile 的字典)
path string ✅ — 输出文件路径

输出(StepResult)

属性 类型 说明
output str 输出文件路径(字符串)
stats.output_path str 输出路径
stats.width / stats.height int 写入尺寸(取自 profile)

说明

io.write_raster 通常与 io.read_raster / raster.* 步骤配合使用:写入所需的 transform、crs、dtype 等元信息已随 raster_info 字典中的 profile 一起传递,无需单独的 metadata 参数:

- id: load-raster
  use: io.read_raster
  params:
    path: "data/dem.tif"

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

- id: save-raster
  use: io.write_raster
  params:
    input: "$reproject-raster"     # 重投影后的 raster_info(含更新后的 profile)
    path: "output/dem_3857.tif"

输出目录不存在时会自动创建。


7.6 IO 步骤最佳实践

6.1 始终检查 CRS

读取数据后,及时检查坐标系,避免后续分析因 CRS 不匹配而失败:

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

- id: check-crs
  use: qc.crs_check
  params:
    input: "$load-data"
    expected_crs: "EPSG:4326"
  on_error: skip

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

6.2 先用 geopipe-agent info 了解数据

geopipe-agent info data/roads.shp
# 输出:feature_count, crs, geometry_types, columns, bounds

6.3 Shapefile 中文编码

中国区域数据常见 GBK 编码的 Shapefile:

- id: load-cn-roads
  use: io.read_vector
  params:
    path: "data/roads_china.shp"
    encoding: "gbk"              # 避免属性字段中文乱码

6.4 大文件处理建议

对于大型矢量文件,可以先用 vector.query 过滤需要的数据,减少后续处理量:

- id: load-all
  use: io.read_vector
  params: { path: "data/national_roads.shp" }

- id: filter-major
  use: vector.query
  params:
    input: "$load-all"
    expression: "road_class in ['highway', 'primary']"   # 只保留主要道路

7.7 本章小结

本章详细介绍了 4 个 IO 步骤:

  1. io.read_vector:支持 GeoJSON、Shapefile、GPKG 等格式,返回 GeoDataFrame,可查看 feature_count、crs、columns 等统计信息
  2. io.write_vector:将 GeoDataFrame 写入文件,支持 GeoJSON/Shapefile/GPKG,自动创建输出目录
  3. io.read_raster:读取 GeoTIFF 等栅格文件,output 为 raster_info 字典(data/transform/crs/profile),stats 提供 width、height、band_count、dtype、bounds 等
  4. io.write_raster:接收含 data 和 profile 的 raster_info 字典,写入 GeoTIFF 等栅格文件,自动创建输出目录

下一章将介绍矢量分析步骤,包括缓冲、裁剪、投影转换等 7 个步骤。


导航:← 第六章:条件执行与错误策略 | 第八章:矢量分析步骤 →