CSV、GeoJSON 还是 Shapefile:你该要哪种格式?
四种格式,四套限制。选错了会悄无声息地丢数据,而这是最糟糕的丢法。
- 作者
- HuiTu Technology
- 发布时间
委托做一份数据集时,格式这个问题通常三秒钟就定了——用需求方软件默认能打开的那种。它其实值得多想一会儿,因为常见答案里有两个会悄悄把数据弄坏。
| CSV | GeoJSON | Shapefile | GeoPackage | |
|---|---|---|---|---|
| 几何对象支持 | 只支持点,以列存储 | 全部类型 | 每个文件一种类型 | 全部类型 |
| 字段名长度 | 不限 | 不限 | 10 个字符 | 不限 |
| 多图层 | 不支持 | 不支持 | 不支持 | 支持 |
| 是否存坐标系 | 不存 | 默认视作 EPSG:4326 | 存,在 .prj 里 | 存 |
| 是否保留数据类型 | 不保留 | 部分保留 | 部分保留 | 保留 |
| 每份数据的文件数 | 1 | 1 | 4 到 7 | 1 |
| 实际体积上限 | 很大 | 浏览器内约 100 MB | 硬限制 2 GB | 非常大 |
CSV:做点数据够用,别的就没救了
如果一份点数据集是要在表格软件里打开、或者要导进数据库,CSV 就是对的交付格式。它通用、能做 diff,什么工具都读得懂。它不存坐标系,所以拿到的人只能靠猜;它也表达不了线和面,除非在某一列里塞 WKT 字符串——而多数表格软件的用户接着就会把它弄坏。
GeoJSON:网页端的默认选择
GeoJSON 是纯文本,人能直接读,所有网页地图库和所有现代 GIS 软件都支持。它支持全部几何类型,也支持嵌套属性。凡是要在浏览器里展示、或者由 API 消费的数据,它都是自然的答案。
它的弱点是体积。坐标以文本存储、精度又给得过高,会产出极大的文件:同一个图层做成 GeoJSON 可能占 40 MB,做成 GeoPackage 只有 6 MB。把坐标截到小数点后六位——大约 10 厘米的精度——通常能砍掉三分之一的体积,而且没有任何实质损失。
# Trim coordinate precision and reproject in one pass
ogr2ogr -f GeoJSON out.geojson in.gpkg \
-t_srs EPSG:4326 \
-lco COORDINATE_PRECISION=6
# Anything over ~50 MB should become vector tiles instead
tippecanoe -o out.pmtiles -zg --drop-densest-as-needed out.geojsonShapefile:仍然到处都是,仍然是 1993 年的东西
shapefile 不是一个文件,而是一组文件;传输途中要是丢了 .prj 或 .dbf,数据就降级甚至彻底不可用。它有两个真会造成损害的限制,值得明说。
- 字段名会被截断到 10 个字符。population_density 变成 population;如果你同时还有 population_total,它就变成 populati_1。字段含义就这么无声地毁掉了。
- 单个文件有 2 GB 上限,如今体量大的图层动不动就超过。
- 字符编码没有可靠的声明,非 ASCII 名称传过来变成乱码的概率,高到需要提前准备应对方案。
- 每个文件只能有一种几何类型,混合图层必须拆开。
只有当对方的工作流确实需要 shapefile 时才要它——在工程与规划领域,这仍然很常见。要的时候,顺带要一份字段名对照表,让截断是被记录下来的,而不是被撞见的。
GeoPackage:优先选它
GeoPackage 是单个 SQLite 文件,可以容纳多个图层,完整保留字段名与字段类型,规范地存储坐标系,也扛得住很大的数据量。它是 OGC 标准,QGIS、ArcGIS、GDAL、PostGIS 以及所有现代工具链都支持。
如果对方的软件支持,交付用 GeoPackage 几乎总是正确答案;而在它基础上搭的网页图层,用 GeoJSON 才是正确答案。
按场景该要什么格式
| 场景 | 该要什么 |
|---|---|
| 点数据进表格软件或 BI 工具 | CSV;若标识符带前导零,再加一份 Excel |
| 网页地图或 API | GeoJSON;超过 50 MB 就用矢量切片 |
| 在 QGIS 或 ArcGIS 里做分析 | GeoPackage |
| 同事坚持要 shapefile | Shapefile 加一份字段名对照表 |
| 导入数据库 | 直接 PostGIS 入库,或者 GeoPackage |
| 归档留待复用 | GeoPackage 加一份纯文本的字段结构说明 |