ℹ️ 读者定位
适合你,如果: 你在 QGIS、ArcGIS、GDAL 或 Python 工作流中交换点线面数据,想用一个文件保存多个图层,或者正在寻找 Shapefile 的现代替代方案。
开始前需要: 知道图层、字段、坐标系这些基础概念;要跟着实操,需要安装带 GeoPackage 驱动的 GDAL 3.x。
读完可以完成: 看懂 GeoPackage 的核心表、几何和空间索引;完成一次转换、检查与规范校验;能在 GeoPackage、Shapefile、GeoJSON、FileGDB、FlatGeobuf、GeoParquet 和 PostGIS 之间做选择。
暂时不适合: 本文不展开 QGIS/ArcGIS 的界面按钮,也不把 GeoPackage 当作企业级多人空间数据库、万能栅格仓库或 FileGDB 高级规则的无损替代品。

GeoPackage:把散落空间文件整理为开放单文件数据库
ℹ️ 读者
我只是想把几份 Shapefile 合成一个文件,GeoPackage 是不是改个后缀就行?
ℹ️ 作者
不是。.gpkg 本身就是一个遵守 OGC 规则的 SQLite 数据库。它能把多个图层装进一个文件,但转换之后仍要检查字段、坐标系、索引和目标软件兼容性。
📄 先给结论
GeoPackage 最适合"本地或离线环境下,把多个空间图层和属性表装进一个开放、便携、可查询的文件"。 它是很实用的平衡型容器,但不是所有空间数据场景的终点。
这篇内容分为以下几个部分:
- 先说清 GeoPackage 解决什么问题。
- 拆开 SQLite 容器、核心表、几何和空间索引。
- 用 GDAL 走一遍转换、检查和校验流程。
- 对比七种常见空间数据方案。
- 用场景和检查清单完成选型与交付。
一、先建立直觉:.gpkg 是数据库文件,不是压缩包
1.1 它解决的是"散、碎、难交接"
在空间数据工作里,我们经常会碰到这样的目录:
bash
roads.shp / roads.shx / roads.dbf / roads.prj / roads.cpg
stations.shp / stations.shx / stations.dbf / stations.prj / stations.cpg
districts.shp / districts.shx / districts.dbf / districts.prj / districts.cpg
文件一多,最怕的不是占空间,而是交接时漏文件、重名、编码不一致,或者不同图层的坐标系说明被弄丢。
GeoPackage 给出的答案很直接:使用一个 SQLite 数据库文件,按 OGC 规则保存多个矢量图层、非空间属性表和瓦片内容。
bash
survey-project.gpkg
├─ roads 道路线图层
├─ stations 站点图层
├─ districts 行政区图层
├─ dictionary 非空间字典表
└─ basemap 可选瓦片表
它不是把上面的文件压缩成 ZIP,也不是给 SQLite 随便加一个 .gpkg 后缀。SQLite 是容器,GeoPackage 标准负责规定空间内容怎样登记、怎样编码、怎样扩展。
1.2 开放标准到底带来什么
OGC 当前标准页列出的正式版本是 GeoPackage 1.4.0。标准规定了容器结构、内容目录、空间参考、矢量几何、瓦片矩阵和扩展声明等规则。OGC 官方标准页
这带来三个实际好处:
- 跨软件有共同底线: QGIS、GDAL、ArcGIS 等工具可以围绕同一套核心表和几何编码读写数据。
- 文件能自我说明: 图层类型、坐标参考和扩展信息都可以记录在容器内部,不再完全依赖旁车文件。
- 可以直接使用: 它是数据库文件,不必先解包或转换成另一种内部格式才能查询。
这里一定要注意:开放标准保证的是核心结构和约定,不保证每个软件都支持所有扩展、样式和厂商私有对象。
1.3 它不是什么
GeoPackage 不是地图服务,也不是 PostGIS 的"便携版"。它能做本地 SQL、索引和事务,但没有服务端账号权限、连接池、持续并发写入、统一审计和高可用架构。
⚠️ 单文件不等于多人数据库
把 .gpkg 放进共享盘,只是让多人都能碰到同一个文件,不等于得到了安全的协同编辑。长期多人生产编辑应使用 PostGIS、企业级地理数据库或经过设计的服务化方案。
二、拆开 GeoPackage:一份文件里到底有什么
2.1 先看两张"总目录"
一个合规的 GeoPackage 至少围绕两张基础表组织内容:
| 表 | 职责 | 可以把它理解成 |
|---|---|---|
gpkg_contents |
登记矢量要素、属性表、瓦片等内容 | 数据集目录 |
gpkg_spatial_ref_sys |
保存坐标参考系统,并提供 srs_id |
坐标系字典 |
矢量图层还要登记到 gpkg_geometry_columns,记录表名、几何列、几何类型、空间参考以及 Z/M 维度。
如果库里包含瓦片,则会用到 gpkg_tile_matrix_set 和 gpkg_tile_matrix,说明覆盖范围、缩放级别、像素尺寸和瓦片布局。

GeoPackage 内部结构:内容目录、空间参考、业务表、几何列、RTree、瓦片与扩展
2.2 一张矢量表就是"业务字段 + 几何列"
假设我们有一个站点图层:
bash
stations
├─ fid 整数主键
├─ geom GeoPackage 几何二进制
├─ station_id 稳定业务编号
├─ name 站点名称
└─ category 站点类型
fid 用来唯一标识一行;geom 保存空间形状;其余字段保存业务属性。
几何值通常由两部分组成:
bash
GeoPackage Binary
├─ GeoPackage 二进制头
│ ├─ 标识与版本
│ ├─ 标志位
│ ├─ SRS ID
│ └─ 可选包围盒
└─ WKB 几何
├─ Point
├─ LineString
├─ Polygon
└─ Multi* / GeometryCollection
这也是为什么不要用普通 SQLite 工具直接把 geom 当文本修改。查看业务字段没问题,改几何、改系统表或改扩展记录,优先交给支持 GeoPackage 的 GIS 库和软件。
2.3 RTree 空间索引解决什么
GeoPackage 可以通过标准扩展给矢量表建立 RTree 空间索引。索引保存每个要素的最小/最大 X、Y 范围。
当你查询"当前地图窗口里有哪些道路"时,软件可以先用矩形范围排除绝大多数不相交要素,再读取候选几何;不用每次把整张表的全部几何都解码一遍。
💡 索引不是性能保证书
有索引只是具备加速条件。数据量、几何复杂度、过滤方式、缓存和软件实现都会影响结果。没有同一数据集和同一查询条件时,不要轻易写"某格式一定比某格式快"。
2.4 "能存栅格"必须说完整
GeoPackage 核心可以保存影像或地图的瓦片矩阵集;GDAL 也支持把影像转换为 GeoPackage 瓦片。高程等连续覆盖可使用 Tiled Gridded Coverage 扩展。GDAL GeoPackage raster 驱动
但这不等于"任意 GeoTIFF 放进去都能原样保留全部波段、像元类型和元数据"。
- 离线底图、影像浏览、瓦片交付:可以评估 GeoPackage。
- 分析型原始栅格、云端按块读取:通常继续评估 GeoTIFF、COG 或专门的栅格数据管理方案。
2.5 核心标准与扩展要分开
GeoPackage 允许通过 gpkg_extensions 声明扩展。这个机制很重要,因为空间数据的需求总会超过最小核心。
但扩展也带来边界:
- OGC 采用的扩展,通常拥有更清晰的互操作预期;
- 软件自定义扩展,需要接收方使用相同实现或明确支持;
- 样式、关系、特殊几何或网格能力,不能只看"文件能打开",还要看具体对象是否被识别。
最终交付时,最好把使用过的扩展列出来,而不是只说"这是标准 GeoPackage"。
三、实战:转换、查看、查询、校验
3.1 第一步:从 GeoJSON 创建 GeoPackage
准备一份 demo-stations.geojson,然后执行:
bash
ogr2ogr -f GPKG demo.gpkg demo-stations.geojson \
-nln stations \
-lco SPATIAL_INDEX=YES
参数分工很清楚:
-f GPKG:输出驱动使用 GeoPackage;demo.gpkg:目标数据库文件;demo-stations.geojson:输入数据;-nln stations:目标图层名;-lco SPATIAL_INDEX=YES:为图层请求创建空间索引。
如果输入是 Shapefile,只需要把输入文件替换成 stations.shp。GDAL 官方文档也提供了从单个 Shapefile 或整个目录转换到 GeoPackage 的示例。GDAL GPKG vector 驱动
3.2 第二步:查看图层结构
bash
ogrinfo -ro -so -al demo.gpkg
不要只看"能不能打开",至少核对:
- 图层名是不是
stations; - 要素数量是否与输入一致;
- 几何类型是否符合预期;
- 坐标参考是否被正确识别;
- 字段名、字段类型和中文内容是否正确。
如果你有 sqlite3,还可以只读查看内容目录:
bash
SELECT table_name, data_type, identifier, srs_id
FROM gpkg_contents
ORDER BY table_name;
这条 SQL 很适合做交付清单,但不要顺手手工修改 gpkg_contents。目录和真实表不一致时,GeoPackage 反而会变得更难排查。
3.3 第三步:追加第二个图层
bash
ogr2ogr -update demo.gpkg roads.shp -nln roads
-update 表示打开现有 GeoPackage 并追加内容。执行前先确认:
roads这个图层名是否已经存在;- 输入字段和坐标系是否需要转换;
- 目标软件是否需要特定 GeoPackage 版本或扩展。
⚠️ 不要把 -append、-overwrite 和 -update 混为一谈
-update 是更新数据源;-append 是向已有图层追加要素;-overwrite 会重建目标图层。生产数据上使用后两者前,先备份目标文件并明确图层级影响。
3.4 第四步:执行规范校验
GDAL 新版命令可以校验 GeoPackage:
bash
gdal driver gpkg validate demo.gpkg
校验通过并不等于业务数据完全正确。稳妥的验收要分四层:
| 层次 | 检查内容 | 成功标准 |
|---|---|---|
| 容器 | SQLite/GeoPackage 结构 | 驱动可识别,规范校验无错误 |
| 数据集 | 图层、表、字段、要素数 | 与迁移清单一致,差异有说明 |
| 空间 | CRS、范围、几何有效性 | 位置正确,无明显空几何或异常范围 |
| 消费端 | 目标 GIS/应用实际加载 | 图层可读,属性、索引和扩展满足使用要求 |
☑️ 实际效果图 / GIF 待补充:查看与校验 GeoPackage
请在这里补充真实终端截图,展示:ogrinfo 的图层/字段摘要,以及 gdal driver gpkg validate 的最终结果。
建议文件名:截图资源/04-GeoPackage校验结果.png。
❌ 当前环境尚未完成命令验证
本次整理发现了 GDAL 3.11.3 可执行文件,但运行时依赖没有成功加载,ogr2ogr、ogrinfo 和 gdal 均以 Windows 退出码 -1073741515 结束,示例 .gpkg 未生成。上面的命令来自 GDAL 官方文档,但不能写成"本机已经跑通"。
四、七种空间数据方案,放到同一张桌子上比较
4.1 先看选型总表
| 方案 | 组织方式 | 最强的地方 | 主要代价 | 推荐场景 |
|---|---|---|---|---|
| GeoPackage | SQLite 单文件,可多表/多图层 | 开放、便携、本地 SQL、事务、空间索引 | 扩展兼容性要核对;不适合服务端多人并发 | 离线项目、跨软件交接、多图层本地包 |
| Shapefile | 多个同名旁车文件,通常单图层 | 历史系统和 GIS 软件兼容广 | 字段名/类型、编码、多文件完整性受限 | 简单矢量交付、固定老接口 |
| GeoJSON | JSON 文本,通常一份要素集合 | 可读、易调试、Web/API 友好 | 大文件体积和解析成本高;RFC 7946 CRS 边界明确 | Web 接口、小中型数据交换 |
| FileGDB | .gdb 多文件目录数据库 |
ArcGIS 数据模型、域、子类型、拓扑 | 目录不可拆;高级能力跨软件支持不一致 | ArcGIS 内持续编辑与质量规则 |
| FlatGeobuf | 单文件二进制,通常单图层 | 流式、随机访问、HTTP Range、可选空间索引 | 不是多图层数据库;人工不可读 | 云端静态矢量分发、大文件按范围读取 |
| GeoParquet | 列式文件或分区数据集 | 压缩、列裁剪、分析引擎、对象存储 | 桌面编辑和工具链成熟度需按项目验证 | 数据湖、批量分析、云原生 ETL |
| PostGIS | PostgreSQL 服务端数据库 | 多人并发、权限、复杂 SQL、服务集成 | 需要部署、运维、备份和连接管理 | 团队生产库、在线服务、复杂空间查询 |

空间数据格式选型地图:按本地编辑、Web 分发、列式分析与多人服务选择
ℹ️ GeoParquet 版本边界
GeoParquet 发布页目前同时列出稳定的 1.1.0 与 2.0.0-rc.1 候选版本。选型时不要把候选版能力直接当成所有工具都已稳定支持的事实。GeoParquet Releases
4.2 GeoPackage 和 Shapefile:从"文件组合"走向"数据库容器"
Shapefile 把几何、索引、属性、坐标系和编码拆进不同文件。GeoPackage 则把目录、空间参考、业务字段和几何放入一个数据库容器。
GeoPackage 的直接收益包括:
- 一个文件可以保存多个图层;
- 不受 DBF 十字符字段名等历史约束;
- UTF-8 文本和字段类型更自然;
- 可以做 SQL 查询、事务和 RTree 空间索引;
- 坐标参考和数据集目录随库保存。
但如果接收方的系统只认 Shapefile,"更现代"并不能替代接口兼容性。此时可以把 GeoPackage 作为内部工作格式,再按交付要求导出 Shapefile。
4.3 GeoPackage 和 GeoJSON:数据库式使用与文本式交换
GeoJSON 打开就能读,特别适合浏览器、API、调试和 Git 中的体积可控数据。RFC 7946 的标准基线是 WGS 84/CRS84 经纬度。RFC 7946
GeoPackage 是二进制数据库,更适合多个图层、多个 CRS、本地索引和重复查询。
一个简单判断:
- 接口返回几十、几百个要素,希望人能直接阅读:选 GeoJSON。
- 一个离线调查项目要同时携带道路、站点、行政区和字典表:选 GeoPackage。
4.4 GeoPackage 和 FileGDB:开放便携与高级数据模型
GeoPackage 的优势是开放标准、单文件和跨软件交接。FileGDB 的优势是 ArcGIS 工作流中的域、子类型、拓扑、关系类等高级数据模型。Esri File geodatabases
从 FileGDB 转到 GeoPackage 时,不能只比较要素数。至少要列出:
- 域和子类型是否保留、转成普通字段,还是丢失;
- 关系类、拓扑、附件和栅格对象如何处理;
- 图层样式是否需要单独交付;
- 接收端是否支持用到的扩展。
4.5 GeoPackage、FlatGeobuf、GeoParquet:编辑包、分发包、分析包
这三个格式经常被放到一起比较,但它们各自的中心任务不同:
- GeoPackage: 可查询、可编辑的本地多图层容器。
- FlatGeobuf: 适合流式和随机访问的静态矢量分发文件,支持 HTTP Range。FlatGeobuf 项目
- GeoParquet: 面向列式分析、分区数据集和对象存储的空间数据格式。
如果目标是 QGIS 里离线编辑一套多图层数据,GeoPackage 更自然;如果目标是网页按范围取一个大图层,FlatGeobuf 更贴近问题;如果目标是 DuckDB、Spark 或云端数据湖统计,GeoParquet 更值得优先评估。
4.6 GeoPackage 和 PostGIS:文件与服务是两类问题
GeoPackage 解决的是"怎样把数据带走,在本地直接用";PostGIS 解决的是"多人和应用怎样连接同一份权威数据"。PostGIS 把空间类型、空间索引和空间函数接入 PostgreSQL,同时继承事务、约束、权限、备份和应用连接能力。PostGIS Introduction
只要需求里出现下面任意几项,就应该认真评估 PostGIS,而不是继续堆 .gpkg 文件:
- 多人持续写入;
- 账号和数据权限;
- 在线 API 或地图服务;
- 复杂空间 SQL;
- 集中备份、审计与恢复;
- 一份权威数据被多个应用共同使用。
五、把 GeoPackage 放进正确的工作流
5.1 五类推荐场景
- Shapefile 整理: 把多组旁车文件整理成一个交付包。
- 跨软件交换: 在 QGIS、ArcGIS、GDAL 和自研程序之间交换常规矢量数据。
- 离线使用: 给移动设备、现场调查或弱网环境准备本地数据。
- 项目快照: 保存验收样本、分析输入或可复现实验数据。
- 轻量查询: 用 SQLite/GDAL 在本地筛选属性和空间范围。
5.2 六类不应直接使用的场景
- 多人长期同时编辑同一权威库;
- 必须无损保留 FileGDB 的全部高级规则;
- 浏览器/API 只需要少量、可读的要素;
- 面向数据湖的大规模列式统计和分区扫描;
- 随缩放级别渲染海量矢量底图;
- 保存需要完整波段和分析元数据的原始栅格。
5.3 迁移与交付检查清单
- ☐已保存原始数据副本,没有直接覆盖唯一来源。
- ☐
gpkg_contents中的内容与实际表一致。 - ☐图层名、要素数、几何类型、字段和 CRS 已核对。
- ☐关键业务主键稳定,没有把临时行号误当永久 ID。
- ☐需要范围查询的图层已建立空间索引。
- ☐扩展清单已记录,接收软件确实支持。
- ☐已在至少一个目标软件中打开并抽样检查位置与属性。
- ☐从 FileGDB/MDB 迁移时,高级规则的保留、转换或丢失有清单。
- ☐文件有独立备份,没有把共享盘同时编辑当作协作方案。
六、结论:GeoPackage 是平衡型本地容器
bash
GeoPackage 的价值不是"一个文件替代所有格式",
而是用开放标准把多图层、空间参考、索引和本地查询装进一个便携数据库。
如果你第一次上手,我建议先拿一份小型 GeoJSON 或 Shapefile 转成 .gpkg,再按"容器---数据集---空间---消费端"四层验收。
最后记住这组选择:
- 本地多图层、离线交付: GeoPackage。
- Web/API、小数据可读: GeoJSON。
- 兼容历史接口: Shapefile。
- ArcGIS 高级模型: FileGDB。
- HTTP 静态大矢量: FlatGeobuf。
- 列式分析和数据湖: GeoParquet。
- 多人生产与服务化: PostGIS。
格式没有绝对的新旧胜负,只有是否贴合数据规模、使用方式和协作边界。把 GeoPackage 放在"开放、便携、本地、受控编辑"这个位置上,它往往会成为比 Shapefile 更稳的默认选择。