WebGIS开发入门教程四: GeoJSON咋读?数据怎么解析?
在WebGIS开发入门教程四: GeoJSON咋读?数据怎么解析?这篇文章里,我们专门解决一个入门阶段最常见的问题:拿到一个 GeoJSON 文件以后,前端到底应该怎么读、怎么解析、怎么把里面的点线面数据变成地图上的要素。
引言:为什么 WebGIS 新手一定要先看懂 GeoJSON
很多同学学习 WebGIS 时,会先接触 Leaflet、OpenLayers 或 Mapbox GL JS。地图底图能加载出来以后,下一步通常就是加载自己的业务数据,比如门店点位、行政区边界、河流线、巡检轨迹等。
这些数据最常见的交换格式之一就是 GeoJSON。它本质上是 JSON,但按照 GIS 的规则组织了空间几何和属性信息。只要你能读懂 GeoJSON,就能理解 WebGIS 中“数据从哪里来、坐标在哪里、属性怎么取、地图怎么画”的基本链路。
本文会围绕 WebGIS GeoJSON解析 这个具体任务,讲清楚 GeoJSON 的结构、点线面数据的读取方法、前端解析流程,以及常见错误的排查方式。

背景:GeoJSON 在 WebGIS 里到底负责什么
在 WebGIS 项目中,地图通常由两类内容组成:
- 底图:例如天地图、OpenStreetMap、ArcGIS Online、Mapbox、XYZ 瓦片等。
- 业务图层:例如地块边界、监测点、道路中心线、行政区、网格单元等。
GeoJSON 主要用来承载业务图层。它既能保存空间位置,也能保存属性字段。例如一个监测站点,不仅有经纬度坐标,还可以有站点名称、编号、监测类型、所属区域等属性。
一个典型的 GeoJSON 数据通常长这样:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [116.391, 39.907]
},
"properties": {
"name": "示例点位",
"type": "监测站"
}
}
]
}
对 WebGIS 开发来说,你最需要关注三个关键词:
- FeatureCollection:要素集合,表示一组空间要素。
- geometry:几何对象,保存点、线、面的坐标。
- properties:属性对象,保存业务字段。
原理:GeoJSON 的核心结构怎么读
理解 GeoJSON数据读取,不要一上来就背规范。先记住一句话:GeoJSON 是用 JSON 表达 GIS 要素的数据格式。
1. type 字段说明当前对象是什么
GeoJSON 中大量使用 type 字段。不同位置的 type 含义不同:
| 位置 | 常见值 | 含义 |
|---|---|---|
| 根对象 | FeatureCollection | 一组要素集合 |
| 单个要素 | Feature | 一个带几何和属性的 GIS 要素 |
| geometry | Point、LineString、Polygon | 具体几何类型 |
2. geometry 保存空间坐标
geometry 是 GeoJSON 中最关键的空间部分。不同几何类型的 coordinates 层级不一样:
| 几何类型 | coordinates 示例 | 说明 |
|---|---|---|
| Point | [116.391, 39.907] | 一个点,通常为 [经度, 纬度] |
| LineString | [[116.1,39.1],[116.2,39.2]] | 一串坐标组成一条线 |
| Polygon | [[[116.1,39.1],[116.2,39.1],[116.2,39.2],[116.1,39.1]]] | 一个或多个闭合环组成面 |
这里有一个非常重要的细节:GeoJSON 标准坐标顺序通常是 [longitude, latitude],也就是 [经度, 纬度],不是很多地图 API 中常见的 [纬度, 经度]。
3. properties 保存业务属性
properties 中的内容不参与几何绘制,但它决定了你在弹窗、样式分类、筛选查询中能使用哪些字段。
{
"properties": {
"name": "朝阳区",
"adcode": "110105",
"level": "district"
}
}
例如你可以根据 level 字段设置不同颜色,也可以把 name 字段显示到点击弹窗里。
步骤:前端如何读取并解析 GeoJSON 数据
下面用一个最常见的前端流程说明 WebGIS GeoJSON解析 的基本做法。这里先不绑定具体框架,重点看数据读取逻辑。
步骤一:准备一个 GeoJSON 文件
假设项目中有一个文件:
/data/stations.geojson
文件内容如下:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [116.391, 39.907]
},
"properties": {
"name": "北京示例站",
"status": "正常"
}
}
]
}
步骤二:用 fetch 读取 GeoJSON
在浏览器端,可以用 fetch 读取本地或服务器上的 GeoJSON 文件:
fetch('/data/stations.geojson')
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('GeoJSON 读取失败:', error);
});
这一步做了两件事:
- 通过 URL 请求 GeoJSON 文件。
- 使用
response.json()把文本解析成 JavaScript 对象。
步骤三:遍历 features 数组
多数业务 GeoJSON 都是 FeatureCollection,真正的数据在 features 数组里:
fetch('/data/stations.geojson')
.then(response => response.json())
.then(data => {
data.features.forEach(feature => {
const geometry = feature.geometry;
const properties = feature.properties;
console.log('几何类型:', geometry.type);
console.log('坐标:', geometry.coordinates);
console.log('名称:', properties.name);
});
});
这就是最基础的 GeoJSON数据读取:先拿到要素集合,再逐个读取 geometry 和 properties。
步骤四:判断点线面类型
实际项目中,一个 GeoJSON 可能包含不同类型的数据。你需要根据 geometry.type 做不同处理:
function parseFeature(feature) {
const geometry = feature.geometry;
const properties = feature.properties || {};
if (!geometry) {
console.warn('缺少 geometry:', feature);
return;
}
switch (geometry.type) {
case 'Point':
parsePoint(geometry.coordinates, properties);
break;
case 'LineString':
parseLineString(geometry.coordinates, properties);
break;
case 'Polygon':
parsePolygon(geometry.coordinates, properties);
break;
default:
console.warn('暂未处理的几何类型:', geometry.type);
}
}
步骤五:解析 Point 点数据
点数据的坐标最简单,通常是一个二维数组:
function parsePoint(coordinates, properties) {
const lng = coordinates[0];
const lat = coordinates[1];
console.log('点位经度:', lng);
console.log('点位纬度:', lat);
console.log('点位名称:', properties.name);
}
如果你用 Leaflet,要注意 Leaflet 的 L.marker 接收的是 [lat, lng],所以需要调换顺序:
const lng = coordinates[0];
const lat = coordinates[1];
L.marker([lat, lng]).addTo(map);
这也是很多 GeoJSON坐标顺序 错误的来源。
步骤六:解析 LineString 线数据
线数据是一组点坐标:
function parseLineString(coordinates, properties) {
const path = coordinates.map(coord => {
const lng = coord[0];
const lat = coord[1];
return [lat, lng];
});
console.log('线名称:', properties.name);
console.log('Leaflet 可用路径:', path);
}
如果用 Leaflet 绘制:
L.polyline(path, {
color: 'blue',
weight: 3
}).addTo(map);
如果用 OpenLayers,一般不需要你手动把坐标改成 [lat, lng],而是要关注数据投影和视图投影是否一致。
步骤七:解析 Polygon 面数据
面数据比点线更容易出错,因为它的坐标多了一层数组。一个 Polygon 通常由一个外环和若干内环组成:
function parsePolygon(coordinates, properties) {
const rings = coordinates.map(ring => {
return ring.map(coord => {
const lng = coord[0];
const lat = coord[1];
return [lat, lng];
});
});
console.log('面名称:', properties.name);
console.log('面环坐标:', rings);
}
在 Leaflet 中绘制面:
L.polygon(rings, {
color: 'red',
weight: 2,
fillColor: '#ff7800',
fillOpacity: 0.4
}).addTo(map);
注意:Polygon 的第一个环通常是外边界,后面的环可能表示洞。如果面显示不正常,要检查坐标环是否闭合、坐标顺序是否正确、数据是否存在自相交。
步骤八:直接用 Leaflet 加载 GeoJSON
在入门项目中,最简单的方式是直接交给 Leaflet 的 L.geoJSON 处理:
fetch('/data/stations.geojson')
.then(response => response.json())
.then(data => {
L.geoJSON(data, {
onEachFeature: function(feature, layer) {
const name = feature.properties.name || '未命名';
layer.bindPopup(name);
},
pointToLayer: function(feature, latlng) {
return L.circleMarker(latlng, {
radius: 6,
color: '#0066cc',
fillColor: '#3399ff',
fillOpacity: 0.8
});
}
}).addTo(map);
});
Leaflet 会自动理解 GeoJSON 的 [lng, lat] 坐标顺序,并转换成它内部需要的点位对象。因此,如果使用 L.geoJSON,通常不需要你手动调换坐标。
步骤九:用 OpenLayers 加载 GeoJSON
OpenLayers 中常用 ol/format/GeoJSON 读取 GeoJSON。关键是设置正确的数据投影和地图投影。
import GeoJSON from 'ol/format/GeoJSON';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
const vectorSource = new VectorSource({
url: '/data/stations.geojson',
format: new GeoJSON({
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
})
});
const vectorLayer = new VectorLayer({
source: vectorSource
});
map.addLayer(vectorLayer);
这里的含义是:
dataProjection: 'EPSG:4326':GeoJSON 原始数据是经纬度坐标。featureProjection: 'EPSG:3857':地图视图使用 Web Mercator 投影。
如果这两个参数写错,常见结果就是图层不显示、位置偏到海里、或者比例尺看起来异常。
常见坑:GeoJSON 解析为什么经常不显示
1. 把经纬度顺序写反
GeoJSON 标准坐标顺序是 [经度, 纬度]。例如北京附近应类似:
[116.391, 39.907]
如果写成:
[39.907, 116.391]
数据会跑到错误位置。做 GeoJSON坐标顺序 排查时,可以先看坐标范围:中国大陆经度大约在 73 到 135 之间,纬度大约在 18 到 54 之间。
2. 文件不是合法 JSON
GeoJSON 首先必须是合法 JSON。常见错误包括:
- 属性名没有使用双引号。
- 数组或对象最后多了逗号。
- 字符串用了中文引号。
- 复制数据时漏掉了括号。
浏览器控制台如果出现 Unexpected token,通常就是 JSON 语法问题。
3. FeatureCollection 拼写错误
GeoJSON 对字段值大小写敏感。下面这些写法都可能导致库无法识别:
featurecollectionFeaturecollectionFeature Collection
正确写法是:
"type": "FeatureCollection"
4. Polygon 面没有闭合
Polygon 的线环一般要求首尾坐标一致:
[
[116.1, 39.1],
[116.2, 39.1],
[116.2, 39.2],
[116.1, 39.1]
]
如果首尾不闭合,部分工具可能会自动补齐,但也可能导致渲染异常或空间分析结果不可靠。
5. 坐标系和地图投影不一致
GeoJSON 常见坐标系是 WGS84,经纬度坐标,对应 EPSG:4326。而很多 Web 地图底图使用 Web Mercator,对应 EPSG:3857。
如果使用 OpenLayers,需要明确告诉它原始数据投影和地图显示投影。如果使用 Leaflet 的 L.geoJSON,一般会按经纬度数据处理,但你的数据本身仍然要保证是正确的经纬度。
6. 本地文件直接打开导致请求失败
如果你直接双击打开 HTML 文件,浏览器地址可能是 file://。这时用 fetch('/data/test.geojson') 读取文件很容易失败。
更推荐的方式是启动一个本地开发服务,例如:
python -m http.server 8000
然后访问:
http://localhost:8000
方法比较:手动解析、Leaflet、OpenLayers 怎么选
| 方法 | 适合场景 | 优点 | 注意点 |
|---|---|---|---|
| 手动解析 GeoJSON | 学习数据结构、做自定义处理 | 能真正理解 geometry 和 properties | 需要自己处理点线面坐标层级 |
| Leaflet L.geoJSON | 轻量级 WebGIS 入门、点线面展示 | 代码少,上手快,适合教学和小项目 | 复杂投影和大数据量支持有限 |
| OpenLayers GeoJSON | 专业 WebGIS、投影转换、多图层管理 | 投影、样式、交互能力更强 | API 学习成本比 Leaflet 高 |
| 后端预处理后再加载 | 大文件、复杂属性、需要过滤查询 | 前端压力小,性能更稳定 | 需要配合 PostGIS、GeoServer 或接口服务 |
如果你是 WebGIS 初学者,建议顺序是:先手动读懂 GeoJSON 结构,再用 Leaflet 快速展示,最后在需要复杂投影、编辑、空间交互时学习 OpenLayers。
检查清单:GeoJSON 数据解析前后应该检查什么
- 确认根对象
type是否为FeatureCollection。 - 确认
features是否是数组,并且数组不为空。 - 确认每个要素是否包含
geometry和properties。 - 确认
geometry.type是否为标准值,例如 Point、LineString、Polygon。 - 确认坐标顺序是否为
[经度, 纬度]。 - 确认坐标范围是否符合数据所在地区。
- 确认 Polygon 外环是否闭合。
- 确认 GeoJSON 文件是否能被浏览器正常请求。
- 确认控制台是否有 JSON 语法错误或跨域错误。
- 确认地图视图范围是否移动到了数据所在区域。
- 确认 OpenLayers 中
dataProjection和featureProjection是否设置正确。 - 确认属性字段名称是否和代码中读取的字段一致。
FAQ:GeoJSON 读取和解析常见问题
1. GeoJSON 和普通 JSON 有什么区别?
GeoJSON 是一种有空间数据规范的 JSON。普通 JSON 可以随意组织字段,而 GeoJSON 规定了 FeatureCollection、Feature、geometry、properties、coordinates 等结构,用来表达 GIS 点线面数据。
2. GeoJSON 坐标顺序到底是经纬度还是纬经度?
GeoJSON 标准通常使用 [经度, 纬度],也就是 [lng, lat]。但部分地图 API 的函数参数可能使用 [lat, lng]。所以做 WebGIS GeoJSON解析 时,要区分“GeoJSON 原始坐标顺序”和“地图 API 接收参数顺序”。
3. 为什么我的 GeoJSON 图层加载后地图上看不到?
常见原因有五类:文件请求失败、JSON 格式错误、坐标顺序写反、坐标系不匹配、地图没有缩放到数据范围。建议先打开浏览器控制台,看网络请求是否成功,再打印 GeoJSON 数据和坐标范围。
4. Leaflet 加载 GeoJSON 需要手动转换坐标吗?
如果使用 L.geoJSON(data),Leaflet 会按 GeoJSON 的 [lng, lat] 规则读取,一般不需要手动转换。只有当你自己用 L.marker、L.polyline、L.polygon 手动创建图层时,才需要注意 Leaflet 常用的 [lat, lng] 参数顺序。
5. OpenLayers 加载 GeoJSON 为什么经常位置不对?
OpenLayers 对投影更严格。很多 GeoJSON 是 EPSG:4326,而 Web 地图视图常用 EPSG:3857。如果没有正确设置 dataProjection 和 featureProjection,就可能出现位置偏移或图层不可见。
6. GeoJSON 适合加载很大的行政区边界数据吗?
小规模数据可以直接加载。若 GeoJSON 文件达到几十 MB,前端解析和渲染会明显变慢。此时建议做简化、切片、按范围请求,或者使用矢量瓦片、PostGIS 接口、GeoServer 服务等方案。
结论:读懂 GeoJSON,就是读懂 WebGIS 数据入口
GeoJSON 是 WebGIS 入门阶段最值得认真掌握的数据格式。它把空间几何放在 geometry 中,把业务信息放在 properties 中,再通过 FeatureCollection 组织成一组可渲染、可查询、可交互的地图要素。
实际开发时,不要只会复制 L.geoJSON 或 OpenLayers 示例代码。你至少要能判断点线面类型、看懂坐标数组层级、区分经纬度顺序、检查坐标系和投影问题。这样遇到 GeoJSON 不显示、位置错误、属性读不到时,才能快速定位原因。
对 WebGIS 初学者来说,推荐的练习路径是:先手动解析一个点 GeoJSON,再解析线和面,最后分别用 Leaflet 和 OpenLayers 加载同一份数据。完成这一步以后,你对 GeoJSON数据读取 和 WebGIS 图层渲染的理解会扎实很多。