- GIS
- 遥感
- 数据工程
【免费下载链接】gdal
GDAL is an open source MIT licensed translator library for raster and vector geospatial data formats.
导读
gdal vector convert是 GDAL(3.11 起新增)提供的矢量数据格式转换子命令,其定位是新一代ogr2ogr风格的声明式转换工具:一条命令即可完成 Shapefile、GeoPackage、GeoJSON、FileGDB 等格式间的互转,并支持追加、覆盖、更新、Upsert(插入或更新)、多图层选择与出错跳过等高级写入策略。本文以 doc/source/programs/gdal_vector_convert.rst 官方文档为核心,结合其底层算法源码(apps/gdalalg_vector_convert.cpp、apps/gdalalg_vector_write.cpp)与自动化测试(autotest/utilities/test_gdalalg_vector_convert.py),系统讲解该命令的全部标准选项、典型用法、底层工作原理与易错点,读者阅读后可直接上手完成各种矢量转换任务。
命令概览与适用场景
gdal vector convert(文档见 doc/source/programs/gdal_vector_convert.rst,源码见 apps/gdalalg_vector_convert.h)用于在不同格式之间转换矢量数据(Convert a vector dataset)。它隶属于 GDAL 3.11 引入的新一代命令体系gdal vector *,从源码结构看,该命令本质上是一个“转发器”:在 apps/gdalalg_vector_convert.cpp 的GDALVectorConvertAlgorithm::RunStep()中,代码只是把输入数据集直接设置为输出数据集(注释明确写道:Do nothing but forwarding the input dataset to the output. Real job is done by GDALVectorWrite.),真正执行转换、写入、覆盖等逻辑的,是矢量流水线中的write步骤(apps/gdalalg_vector_write.cpp)。
这一设计带来两个重要的使用含义:
gdal vector convert可以看作gdal vector pipeline中read ! write的简写形式。需要多步骤处理时(如转换同时重投影、筛选),可直接改用 gdal vector pipeline 文档 组合各步骤。- 它复用了
write步骤的完整写入能力,包括数据集/图层创建选项、追加、覆盖、Upsert、跳过错误、--no-create-empty-layers等(参数由 apps/gdalalg_vector_output_abstract.cpp 的AddAllOutputArgs()统一注册)。
此外,该算法在注册表中带有隐藏别名translate(见 apps/gdalalg_vector_convert.h 中GetAliasesStatic()),说明它承接了部分传统ogr2ogr的转换语义。仓库当前版本为 3.14.0(见 VERSION)。
命令行语法(Synopsis)
通过--help-doc可查看完整在线帮助:
$ gdal vector convert --help-doc其基本用法形如:
$ gdal vector convert [OPTIONS] <INPUT> <OUTPUT><INPUT>:输入矢量数据集,可以是文件路径,也可以是连接字符串(如MongoDBv3:tmp/foo)。<OUTPUT>:输出矢量数据集路径。若省略-f/--of,命令会依据输出文件名后缀自动猜测驱动;无法猜测时会报错Cannot guess driver for <name>(对应测试test_gdalalg_vector_convert_output_format_not_guessed)。
标准选项详解
以下选项均来自官方文档(doc/source/programs/gdal_vector_convert.rst)以.. include::方式引用的标准选项文件(位于 doc/source/programs/gdal_options/),下表为速览,随后逐个展开:
| 选项 | 别名 | 作用 |
|---|---|---|
--append | — | 允许向已有图层追加要素,不存在时同时创建输出数据集 |
-f, --of, --format, --output-format | — | 指定输出矢量格式 |
--co, --creation-option | — | 数据集创建选项(DSCO),可重复 |
--lco, --layer-creation-option | — | 图层创建选项,可重复 |
--oo, --open-option | — | 输入数据集打开选项,可重复 |
--output-open-option, --output-oo | — | 输出数据集打开选项(3.12 起),可重复 |
--if, --input-format | — | 指定输入驱动候选,可重复 |
--input-layer | — | 指定要处理的输入图层(可多个),默认处理全部图层 |
--output-layer | — | 指定输出图层名,默认与输入图层同名 |
--overwrite | — | 允许覆盖已存在的目标文件/数据集 |
--overwrite-layer | — | 允许覆盖已存在的输出图层 |
--update | — | 以更新模式打开已存在的输出数据集 |
--skip-errors | — | 忽略写入失败(3.12 起) |
--upsert | — | 使用 Upsert 插入或更新要素(3.12 起) |
--no-create-empty-layers | — | 避免创建无要素写入的图层(3.13 起) |
-q, --quiet | — | 抑制进度条与部分警告 |
1.--append:追加要素到已有图层
来自 doc/source/programs/gdal_options/append_vector.rst:
是否允许将要素追加(append)到已有图层。若输出数据集尚不存在,该选项也会先创建输出数据集。
从源码看(apps/gdalalg_vector_output_abstract.cpp),--append存在一个关键副作用:设置它时会自动把--update置为 true(AddAction([&updateArg] { updateArg.Set(true); })),即以更新模式打开输出数据集,再在目标图层上执行追加写入。
2.-f/--of/--format/--output-format:选择输出格式
来自 doc/source/programs/gdal_options/of_vector.rst:指定输出矢量格式,允许的值可用以下命令查看:
$ gdal --formats | grep vector | grep rw | sort若不指定,命令会根据输出文件后缀自动猜测驱动(见 apps/gdalalg_vector_output_abstract.cpp 中GDALGetOutputDriversForDatasetName(..., bSingleMatch = true, bWarn = true)的调用逻辑)。测试用例test_gdalalg_vector_convert_output_format_multiple_layers也验证了不同驱动的多图层能力差异——例如 GeoJSON 驱动不支持多图层(报GeoJSON driver does not support multiple layers),而 GPKG、ESRI Shapefile、CSV、MapInfo File 可以。
3.--co/--creation-option:数据集创建选项
来自 doc/source/programs/gdal_options/co_vector.rst:
- 许多格式支持一个或多个数据集创建选项(DSCO),用于控制生成文件的细节。例如 GeoPackage 驱动可用创建选项控制 OGC GeoPackage 版本。
- 选项可重复指定;不同驱动支持的选项各不相同,简单格式可能完全没有创建选项。
- 可用
--formats列出某格式支持的选项,但各驱动文档才是合法选项的权威来源(见 矢量驱动文档)。 - 数据集创建选项与图层创建选项(
--lco)是两回事,不可混用。
典型示例(对应测试test_gdalalg_vector_convert_dsco):
$ gdal vector convert poly.shp output.gpkg --co ADD_GPKG_OGR_CONTENTS=NO4.--lco/--layer-creation-option:图层创建选项
来自 doc/source/programs/gdal_options/lco.rst:控制新建图层细节,例如 GeoPackage 驱动可借此设置要素标识列(FID 列)、几何列名、图层标识符与描述等。可重复指定。对应测试test_gdalalg_vector_convert_lco验证了--lco FID=my_fid可将输出图层的 FID 列命名为my_fid:
$ gdal vector convert poly.shp output.gpkg --lco FID=my_fid5.--oo/--open-option:输入打开选项
来自 doc/source/programs/gdal_options/oo.rst:格式相关的输入数据集打开选项,可重复。典型场景如 CSV 多几何列读取(测试test_gdalalg_vector_convert_multiple_geometry_fields使用--oo KEEP_GEOM_COLUMNS=NO)。
6.--output-open-option/--output-oo:输出打开选项
来自 doc/source/programs/gdal_options/output_oo.rst,GDAL 3.12 新增:格式相关的输出数据集打开选项,可重复,用于控制以何种方式打开已存在的输出数据集。
7.--if/--input-format:指定输入驱动
来自 doc/source/programs/gdal_options/if.rst:
- 指定用于打开输入文件的驱动名。通常无需指定(GDAL 会自动探测),但当自动探测选择错误驱动时可显式指定跳过探测。
- 可重复指定多个候选驱动;注意该选项并不强制这些驱动打开数据集,某些驱动对文件扩展名仍有要求。
8.--input-layer:选择输入图层
来自 doc/source/programs/gdal_options/input_layer_no_active_layer.rst:指定要处理的一个或多个图层名称,默认处理全部图层。若图层名不存在会报错(测试用例验证错误信息为Cannot find source layer 'invalid')。
9.--output-layer:指定输出图层名
来自 doc/source/programs/gdal_options/output_layer.rst:指定要素写入的图层名;未指定时输出图层名与输入图层名相同。该参数在源码中另有别名--nln(见 apps/gdalalg_vector_output_abstract.cpp 中AddOutputLayerNameArg(&m_outputLayerName).AddAlias("nln"))。
关于默认图层名的补充细节(源码行为,apps/gdalalg_vector_output_abstract.cpp):对于 ESRI Shapefile 输出,若文件扩展名为.shp且图层数 ≤ 1,输出图层名会被强制设为文件名基名;若未指定且输出数据集恰好只有 1 个图层,则采用该图层的名字作为默认输出图层名。
10.--overwrite:覆盖整个目标
来自 doc/source/programs/gdal_options/overwrite.rst:允许覆盖已存在的目标文件或数据集;否则默认情况下目标已存在会直接报错。测试test_gdalalg_vector_convert_base验证了:不指定--overwrite直接写入已存在文件会报already exists;指定后要素数恢复为 10。另外 apps/gdalalg_vector_output_abstract.cpp 表明--overwrite与--update互斥(同一MutualExclusionGroup("overwrite-update"))。
11.--overwrite-layer:覆盖已有图层
来自 doc/source/programs/gdal_options/overwrite_layer.rst:是否允许覆盖已存在的输出矢量图层。源码逻辑(apps/gdalalg_vector_output_abstract.cpp 的SetupOutputDataset())为:若目标图层已存在且指定了--overwrite-layer,则先DeleteLayer再重建;若未指定且未--append,则报错提示指定--overwrite-layer覆盖或--append追加;若指定了--append或--overwrite-layer却找不到该图层,则报Cannot find layer '<name>'。
12.--update:更新模式打开输出
来自 doc/source/programs/gdal_options/update.rst:是否以更新(update)模式打开已存在的输出数据集。与--overwrite互斥。典型场景是向已有 GeoPackage 中添加新图层(见下方示例 2),测试test_gdalalg_vector_convert_base验证了--update --nln layer2会保留原图层并新增layer2。
13.--skip-errors:忽略要素写入失败
来自 doc/source/programs/gdal_options/skip_errors.rst,GDAL 3.12 新增:
- 是否忽略写入要素失败。
- 重要性能提示:该选项会把事务单元大小设为“一次一个要素”(transaction unit = one feature at a time),向数据库插入时可能造成严重性能下降。
- 测试
test_gdalalg_vector_convert_skip_errors验证:写入含无法表示几何(如 Shapefile 不支持 LINESTRING 场景下)的数据时,不指定该选项会报Failed to write layer 'test'. Use --skip-errors;指定后跳过失败要素并成功写出其余要素。
14.--upsert:插入或更新要素
来自 doc/source/programs/gdal_options/upsert.rst,GDAL 3.12 新增:
- 是
--append的变体:使用OGRLayer::UpsertFeature操作(而非CreateFeature)来插入或更新要素。 - 当前仅少数驱动实现:
GPKG、Elasticsearch、MongoDBv3(实现 upsert 的驱动会暴露GDAL_DCAP_UPSERT能力)。测试test_gdalalg_vector_convert_upsert验证 SQLite 驱动会报SQLite driver does not support upsert,而 GPKG 可以正常 Upsert。 - 键的规则:Upsert 以输入要素的 FID(当 FID 已设置且 FID 列名非空字符串)作为更新已有要素的键,因此必须保证源与目标图层的 FID 一致。
- 对于 GPKG 驱动,当存在非整型主键的 UNIQUE 列时,还可以 Upsert FID 未设置或不重要的要素(可用
gdal vector edit --unset-fid(见 gdal_vector_edit 文档)忽略源要素的 FID)。
15.--no-create-empty-layers:避免创建空图层
来自 doc/source/programs/gdal_options/no_create_empty_layers.rst,GDAL 3.13 新增:避免创建没有任何要素写入的图层。其底层实现在 apps/gdalalg_vector_write.cpp 的GDALReadBufferedDataset:会预读每个图层的第一条要素(PeekNextFeature()),过滤掉空图层后再交给写入逻辑。若源数据集支持随机图层读取(ODsCRandomLayerRead),会发出警告并退化为按图层逐层读取(测试test_gdalalg_vector_pipeline_no_create_empty_layers_random_layer_read_warning验证了该警告;test_gdalalg_vector_convert_no_create_empty_layers验证过滤效果)。
16.-q/--quiet:静默模式
来自 doc/source/programs/gdal_options/quiet.rst:抑制进度条与部分警告信息。例如向不支持曲线几何的输出格式写入曲线要素时,非静默模式会告警Attempt to write curve geometries,静默模式则无告警(测试test_gdalalg_vector_convert_warn_no_curve_support)。当输出到/vsistdout/时静默模式会被自动开启(测试test_gdalalg_vector_convert_to_stdout验证)。
典型实战示例
示例 1:将 Shapefile 转换为 GeoPackage
$ gdal vector convert poly.shp output.gpkg- 输出驱动由
.gpkg后缀自动判定为 GPKG。 - 图层默认保持原名
poly,全部要素(测试数据poly.shp共 10 个要素)被写入output.gpkg。
示例 2:向已有 GeoPackage 添加新图层并重命名
$ gdal vector convert --update --output-layer=lines line.shp output.gpkg--update以更新模式打开已存在的output.gpkg,避免“目标已存在”报错。--output-layer=lines将源图层line写入后命名为lines。- 测试验证该组合会保留既有图层(
poly要素数不变)并新增layer2/lines图层。
示例 3:向已有图层追加要素(静默模式)
$ gdal vector convert --quiet --append --output-layer=poly poly2.shp output.gpkg--append允许追加并自动启用--update,目标图层poly追加来自poly2.shp的要素。--quiet抑制进度条。测试test_gdalalg_vector_convert_base中两次追加后poly图层要素数从 10 变为 20。
底层工作原理:从算法到write步骤
gdal vector convert的完整执行链路(可结合 apps/gdalalg_vector_convert.cpp 与 apps/gdalalg_vector_write.cpp 阅读):
- 参数解析与校验:
GDALVectorConvertAlgorithm继承自GDALVectorPipelineStepAlgorithm(注册为独立步骤convert,见 apps/gdalalg_vector_convert.h),并声明SetNoCreateEmptyLayersArgument(true)与SetStandaloneStep(true)。 - 输入转发:
RunStep()校验输入唯一后将输入数据集直接赋给输出(m_outputDataset.Set(poSrcDS))。 - 写入执行:真正的转换由
write步骤(GDALVectorWriteAlgorithm)完成——它把各选项翻译成GDALVectorTranslateOptions,最终调用GDALVectorTranslate()(apps/gdalalg_vector_write.cpp 中RunStep())。选项映射关系包括:--overwrite→-overwrite/--no-overwrite、--overwrite-layer→-overwrite、--append→-append、--upsert→-upsert、--co→-dsco、--lco→-lco、--output-layer→-nln、--skip-errors→-skipfailures、-q→-q。 - 输出数据集准备:
SetupOutputDataset()(apps/gdalalg_vector_output_abstract.cpp)负责驱动猜测、数据集创建(poDriver->Create)、图层存在性检查以及覆盖/追加分支处理。 - 空图层过滤(可选):
--no-create-empty-layers时,GDALReadBufferedDataset会预读每层首个要素以剔除空图层。
常见错误信息与排查指引
| 错误信息(节选) | 触发条件 | 解决办法 |
|---|---|---|
Cannot guess driver for <name> | 输出文件名无法推断驱动 | 显式指定-f/--of <FORMAT> |
... already exists ... | 目标已存在且未指定覆盖/更新选项 | 加--overwrite(整体覆盖)或--update(更新模式) |
Layer '<name>' already exists. Specify the --overwrite-layer option to overwrite it, or --append to append to it. | 目标图层已存在,未指定覆盖或追加 | 按提示加--overwrite-layer或--append |
Cannot find layer '<name>' | 指定了--append/--overwrite-layer但找不到目标图层 | 检查--output-layer名称与源图层名 |
Cannot find source layer '<name>' | --input-layer指定的输入图层不存在 | 用ogrinfo确认源图层名 |
Failed to write layer '<name>'. Use --skip-errors to ignore errors | 存在无法写入的要素 | 加--skip-errors跳过(注意数据库场景的性能代价) |
SQLite driver does not support upsert | 目标驱动无 Upsert 能力 | 改用支持GDAL_DCAP_UPSERT的驱动(GPKG/Elasticsearch/MongoDBv3) |
与相关命令的关系
gdal vector pipeline:convert可等价视为流水线read ! write的简写。需要叠加 reproject、clip、filter 等步骤时,参考 gdal vector pipeline 文档 与各步骤文档(如 gdal_vector_reproject、gdal_vector_filter)。从源码看,convert算法是 pipeline 步骤体系中的一员(注册表见 apps/gdalalg_vector_pipeline.cpp 的RegisterAlgorithms())。ogr2ogr:gdal vector convert在功能上继承并规范化了ogr2ogr的核心转换语义(其隐藏别名translate也印证了这一点),同时融入新命令体系统一的参数风格。gdal vector edit:当需要先忽略源要素 FID 再执行 Upsert 时,可配合 gdal_vector_edit 文档 的--unset-fid使用。
总结
gdal vector convert提供了统一、可组合、语义清晰的矢量格式转换入口:格式自动探测与显式-f双通道、数据集与图层两级创建选项、覆盖/更新/追加/Upsert 四种写入模式,以及--skip-errors、--no-create-empty-layers等容错与优化开关。其底层复用write步骤与GDALVectorTranslate()实现,行为既有传统ogr2ogr的兼容性,又具备流水线化的扩展空间。官方测试(autotest/utilities/test_gdalalg_vector_convert.py)覆盖了覆盖、追加、图层重命名、Upsert、多图层、stdout 输出、错误处理等主要路径,可作为验证自身用法的参考基线。
- GIS
- 遥感
- 数据工程
【免费下载链接】gdal
GDAL is an open source MIT licensed translator library for raster and vector geospatial data formats.
相关推荐
GDAL `gdal raster convert` 命令详解:栅格格式转换、子数据集追加与 COG 输出实战
GDAL gdal raster convert 命令详解:栅格格式转换、子数据集追加与 COG 输出实战 本文基于 GDAL 仓库(当前版本 VERSION
GIS遥感数据工程GDAL `gdal convert` 命令详解:一次调用自动完成栅格与矢量格式转换
GDAL gdal convert 命令详解:一次调用自动完成栅格与矢量格式转换 gdal convert 是 GDAL 3.11 起引入的顶层转换命令,它本身
GIS遥感数据工程GDAL `gdal vector rename-layer` 子命令完全指南:重命名矢量图层与批量清洗图层名
GDAL gdal vector rename layer 子命令完全指南:重命名矢量图层与批量清洗图层名 GDAL 3.13 新增的 gdal vector
GIS遥感数据工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考