znlgis 博客

GIS开发与技术分享

第七章: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 ndarray 栅格数组(shape: [bands, height, width]
metadata.transform Affine 仿射变换矩阵
metadata.crs CRS 坐标参考系
metadata.dtype str 数据类型(如 uint8float32
metadata.nodata float/None NoData 值
metadata.count int 波段数量
metadata.width int 栅格宽度(像素)
metadata.height int 栅格高度(像素)
metadata.bounds BoundingBox 地理范围

示例

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

# 后续步骤使用栅格数据
- id: calc-ndvi
  use: raster.calc
  params:
    input: "$load-multispectral"
    expression: "(band4 - band3) / (band4 + band3)"
    output_bands: 1

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

7.5 io.write_raster:写入栅格数据

参数

参数 类型 必填 默认值 说明
input ndarray 输入栅格数组
path string 输出文件路径
metadata dict 栅格元信息(包含 transform、crs、dtype 等)

说明

io.write_raster 通常与 raster.* 步骤配合使用,其中 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"          # 重投影后的数组
    path: "output/dem_3857.tif"
    metadata: "$reproject-raster.metadata"   # 新的元信息(包含更新后的 transform、crs)

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"
    expr: "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 等栅格文件,返回数组+完整元信息(transform、crs、bands等)
  4. io.write_raster:将栅格数组和元信息写入 GeoTIFF

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


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