GeoJSONcn
GeoJSONcn / 技术专栏 / GeoJSON 太大加载慢?用 …

GeoJSON 太大加载慢?用 TopoJSON 转换加压缩瘦身

发布于 2026-07-15 · GeoJSONcn 技术团队 · 阅读约 4 分钟

做行政区划边界数据的人,迟早会撞上一个尴尬:一个省的市界县界全画上,GeoJSON 动辄几 MB,网页一打开就转圈。我在 GeoJSONcn 处理全国四级边界时也踩过这个坑。这篇不绕弯子,只聊怎么把体积压下来。

为什么 GeoJSON 这么占地方

GeoJSON 是纯文本,每个坐标都是 [经度, 纬度] 两个数,外加上一堆引号和逗号。更致命的是相邻行政区共边:北京和河北的省界,在 GeoJSON 里会被两个 Polygon 各存一遍,数据量直接翻倍。

数量级感受一下:全国 4.6 万页边界数据,原始 GeoJSON 加起来几百 MB。直接丢给前端,谁都受不了。

TopoJSON:把共享边界只存一次

TopoJSON 是 GeoJSON 的一个变体,核心思路是拓扑编码:

效果很直接:北京和河北共用的那条省界,从两份坐标变成一份弧段加两个引用。嵌套层级越多省得越多。实测一个省的边界,TopoJSON 比 GeoJSON 小 60% 到 80%。

转出来的结构长这样:

{
  "type": "Topology",
  "arcs": [[[116, 40], [117, 40], [118, 41]]],
  "objects": {
    "provinces": { "type": "GeometryCollection", "geometries": [] }
  }
}

前端渲染前用 topojson-client 的 feature() 还原成 GeoJSON 即可,接口几乎无感。

压缩:传输层别浪费

TopoJSON 是结构化瘦身,压缩是传输瘦身,两件事要一起做:

我在 GeoJSONcn 的做法是:边界数据在生成期就转成 TopoJSON 并预压缩,边缘按 AE 头协商发版本。前端拿到的是已经很小的包,解码毫秒级。

一个容易忽略的点:精度不是越高越好

坐标小数位越多文件越大,但屏幕像素就那么些。省级边界留 4 到 5 位小数(约 1 米精度)足够,乡镇级留 5 到 6 位。盲目 15 位浮点,体积白白涨几倍,肉眼根本看不出区别。

最后

GeoJSON 体积大的根因是重复存坐标。解法是两套组合拳:结构上用 TopoJSON 去重共享边界,传输上用 Brotli 预压缩加边缘协商。处理好了,一个省的几 MB 能压到几百 KB,前端加载从转圈变秒开。

如果你手上有全国或某省的行政区划边界,想试试 TopoJSON 瘦身,可以去 GeoJSONcn 扒一份对照。下一篇聊个偏产品的技术点:下载要付费,但导出的文件又不能带水印,这矛盾怎么解?