乐于分享
好东西不私藏

GeoAI矢量化要求

GeoAI矢量化要求

本文档基于 GeoAI 项目源码深度分析及行业最佳实践,系统阐述面向深度学习训练的**矢量标注(Vector Annotation)**规范。在整个 GeoAI 项目 的工作链条中,“标签(Label)”并不是一个简单的附属物,而是决定模型认知边界的核心数据。GeoAI 中的大量训练流程,本质上都是:

遥感影像(Raster) + 矢量标注(Vector Label) → 栅格标签(Mask) → 模型训练

因此,“矢量标注阶段”实际上就是传统 GIS 中的:遥感影像目标矢量化。但 GeoAI 里的“矢量化”与传统测绘制图中的“矢量化”又略有区别。


矢量标注 vs.矢量化

矢量化的广义定义

矢量化(Vectorization) 是 GIS 领域的通用术语,指将栅格数据(如扫描地图、遥感影像)转换为矢量数据(点、线、面)的过程。其目的多样:

  • • 地图数字化与制图
  • • 空间数据库建设
  • • 地物边界提取
  • • 地籍
  • • 测绘成果
  • • 空间分析

矢量标注的特定定义

在 GeoAI 项目中,矢量标注(Vector Annotation) 是矢量化在深度学习场景下的专业化子集。它强调:

维度
通用矢量化
GeoAI 矢量标注
目的
制图、分析、存档,面向地图表达
为神经网络训练提供监督信号,面向地图表达
属性要求
可包含复杂属性
必须包含类别字段
(如 class),属性尽量简单
几何精度
满足制图精度,强调几何精度
需与影像像素级对齐,强调语义一致性
拓扑要求
视应用场景而定
严格要求无重叠、无缝隙
坐标系
按项目要求,可多尺度混合
必须与参考影像完全一致
输出格式
SHP/GeoJSON/GDB 等
最终需栅格化为单波段掩膜

矢量标注 = 面向 AI 训练的、带类别属性的、与影像严格对齐的矢量化成果。

当你拿到一张高清影像图,在 GIS 软件中勾绘建筑、植被、水系的边界并赋予类别属性时,你正在进行的就是矢量标注

SHP 图层结构设计

图层命名

建议:{区域标识}_{任务类型}_{版本号}_{日期},如beijing_building_2026.shp,nanjing_vegetation_2026.shp,不要随意其名称,因为后期数据量会指数爆炸。

字段设计

GeoAI 标签字段:越简单越好,训练阶段通常只需要:

字段名
类型
说明
id
int
唯一ID
class
*
int/string
类别
name
string
类别名称
source
string
数据来源
confidence
float
置信度(可选)

推荐最小训练字段只id 和class字段,如果要进行语义增强,使用id、class、classname、source、remark。方便数据治理也符合STAC规范。

编码推荐:

class 值
类别名称
说明
0
背景(Background)
保留值,矢量文件中不应出现
1
建筑(Building)
人工建筑、房屋、厂房
2
植被(Vegetation)
林地、草地、农田
3
水体(Water)
河流、湖泊、池塘
4
道路(Road)
公路、街道、铁路
5
裸地(Bare Soil)
未利用地、建筑工地

内容两种组织方式对比

假设需要标注建筑、植被、水系三类地物,有两种数据组织策略:

策略 A:多个单种类 SHP(Single-class Multi-layer)

project_annotations/├── buildings.shp          # 仅含建筑,class=1├── vegetation.shp         # 仅含植被,class=2└── water.shp              # 仅含水系,class=3

策略 B:单一综合 SHP(Multi-class Single Layer)

project_annotations/└── landcover_annotations.shp    # 含所有地物,class 字段区分类别

深度对比分析

对比维度
策略 A:多个单种类 SHP
策略 B:综合 SHP
GeoAI 源码支持度
需手动合并或分别栅格化后叠加
原生支持
export_geotiff_tiles_batch 直接读取单文件
class_value_field
 处理
每个文件 class 值固定,灵活性差
同一字段存储多类别值,自动映射为像素 ID
空间一致性保证
多文件间易出现缝隙、重叠
单文件内可通过拓扑检查统一控制
类别冲突处理
多文件栅格化时后覆盖前,类别优先级难以控制
np.maximum
 取高值,或按绘制顺序控制,相对容易
标注效率
需频繁切换图层,易遗漏
同一图层内连续标注,效率更高
数据管理
文件数量随类别线性增长
文件数量恒定,易于版本控制
目标检测
非常合适
一般
语义分割
一般
非常合适
COCO/YOLO 导出
需额外合并步骤
直接导出,类别映射自动完成
实例分割支持
每个文件天然为单类,但实例 ID 需额外处理
需 instance_class_value_field 区分类别与实例

推荐方案

做语义分割,推荐综合shp,适用模型:UNet、DeepLab、SegFormer、SAM 微调

做目标检测,推荐单类别shp,适用模型:YOLO、MMDetection、Detectron2

GeoAI 源码证据

在 geoai/utils/training.py 中,核心切分函数 _process_image_mask_pair 对矢量数据的处理逻辑如下:

# Check if class_value_field existsif class_value_field in gdf.columns:    unique_classes = gdf[class_value_field].unique()# Create class mapping: 自动将任意类别值映射为 1, 2, 3...    class_to_id = {cls: i + 1for i, cls inenumerate(unique_classes)}else:    class_to_id = {11}  # Default mapping

关键结论:GeoAI 的栅格化引擎天然设计为处理单文件多类别输入。它会自动提取 class_value_field 中的唯一值,并将其映射为连续的整数类别 ID。若使用多个单种类 SHP,则需:

  1. 1. 分别读取每个文件;
  2. 2. 手动指定每个文件的类别 ID;
  3. 3. 栅格化后通过 np.maximum 或波段叠加合并;
  4. 4. 极易引入对齐误差和缝隙。

在 geoai/utils/training.py 的瓦片级栅格化代码中:

for idx, feature in window_features.iterrows():    class_val = feature[class_value_field] if class_value_field in feature else1    class_id = class_to_id.get(class_val, 1)    feature_mask = features.rasterize(        [(geom, class_id)], ...    )    label_mask = np.maximum(label_mask, feature_mask)  # 高值优先

这进一步证明:单文件多类别是 GeoAI 的一等公民,多文件需额外适配。

类别映射表

每个矢量标注文件必须附带一个类别映射表(JSON 或 YAML),明确 class 值与语义之间的对应关系:

{"0":"background","1":"building","2":"vegetation","3":"water","4":"road","5":"bare_soil"}

此映射表用于:

  • • 训练时配置 num_classes
  • • 推理结果可视化时赋予颜色与图例;
  • • 多项目协作时统一语义理解。

几何与拓扑规范

Remote Sensing Image Semantic Segmentation Sample Generation Using a ...

几何类型选择

地物类型
推荐几何类型
说明
建筑、水体、农田
Polygon(多边形)
面状地物,最常用
道路、河流
LineString / Polygon
线状地物可用线,但栅格化时建议缓冲为面

GeoAI 优先处理 Polygon。对于线状或点状地物,建议在标注阶段通过 buffer_radius 扩展为面状,或在 GeoAI 导出时设置 buffer_radius 参数。

拓扑规则

QGIS基础:创建矢量数据(栅格矢量化)_qgis矢量图栅格化-CSDN博客
规则
要求
检查工具
无重叠(No Overlap)
同类或不同类多边形之间不得重叠
QGIS 拓扑检查 / ArcGIS Topology
无缝隙(No Gaps)
相邻地物边界应完全贴合
QGIS 拓扑检查
无自相交(No Self-intersection)
单个多边形不得自相交
shapely.is_valid
无悬挂节点
线要素端点应闭合或连接
拓扑检查

重叠处理原则

在 GeoAI 栅格化时,若多边形重叠,后绘制的多边形会覆盖先绘制的(np.maximum 取高值)。为避免不确定性,应在矢量阶段消除重叠:

  • • 建筑压盖植被 → 优先保留建筑,从植被中裁剪出建筑区域;
  • • 道路穿越农田 → 道路与农田边界应完全重合。

边界精度要求

  • • 配准误差:矢量边界与影像地物边界的偏差应 ≤ 0.5 个像元
  • • 最小图斑:面积小于 4 × 4 像元 的地物建议合并到相邻类别或不单独标注;
  • • 简化容差:矢量简化(Simplify)的容差应 ≤ 0.5 个像元,避免过度平滑。

坐标系与投影规范

坐标系选择

场景
推荐坐标系
说明
一般区域
UTM 投影
(EPSG:326xx / 327xx)
保证面积、距离计算准确
中国区域
CGCS2000 / 高斯-克吕格(EPSG:4490 + 3/6度带)
符合国家规范
全球分析
WGS84(EPSG:4326)
仅用于小比例尺,不推荐用于标注

与影像的对齐要求

矢量标注的 CRS 必须与参考影像完全一致

GeoAI 在读取矢量时会自动检查并重投影:

if gdf.crs != src.crs:    gdf = gdf.to_crs(src.crs)

自动重投影会引入微小变形,因此最佳实践是:

在标注阶段就将影像和矢量统一为同一投影坐标系。


数据格式问题

Shapefile 严格来说已经不是最佳选择。Shapefile 有大量历史问题:

  • • 字段名最长10字符
  • • 中文乱码问题
  • • 多文件依赖
  • • NULL 支持差

现在越来越推荐:

  • • GeoPackage
  • • GeoJSON
  • • FlatGeobuf

推荐目录结构

dataset/├── images/│   ├── tile_001.tif│   ├── tile_002.tif├── labels/│   ├── landcover.geojson├── masks/│   ├── tile_001_mask.tif├── chips/│   ├── images/│   ├── masks/

完整工作流程示例

从影像到训练标签的全流程

步骤 1: 准备高清影像    └── beijing_hd_2025.tif (EPSG:32650)步骤 2: 创建综合 SHP 并标注    └── 在 QGIS 中新建 "beijing_hd_landcover_v1.geojson"    └── 添加字段: class (Integer), class_name (String)    └── 勾绘所有地物,填写 class 值步骤 3: 拓扑检查与修复    └── QGIS → Vector → Geoprocessing Tools → Check Validity    └── 修复重叠、缝隙、自相交步骤 4: 导出为 GeoJSON(推荐)    └── beijing_hd_landcover_v1.geojson    └── 配套: class_mapping.json步骤 5: 使用 GeoAI 生成训练数据    └── Python 代码见下方步骤 6: 验证标签质量    └── 可视化检查瓦片与掩膜的对齐情况

GeoAI 训练数据导出代码

import geoai# 单文件多类别模式(推荐)stats = geoai.export_geotiff_tiles_batch(    images_folder="data/images",    masks_file="data/beijing_hd_landcover_v1.geojson",  # 单一综合文件    output_folder="output/training_tiles",    tile_size=256,    stride=256,    class_value_field="class",      # 指定类别字段    skip_empty_tiles=True,          # 跳过无标注瓦片    all_touched=True,               # 接触即标记    buffer_radius=0,                # 无缓冲)print(f"生成瓦片: {stats['total_tiles']}")print(f"含标注瓦片: {stats['tiles_with_features']}")

类别映射表示例

# class_mapping.json{"project""beijing_hd_landcover","version""v1","num_classes"6,"classes": {"0": {"name""background""color": [000]},"1": {"name""building""color": [25500]},"2": {"name""vegetation""color": [02550]},"3": {"name""water""color": [00255]},"4": {"name""road""color": [2552550]},"5": {"name""bare_soil""color": [1396919]}    }}

常见问题与解决方案

问题
原因
解决方案
栅格化后类别粘连
多边形间距 < 像元大小
提高影像分辨率或人工修正矢量边界
小目标在瓦片中丢失
未设置缓冲或瓦片尺寸过大
减小 tile_size 或增大 buffer_radius
类别 ID 冲突
多文件 ID 重复
使用单一综合 SHP,统一分配 ID
瓦片边界标注残缺
地物跨瓦片被截断
设置 stride = tile_size / 2 产生重叠
矢量与影像错位
CRS 不一致或配准误差
统一 CRS,配准残差控制在 0.5 像元内
背景被错误标记
class
 字段存在 0 值
确保 class=0 仅用于背景,矢量中不出现
COCO 导出类别缺失
class
 字段为空或类型错误
检查所有要素的 class 字段是否填充完整
规范项
推荐做法
数据组织
单一综合 SHP/GeoJSON,包含所有类别
文件名{区域}_{任务}_v{版本}_{日期}.geojson
核心字段class
(Integer,从 1 开始)
辅助字段class_name
sourceconfidencedate
类别编码
连续整数:1=建筑, 2=植被, 3=水体...
背景处理0
 保留为背景,矢量中不出现
拓扑规则
无重叠、无缝隙、无自相交
坐标系
与参考影像完全一致,推荐投影坐标系
配套文件
必须附带 class_mapping.json

核心原则:矢量标注是 GeoAI 训练数据流水线的起点,其质量直接决定模型性能。采用单一综合 SHP、规范字段命名、严格拓扑检查,是高效、准确制作训练标签的根本保障。