GDAL (Geo)Arrow 矢量驱动完全指南:Feather/Arrow IPC 格式的读写、配置与源码剖析

发布时间:2026/10/12 1:52:10
GDAL (Geo)Arrow 矢量驱动完全指南:Feather/Arrow IPC 格式的读写、配置与源码剖析
GIS遥感数据工程【免费下载链接】gdalGDAL is an open source MIT licensed translator library for raster and vector geospatial data formats.项目地址https://gitcode.com/gh_mirrors/gd/gdal点击查看免费下载(Geo)Arrow IPC File Format / Stream即 Feather 格式家族是 Apache Arrow 生态中用于存储 Arrow Table 或数据框如 Python/R 中常见的数据框对象的便携式文件格式内部基于 Arrow IPC 协议。GDAL 自 3.5 起通过Arrow 矢量驱动原生支持该格式的两种变体随机访问的 File 格式与流式的 Streaming IPC 格式并在 3.9 起完整支持 GeoArrow 几何列规范。本文将以官方驱动文档为主体结合 GDAL 仓库中的驱动实现源码与自动化测试系统讲解该驱动的格式背景、打开与识别机制、创建选项、几何编码、安装部署与源码级实现原理帮助你直接用 GDAL/OGR 读写 Feather/Arrow 文件并理解其底层工作方式。一、格式背景Arrow IPC 的两种变体Arrow IPC 格式本质上是一套列式二进制布局的封装协议。GDAL Arrow 驱动支持其两种变体官方文档定义File / Random Access 格式又名 Feather用于序列化固定数量的 Record Batch记录批次。读取此类文件需要随机访问能力但生成端只需具备流式写入能力即可。推荐扩展名为.arrow。GDAL 驱动元数据中注册的扩展名为arrow feather arrows ipc见 ogrfeatherdrivercore.cpp。Streaming IPC 格式用于发送任意长度的 Record Batch 序列一般必须从头到尾顺序处理不需要随机访问。该格式通常不物化为文件若物化推荐扩展名为.arrows注意带尾字母 s。驱动同时支持普通文件以及/vsistdin/、/vsistdout/这类流式虚拟文件。两种变体的差别在读取路径上体现为使用不同的 Arrow 读取器驱动源码在打开文件时流式格式走arrow::ipc::RecordBatchStreamReader::Open()文件格式走arrow::ipc::RecordBatchFileReader::Open()见 ogrfeatherdriver.cpp在写入路径上则分别调用arrow::ipc::MakeStreamWriter()与arrow::ipc::MakeFileWriter()见 ogrfeatherwriterlayer.cpp。提示本驱动同时支持几何列GeoArrow 规范但官方文档明确标注该驱动应视为实验性功能因为 GeoArrow 规范尚未最终定稿。二、打开与格式识别机制1. 自动识别策略驱动打开文件时通过Identify()逻辑判定内容属于哪种变体实现见 ogrfeatherdrivercore.cppFile 格式校验文件头尾是否都有 6 字节签名ARROW1并解析文件末尾 4 字节的 footer 大小字段见OGRFeatherDriverIsArrowFileFormat()ogrfeatherdrivercore.cpp。Stream 格式先检查头部是否以0xFFFFFFFF连续标记4 字节 4 字节元数据长度开头若扩展名为arrows或ipc则直接判定否则进一步用RecordBatchStreamReader::Open()尝试解析见 ogrfeatherdriver.cpp。2. 流式格式识别的难点与强制手段官方文档指出打开时驱动可能难以识别内容是否为 Arrow IPC 流尤其是扩展名不是.arrows、且元数据段很大时。为此文档提供三种强制打开方式文件名前缀ARROW_IPC_STREAM:例如ARROW_IPC_STREAM:/vsistdin/驱动将无条件按流式 IPC 格式打开。注意前缀后跟的路径才是真实文件名驱动会剥离此前缀后按原路径打开ogrfeatherdriver.cpp。GDAL 3.10 起命令行工具中传入-if ARROW。GDAL 3.10 起在GDALOpenEx的papszAllowedDrivers中仅指定ARROW一个值也强制驱动识别该文件名。其中ARROW_IPC_STREAM:前缀在流式文件的随机访问/回退能力上有专门处理驱动据此判断流是否可 seekbSeekable/vsistdin/与ARROW_IPC_STREAM:打开的流被标记为不可回退FeatureCount 快速统计、rewind 等操作会受到限制对应测试见 ogr_arrow.py。3./vsistdin/的特殊处理与 1 MB 限制源码中针对/vsistdin/有一个值得注意的实现细节由于标准输入无法回退超过首个 1 MB当头部元数据段超过约 1 MB 时驱动无法自动识别流式内容此时必须通过ARROW_IPC_STREAM:前缀或allowed_drivers[ARROW]强制打开ogrfeatherdrivercore.cpp。自动化测试test_ogr_arrow_ipc_read_stdin专门构造了一个元数据超过 1 MB 的流式文件验证了默认无法打开、指定 allowed_drivers 后可打开的行为ogr_arrow.py。4. 打开限制不支持更新OGRFeatherDriverOpen()中对GA_Update直接返回nullptrogrfeatherdriver.cpp。支持虚拟 IOGDAL_DCAP_VIRTUALIO YES因此/vsi*路径均可读写。三、Open Options打开选项官方文档定义的唯一打开选项如下选项取值默认值引入版本说明LISTS_AS_STRING_JSONYES/NONO3.12.1是否将字符串/整数/实数列表字段报告为String(JSON)字段而不是String/Integer[64]/RealList列表类型该选项的核心价值在于空值语义的精确映射当列表中存在 null 值时默认的列表类型映射会省略空字符串字符串列表或置 0布尔/整数/实数列表而YES模式能原样保留 null 值。驱动在注册元数据时同步生成了该选项的 XML 定义ogrfeatherdrivercore.cpp测试test_ogr_arrow_lists_as_string_json验证了开启后[null,false,true,false]、[null,7,8,9]等空值被完整保留ogr_arrow.py。四、创建能力与限制驱动支持创建GDAL_DCAP_CREATE YES、GDAL_DCAP_CREATE_LAYER YES但每个数据集只能创建单层。这一点在写入端有硬性约束ICreateLayer()中若m_poLayer已存在直接报错Can write only one layer in a Feather fileogrfeatherwriterdataset.cpp。字段能力方面驱动注册支持Integer Integer64 Real String Date Time DateTime Binary IntegerList Integer64List RealList StringList等创建字段类型以及Boolean Int16 Float32 JSON UUID字段子类型ogrfeatherdrivercore.cpp。值得注意的元数据还包括GDAL_DCAP_MEASURED_GEOMETRIES YES与GDAL_DCAP_Z_GEOMETRIES YES支持 M / Z / ZM 维度几何默认仅 2D可用配置项OGR_ARROW_ALLOW_ALL_DIMSYES放开见 ogrfeatherwriterlayer.cpp。GDAL_DCAP_REOPEN_AFTER_WRITE_REQUIRED YES写入完成后需重新打开才能读取。五、Layer Creation Options图层创建选项这是驱动最核心的实操参数官方文档定义如下下面逐项结合源码展开。1.COMPRESSION— 压缩方法取值NONE、ZSTD、LZ4。默认值Arrow 库编译时支持 LZ4 则用LZ4否则NONE。说明可选值取决于 Arrow 库的编译情况。驱动在注册元数据时通过arrow::util::Codec::GetCompressionType()Codec::IsAvailable()动态探测可用压缩器生成LayerCreationOptionList时只列出实际可用的取值ogrfeatherdriver.cpp。写入时若显式指定了不支持的压缩方法会直接报错ogrfeatherwriterlayer.cpp。源码细节NONE在内部会被转换为UNCOMPRESSED传给 Arrow 编解码器且 XML 选项中NONE带有UNCOMPRESSED别名。2.FORMAT— 格式变体取值FILE、STREAM。默认值FILE除非文件名是/vsistdout/或其扩展名是.arrows此时默认STREAM。源码中的默认值判定逻辑如下ogrfeatherwriterlayer.cppconst char *pszDefaultFormat (EQUAL(CPLGetExtensionSafe(osFilename.c_str()).c_str(), arrows) || STARTS_WITH_CI(osFilename.c_str(), /vsistdout)) ? STREAM : FILE;结合第一节的读取逻辑可以看出FILE写出的是带ARROW1头尾签名与 footer 的可随机访问文件STREAM写出的是连续 Record Batch 序列——这也解释了扩展名约定.arrow与.arrows的来源。3.GEOMETRY_ENCODING— 几何编码取值GEOARROW、WKB、WKT、GEOARROW_INTERLEAVED。默认值GEOARROW。官方文档特别强调了GDAL 3.9 的命名变化GDAL 3.9 起GEOARROW使用 GeoArrowstruct 结构体编码点建模为带x、y子字段的 struct 字段线建模为这种点的 list依此类推。原版本中名为GEOARROW的编码在 3.9 被重命名为GEOARROW_INTERLEAVED点使用(x,y)的FixedSizedList线使用这种定长点列表的可变长 list依此类推。源码中选项到内部枚举的映射完全对应文档ogrfeatherwriterlayer.cpp且GEOARROW_STRUCT作为GEOARROW的别名接受。测试test_ogr_arrow_check_geoarrow_types用 PyArrow 逐类型验证了两种编码的底层 Arrow 类型ogr_arrow.py例如GEOARROWstruct 编码的 Point →structx: double not null, y: double not nullGEOARROW_INTERLEAVED的 Point →fixed_size_listxy: double not null[2]Polygon 的 struct 编码 →listrings: listvertices: structx, y此外写入几何列时驱动会在 schema 元数据geo键中记录schema_version、primary_column、每列的encoding、CRSWKT2_2019 格式与坐标纪元epoch并在 footer 元数据gdal:geo键中额外写入bbox与gdal:geometry_typeogrfeatherwriterlayer.cpp。4.BATCH_SIZE— 每批次最大行数取值任意正整数。默认值65536。该值决定每个 Record Batch写入批次的最大行数。源码中若显式指定则覆盖默认值且上限钳制为INT_MAXogrfeatherwriterlayer.cpp。测试验证了批次数目与_ARROW_元数据域中NUM_RECORD_BATCHES、RECORD_BATCHES[N].NUM_ROWS的对应关系ogr_arrow.py。5.GEOMETRY_NAME— 几何列名默认值geometry。用于指定写入的几何列名称对应源码中CSLFetchNameValueDef(papszOptions, GEOMETRY_NAME, geometry)ogrfeatherwriterlayer.cpp。6.FID— FID 列名默认值不指定时不创建 FID 列。官方文档特别提示了与 ogr2ogr 的联动若使用 ogr2ogr 以 Arrow 驱动为目标驱动、且源图层带有命名 FID 列该 FID 列名会被自动用来设置 Arrow 驱动的 FID 图层创建选项除非用-lco FID显式设为空名。测试中通过FIDfid或FIDmy_fid验证了 FID 列的创建与GetFIDColumn()行为ogr_arrow.py。7.TIMESTAMP_WITH_OFFSET— 带时区偏移的时间戳取值AUTO、YES、NO。默认值AUTO。引入版本3.13。该选项决定 OGR 的 datetime 字段是否按 Arrow 官方的Timestamp With Offset 扩展规范Apache Arrow Canonical Extensions 之一写出为带偏移的时间戳字段。此类字段同时存储UTC 时区下表达的时间戳和该 datetime 定义时区的 UTC 偏移量两部分信息。三种模式的语义AUTO只要 DateTime 字段报告混合时区标志即OGRFieldDefn::GetTZFlag()返回OGR_TZFLAG_MIXED_TZ就启用该扩展。YES强制启用——由于能自动设置混合时区标志的驱动很少手动设为YES很有用。NO强制使用带 UTC 时区的 DateTime 字段。源码在写入 schema 时按此逻辑为字段记录时区标志并生成arrow.timestamp_with_offset扩展名ograrrowwriterlayer.hpp。测试test_ogr_arrow_timestamp_with_offset构造了带0345、-0745混合偏移的时间戳验证写读往返后TZFLAG_MIXED_TZ与偏移值完整保留ogr_arrow.py。六、安装方式1. 随 GDAL 整体构建Arrow 驱动由ogr/ogrsf_frmts/arrow/目录下的CMakeLists.txt负责构建源码文件包括ogrfeatherdriver.cpp驱动的 Open / Create / 元数据初始化ogrfeatherdataset.cpp、ogrfeatherlayer.cpp读取端数据集与图层ogrfeatherwriterdataset.cpp、ogrfeatherwriterlayer.cpp写入端ogrfeatherdrivercore.cppIdentify 与公共元数据vsifilesystemregistrar.cppArrow VSI 文件系统注册仅当 Arrow ≥ 16.0 时编译见 CMakeLists.txt驱动以PLUGIN_CAPABLE方式构建并依赖Arrow::arrow_shared/arrow_static链接CMakeLists.txt。公共几何逻辑与 Parquet 驱动共享ogr/ogrsf_frmts/arrow_common/目录下的实现。2. Conda-forge 插件包官方文档提供的安装命令作为libgdalconda-forge 包的插件conda install -c conda-forge libgdal-arrow-parquet3. 独立插件编译GDAL 3.10 起除了随整个 GDAL 构建内置于 libgdal 或作为插件之外还可以仅将该驱动编译为插件链接到已构建好的 libgdal。前提是用于编译驱动的 GDAL 源码版本必须与所链接的 libgdal 版本一致。官方文档示例在 GDAL 源码树根目录下的build_arrow目录中执行cmake -S ../ogr/ogrsf_frmts/parquet -DCMAKE_PREFIX_PATH/path/to/GDAL_installation_prefix -DArrow_DIR/path/to/lib/cmake/Arrow cmake --build .说明示例命令以 GDAL 源码树内ogr/ogrsf_frmts/下的驱动源码目录为-S源通过CMAKE_PREFIX_PATH指向 GDAL 安装前缀、Arrow_DIR指向 Arrow 的 CMake 配置目录。Arrow 驱动的CMakeLists.txt同样内置了独立插件构建支持project(ogr_Arrow)SetupStandalonePlugin.cmake见 arrow/CMakeLists.txt。文档还提示了一个重要限制此类插件在链接到不感知它的 libgdal 时会在 GDAL 驱动初始化阶段被系统性加载无法受益于延迟插件加载能力RFC 96。要启用延迟加载需要 libgdal 自身以 CMake 变量OGR_REGISTER_DRIVER_ARROW_FOR_LATER_PLUGINON构建。七、Arrow VSI 文件系统GDAL 3.10 起从 GDAL 3.10 与 Arrow 16.0 开始任何 GDAL 虚拟文件系统都可以在只读上下文中用于任何需要 URI 的 Arrow C 库位置且不限于 OGR Arrow 驱动本身。启用方式官方文档注册文件系统工厂用arrow::fs::LoadFileSystemFactories()加载libgdal.so/dll若 Arrow 驱动以插件库形式构建则加载ogr_Arrow.so/dll。另外如果 Arrow 驱动被完整加载例如调用GetGDALDriverManager()-GetDriverByName(ARROW)-GetMetadata()Arrow VSI 文件系统也会被自动注册。使用gdalvsi://URI 前缀在 GDAL 文件名可能自带的 vsi 前缀之外再冠以该前缀。例如 GDAL 文件名/vsicurl/http://example.com对应的 Arrow URI 为gdalvsi:///vsicurl/http://example.com。源码层面的注册实现在 vsifilesystemregistrar.cpp通过ARROW_REGISTER_FILESYSTEM宏以gdalvsi作为 scheme 注册工厂工厂回调剥离gdalvsi://前缀并返回基于 GDAL VSI 的VSIArrowFileSystem实现。驱动在RegisterOGRArrow()中还会读取OGR_ARROW_LOAD_FILE_SYSTEM_FACTORIES配置项主要用于测试来触发LoadFileSystemFactories()ogrfeatherdriver.cpp。对应的自动化测试test_ogr_arrow_vsi_arrow_file_system在 Arrow ≥ 16 的环境下直接ogr.Open(gdalvsi://data/arrow/test.feather)验证该机制ogr_arrow.py。八、实操示例以下命令演示最常用的读写场景基于 GDAL 命令行工具# 1. 将 Shapefile 转换为 FeatherFile 格式LZ4 压缩GeoArrow struct 几何编码 ogr2ogr -f Arrow out.arrow in.shp \ -lco COMPRESSIONLZ4 \ -lco GEOMETRY_ENCODINGGEOARROW # 2. 写出流式 IPC 格式输出到 stdout自动判定为 STREAM 格式 ogr2ogr -f Arrow /vsistdout/ in.shp | cat out.arrows # 3. 强制将文件按流式 IPC 格式打开即使扩展名不是 .arrows ogrinfo ARROW_IPC_STREAM:unknown_ext.bin -so -al # 4. 列出 Arrow 驱动的图层创建选项查看当前环境实际可用的压缩方法 gdalinfo --format Arrow # 或查看驱动元数据 DS_LAYER_CREATIONOPTIONLISTPython 端直接使用驱动 APIfrom osgeo import gdal, ogr # 写入单层限制 FID 列 自定义批次大小 ds gdal.GetDriverByName(Arrow).Create(out.feather, 0, 0, 0, gdal.GDT_Unknown) lyr ds.CreateLayer(out, geom_typeogr.wkbPoint, srssrs, options[GEOMETRY_ENCODINGGEOARROW, FIDfid, BATCH_SIZE65536, COMPRESSIONLZ4]) # ... 创建字段与要素 ... ds None # 关闭并完成文件写入 # 读取强制按流式 IPC 打开 ds gdal.OpenEx(ARROW_IPC_STREAM:/vsistdin/, gdal.OF_VECTOR) lyr ds.GetLayer(0) for feat in lyr: print(feat.GetGeometryRef().ExportToIsoWkt())九、相关资源官方格式文档Feather File FormatArrow Python 文档GeoArrow 规范GeoArrow 几何列标准当前处于演进中。关联驱动Parquet 矢量驱动与 Arrow 驱动共享arrow_common底层实现测试中也互相复用检查逻辑。驱动源码ogr/ogrsf_frmts/arrow/读写实现、ogr/ogrsf_frmts/arrow_common/公共 Arrow 桥接层。测试套件autotest/ogr/ogr_arrow.py覆盖几何类型全矩阵、压缩、流式 stdin、VSI 文件系统、扩展类型、时间戳偏移等 1060 行用例。赞分享GIS遥感数据工程【免费下载链接】gdalGDAL is an open source MIT licensed translator library for raster and vector geospatial data formats.项目地址https://gitcode.com/gh_mirrors/gd/gdal点击查看免费下载相关推荐Apache Arrow C IPC 格式读写完整指南Stream / File 与事件驱动解码Apache Arrow C IPC 格式读写完整指南Stream / File 与事件驱动解码 本文是 Apache Arrow C位于当前仓库数据工程数据分析大数据Apache Arrow C IPC 读写指南Stream/File 两种格式、事件驱动解码与完整配置项解析Apache Arrow C IPC 读写指南Stream/File 两种格式、事件驱动解码与完整配置项解析 Apache Arrow 的 C 实现数据工程数据分析大数据Apache Arrow Java IPC 读写实战Streaming 流式格式与 Random Access 文件格式完全指南Apache Arrow Java IPC 读写实战Streaming 流式格式与 Random Access 文件格式完全指南 导读 本文基于 Apache数据工程大数据序列化数据分析上一篇Apache Beam 发布流程实战指南从 Release Manager 视角的七阶段完整流程下一篇DLSS Swapper终极指南三步快速优化游戏性能的免费神器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考