GeoJSON 是每个现代 Web 地图都能读取的基于 JSON 的格式。如果你在 Leaflet 上画过多边形、在 MapLibre 上为矢量图层定过样式、或者在 PostGIS 中存过服务区,那你已经在用 GeoJSON,哪怕文件后缀写的是别的。
本文讲解 GeoJSON 到底是什么、它的几何类型代表什么、它在真实系统中出现在哪里,以及当 GeoJSON 文件离开开发者笔记本进入生产环境时会咬人的那些坑。
GeoJSON 的本质
GeoJSON 是一种用于编码地理数据结构的开放格式,2016 年由 IETF 标准化为 RFC 7946。它是 JSON 的严格子集:每份 GeoJSON 文档都是有效 JSON,但规范增加了关于允许哪些键、几何如何组织、坐标如何排序的规则。
格式有意保持精简。整个规范的顶层对象类型只有九种,称职的开发者完全可以全部记在脑子里。这种精简正是 GeoJSON 成为 Web 地图通用语的原因:易读、易写、易校验。
坐标始终写作 [经度,纬度](可选第三个值为海拔),坐标参考系固定为 WGS84,与手机 GPS 使用的基准相同。没有谈判,没有投影元数据,也没有轴序之争。一种基准、一种顺序,到处通用。
几何类型
GeoJSON 定义了七种几何类型。前三种是基础类型:
- Point:单个坐标,用于图钉、地址和单个传感器
- LineString:两个或多个坐标的有序列表,用于路线、道路和河流
- Polygon:闭合的坐标环(首末点相同),用于建筑、地块和行政边界
接下来三种就是这些基础类型的集合:
- MultiPoint:在一个几何中包含多个点,方便把一连串门店表示为单一要素
- MultiLineString:多条线串,用于碎片化路线或河网
- MultiPolygon:多个多边形,是任何带岛屿的国家的正确选择(也就是几乎所有国家)
第七种 GeometryCollection 可以混合包含上述任意类型。规范不鼓励使用它,因为多数消费者处理得很差,而且你几乎不需要它。当你想用 GeometryCollection 时,往往说明这个模型本来应该是 FeatureCollection。
Feature 与 FeatureCollection
只有几何往往不够用。你还需要知道它代表什么。这就是 Feature 的作用:Feature 用 properties 对象包裹几何,里面承载任意元数据。
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [4.8952, 52.3702]
},
"properties": {
"name": "Amsterdam Centraal",
"type": "station",
"platforms": 15
}
}
FeatureCollection 是一组 Feature。在野外遇到的几乎每一份真实 GeoJSON 文件都是 FeatureCollection,因为真实数据集里通常包含很多东西。
关键的设计选择是 properties 是开放的。规范完全不规定它能包含什么键、值是什么类型。这是特性而不是缺陷:它意味着 GeoJSON 同时适用于街道家具、选区边界、配送区和 AIS 船舶轨迹,无需扩展格式。代价是消费方要小心:如果你依赖 properties.population 存在,自己去校验它,因为 RFC 7946 不会替你做。
GeoJSON 出现在哪里
一旦留心,你会发现 GeoJSON 在地理空间栈里无处不在:
- 地图库:MapLibre GL、Mapbox GL、Leaflet、OpenLayers 都原生消费 GeoJSON 作为图层数据源
- 矢量瓦片管线:Tippecanoe 等工具接受 GeoJSON 输入,输出 MVT(Mapbox Vector Tile)瓦片集
- 地图样式规范:Mapbox Style Specification(MapLibre 也使用)把 GeoJSON 列为一等数据源类型
- 空间数据库:PostGIS、BigQuery GIS、Snowflake 都通过专用函数导入导出 GeoJSON
- API 输出:多数现代地理编码、等时圈、路径 API 都以 GeoJSON Feature 形式返回结果,响应可直接投到地图上
- 路线折线:导航响应通常包含一个 LineString 几何,方便直接渲染
- 数据共享:开放数据门户、OpenStreetMap 导出、政府边界发布在面向 Web 用户时默认采用 GeoJSON
如果一个工具能讲任何地理空间格式,那它几乎肯定也能讲 GeoJSON。
生产环境中的坑
GeoJSON 在第一天宽容,第九十天残酷。最容易把团队套牢的陷阱:
先经度。 RFC 7946 把顺序固定为 [lon, lat]。人类、地址和多数文档都写「lat, lon」。两者搞反是 GeoJSON 最常见的 bug,结果就是你的点落到了另一个海洋。
多边形绕向。 RFC 7946 规定外环必须逆时针、内环(孔)必须顺时针。许多旧 GeoJSON 文件无视这一点。一些渲染器不在意,另一些(尤其是 Mapbox GL 处理跨经度反转的多边形时)会把多边形渲染成你想要的反面:一座小岛会变成一片孔,把世界其余地方包起来。
反子午线处理。 跨越 180/-180 经线的几何须按规范拆分。在太平洋上随手画的多边形会被渲染成一条绕地球大圈的细带。
WGS84 之外没有原生 CRS 支持。 RFC 7946 刻意删除了旧版的 crs 成员。如果数据是国家网格(British National Grid、RD New、EPSG:3857),必须先重投影到 WGS84 再序列化。输出非 WGS84 的 GeoJSON 在技术上属于不合规。
文件体积。 包含数百万个精细多边形的 FeatureCollection 可膨胀到 GB 级。要在浏览器交付时改用矢量瓦片、用 Douglas-Peucker 简化几何,或采用按行分隔的 GeoJSON(.ndjson)流式传输。
校验。 在 CI 中使用 GeoJSONLint 或 geojson-validation 库等校验器。在构建时捕获错误的绕向或反转的坐标,比从客户工单里发现要便宜得多。
MapAtlas 中的 GeoJSON
GeoJSON 是 MapAtlas 平台默认的数据交换格式。Dynamic Maps 产品直接接受 GeoJSON 数据源用于自定义叠加、样式和交互图层,无需任何预处理。
Geocoding API 以 GeoJSON Feature 形式返回匹配的地址,因此正向地理编码的结果可以直接投到地图上,或不经字段重映射地存入 PostGIS。Isochrone API 以 GeoJSON 多边形形式返回通行时间区域,意味着「15 分钟内可达地点」查询离上屏只差一次 fetch 和一次 addSource 调用。
GeoJSON 不光鲜。它只是 JSON 的一个小而有主张的子集,固定了坐标顺序,规定了少数几种几何类型。但正是这种格式让现代位置栈的每一层(从空间数据库到地图画布)都能就「一个地点是什么」达成共识。把经度顺序写对、绕向校验做好,栈的其他部分往往会自行就绪。
常见问题
什么是 GeoJSON?
GeoJSON 是一种基于 JSON 的开放地理数据格式,由 IETF 标准化为 RFC 7946。它定义了一组小型几何类型(Point、LineString、Polygon 及其 multi 变体),以及把几何与任意属性绑定的 Feature 与 FeatureCollection 对象。坐标始终以「经度,纬度」按 WGS84 基准书写,这正是每个现代 Web 地图库期望的形式。
GeoJSON 与 JSON 有什么区别?
GeoJSON 是 JSON 的严格子集,并附加了若干规则。每份 GeoJSON 文档都是有效 JSON,但并非每份 JSON 文档都是有效 GeoJSON。规范固定了顶层对象类型、几何对象的结构、坐标顺序(先经度)以及坐标参考系(WGS84)。任何不符合这些规则的内容只是恰好包含地理数据的 JSON。
什么时候应该用 GeoJSON 而不是 shapefile 或 KML?
凡是数据要在 Web 栈中流动时就用 GeoJSON:API、浏览器、PostGIS 这类数据库,以及 MapLibre、Leaflet、Mapbox GL、OpenLayers。Shapefile 在桌面 GIS 中仍很常见,但要附带四份以上文件,使用 1990 年代的二进制格式。KML 用 Google Earth 没问题,但冗长且基于 XML。在与 JSON API 打交道的所有场景里,GeoJSON 是赢家。
为什么 GeoJSON 坐标先经度?
RFC 7946 把顺序固定为「经度,纬度,可选海拔」。这与多数图形和 GIS 系统使用的 x、y、z 约定一致。它与人类书写坐标的习惯(先纬度,例如 51.5, -0.1)相反,是手写 GeoJSON 时最常见的 bug:两个值一调换,点就落到了另一个半球。GeoJSON 中永远先经度。

