格式 | 类型 | 空间索引 | 属性表 | 坐标系 | 适用场景 |
|---|
GeoJSON | 文本 | ❌ | ❌(嵌套) | 可选 | 交换、小数据、API 响应 | GeoPackage | SQLite | ✅ R-tree 内置 | ✅ 完整 SQL | ✅ | 单文件数据分发、离线桌面 | FlatGeobuf | 二进制流 | ✅ Hilbert 曲线 | ❌ | ✅ | 高压缩比、HTTP Range 流式读取 | Shapefile | 二进制 | ⚠️ 外部 .qix | ✅ .dbf | ✅ | 遗留系统兼容 | PMTiles | 单文件瓦片 | ✅ 内部目录 | ❌ | ✅(3857) | 底图分发、零运维托管 | MVT | 二进制瓦片 | ✅ | 编码压缩 | ✅(3857 内) | 矢量瓦片传输 |
GeoJSON:通用但不是万能GeoJSON 的普及度无可替代——它是 Web 上事实上的地理数据交换格式。但它有三个硬限制: 1. 文件体积:JSON 是文本编码,坐标是十进制度数。典型膨胀 3-5 倍 2. 无空间索引:每次空间查询都是全量扫描 3. 无属性表结构:属性是 JSON 对象,不是表结构,没有类型约束 减小 GeoJSON 体积的实用技巧// 1. 精度截断——可视化不需要厘米级精度
const round = (v, d = 6) => Math.round(v * 10 ** d) / 10 ** d;
// 2. 移除冗余字段
delete feature.properties.createdAt;
delete feature.properties.internalId;
// 3. 用 MultiPolygon 替代多个 Polygon(减少重复的结构开销)
// 4. 坐标数组而非对象
// ✗ {"type":"Point","coordinates":[-0.1276,51.5072]} → 31 字节
// ✓ [-0.1276,51.5072] → 18 字节
精度截断是性价比最高的一招。 6 位小数约 0.1 米精度,对绝大多数可视化场景绰绰有余,通常能减 20-30% 体积。 什么时候 GeoJSON 是对的数据量小(几千要素以内) API 响应格式 需要人类可读、便于调试 前端临时数据交换
如果你的 GeoJSON 超过 10MB,就该考虑换格式了。 GeoPackage:单文件方案的赢家GeoPackage 是 OGC 标准,构建在 SQLite 上。它的实际优势常被低估: 核心优势:索引随文件走。 Shapefile 的 .qix 是独立文件,极易丢失——数据传了索引没传,查询立刻变慢。GeoPackage 的 R-tree 存在 .gpkg 内部,一体传输。 # 转换并自动构建 R-tree 索引
ogr2ogr -f GPKG output.gpkg input.shp
# 检查索引是否存在
ogrinfo output.gpkg | grep -i rtree
属性表是真正的关系表: -- 可以直接 JOIN、GROUP BY、建索引
SELECT e.name, count(*) AS cnt
FROM events e
JOIN admin_regions r ON ST_Intersects(e.geom, r.geom)
GROUP BY e.name
ORDER BY cnt DESC
LIMIT 10;
其他特性: 完整的 SQLite SQL 支持 并发写入(虽然 WAL 模式下仍需谨慎) 无坐标系丢失 GDAL 支持最完善
局限:单文件写入时不适合高并发。多人同时编辑的场景需要数据库。 FlatGeobuf:高压缩比的新选项FlatGeobuf 是较新的二进制空间格式,基于 Hilbert 空间填充曲线组织数据。 Hilbert 曲线的性质是:空间上邻近的点,在文件里也邻近。这个特性带来两个直接好处: 1. 压缩率高:坐标序列在文件中连续,相邻值差异小,压缩器能有效利用(二进制 + Zstd 压缩率常达 JSON 的 1/10) 2. HTTP Range 请求:因为数据按空间聚集,可以只请求视口对应的字节区间,而不是下载整个文件 # 生成 FlatGeobuf,启用空间索引
ogr2ogr -f FlatGeobuf data.fgb input.geojson -dsco SPATIAL_INDEX=YES
适合:需要高压缩比又需要浏览器端流式读取的场景。CDN 分发大矢量数据集时优势明显。 局限:无属性表结构,不适合做空间查询分析。它是交换和分发格式,不是分析格式。 PMTiles:底图分发的最优解PMTiles 是专为"单个文件包含完整瓦片金字塔"设计的格式。它把整个 z/x/y 目录放在文件头,后面接瓦片数据。 核心价值:零运维托管。 # 把 MBTiles 转成 PMTiles
pmtiles convert input.mbtiles output.pmtiles
# 直接在 HTTP 静态服务器上发布,不需要瓦片服务
这意味着一个全球范围的完整底图可以是一个静态文件,放在对象存储上通过 CDN 分发,不需要任何服务端逻辑。 对比传统方式: 方案 | 文件数 | 需要服务端 |
|---|
传统 XYZ 瓦片 | 数十万个 | ✅ 需要 | PMTiles | 1 个 | ❌ 不需要 |
这是 PMTiles 最大的意义——把底图分发的运维成本降到接近零。 局限: 只支持 EPSG:3857 瓦片 不是分析格式 不支持增量更新(文件是完整快照)
Shapefile:只在遗留场景用Shapefile 是最老的格式,现在新项目不应该再用它,除非对接遗留系统。 必须知道的三个坑: 1. 多文件:xxx.shp、xxx.shx、xxx.dbf、xxx.prj、xxx.qix……少任何一个都打不开。zip 传输时最容易丢文件 2. 字段名截断:DBF 格式字段名最长 10 个字符,超长被静默截断,导致字段名对不上 3. 编码问题:.cpg 文件缺失时中文字段会乱码 结论:新项目直接用 GeoPackage;如果必须对接 Shapefile,在中间做一次格式转换,不要让它进入你的主链路。 OGC 服务格式:什么时候用WMS / WFS / WCS 这类不是文件格式,是服务协议。 协议 | 返回 | 适用 |
|---|
WMS | 服务器渲染的图片 | 影像、样式固定的专题图 | WFS | 矢量要素(GML/GeoJSON) | 查询、编辑、少量矢量 | WMTS | 缓存瓦片图片 | 高并发底图浏览 | WCS | 栅格数据覆盖 | 影像分析 |
关键区别:WMS 是服务端渲染(每次请求生成图片),WMTS 是预先切好的缓存瓦片。对高并发场景,WMTS 便宜得多。 现代 Web 应用越来越少直接消费 WMS/WFS,但如果需要对接传统 GIS 部门的数据,OpenLayers 的 ol.source.ImageWMS、ol.source.TileWFS 能无成本对接。 选型决策树你的场景是什么?
│
├─ API 响应 / 前端临时数据
│ └─ 数据 < 10MB ────────────► GeoJSON(截断精度 + gzip)
│
├─ 单文件数据分发 / 离线桌面
│ └─ 需要属性分析 ────────────► GeoPackage
│
├─ 大矢量 + CDN 分发 + 流式读取
│ └─ 浏览器端渲染 ────────────► FlatGeobuf
│
├─ 底图 / 静态瓦片金字塔
│ └─ 不想运维瓦片服务 ────────► PMTiles
│
├─ 高并发动态瓦片
│ └─ 数据在 PostGIS ──────────► 实时 ST_AsMVT(MBTiles 缓存)
│
├─ 对接遗留系统
│ └─ 必须 ────────────────────► Shapefile(用完尽快转出)
│
└─ 传统 GIS 平台对接
└─ 标准要求 ────────────────► WMS / WFS / WMTS
各环节推荐格式一个典型的 WebGIS 项目里,不同环节用不同格式: 环节 | 格式 | 理由 |
|---|
数据库存储 | PostGIS(原生 geometry) | 索引 + 空间查询 | 瓦片生成 | MVT(实时或预生成) | 传输优化 | 底图分发 | PMTiles | 零运维 | 数据交换 | GeoPackage | 格式保真 + 索引 | API 响应 | GeoJSON | 通用可读 | 离线交付 | FlatGeobuf | 压缩比 | | | |
|