07. GeoJSON 数据实战
概述
GeoJSON 是 Web 地图中最常用的数据格式,本节深入学习 GeoJSON 规范和在 MapLibre 中的实战应用:
- GeoJSON 规范(RFC 7946)
- 七种几何类型
- Feature 与 FeatureCollection
- 动态加载与更新 GeoJSON
- 坐标系与投影
GeoJSON 规范
GeoJSON 是一种基于 JSON 的地理数据编码格式,遵循 RFC 7946 规范。
结构层次
GeoJSON
├── Geometry — 几何图形(7种类型)
├── Feature — 要素 = 几何 + 属性
└── FeatureCollection — 要素集合
七种几何类型
1. Point — 点
{
"type": "Point",
"coordinates": [116.39, 39.91]
}
2. MultiPoint — 多点
{
"type": "MultiPoint",
"coordinates": [
[116.39, 39.91],
[121.47, 31.23]
]
}
3. LineString — 线
{
"type": "LineString",
"coordinates": [
[116.39, 39.91],
[121.47, 31.23],
[113.26, 23.13]
]
}
4. MultiLineString — 多线
{
"type": "MultiLineString",
"coordinates": [
[[116.39, 39.91], [121.47, 31.23]],
[[113.26, 23.13], [104.07, 30.67]]
]
}
5. Polygon — 多边形
{
"type": "Polygon",
"coordinates": [
[
[116.33, 39.95], [116.45, 39.95],
[116.45, 39.87], [116.33, 39.87],
[116.33, 39.95]
]
]
}
⚠️ 多边形的第一个和最后一个坐标必须相同(闭合环)。
6. MultiPolygon — 多面
{
"type": "MultiPolygon",
"coordinates": [
[[[116.33, 39.95], [116.45, 39.95], [116.45, 39.87], [116.33, 39.87], [116.33, 39.95]]],
[[[121.40, 31.30], [121.55, 31.30], [121.55, 31.15], [121.40, 31.15], [121.40, 31.30]]]
]
}
7. GeometryCollection — 几何集合
{
"type": "GeometryCollection",
"geometries": [
{ "type": "Point", "coordinates": [116.39, 39.91] },
{ "type": "LineString", "coordinates": [[116.39, 39.91], [121.47, 31.23]] }
]
}
Feature — 要素
Feature 将 Geometry 与属性(properties)绑定:
{
"type": "Feature",
"id": "bj001",
"geometry": {
"type": "Point",
"coordinates": [116.39, 39.91]
},
"properties": {
"name": "北京",
"population": 21540000,
"level": "直辖市"
}
}
id:可选,要素唯一标识properties:自定义属性对象,用于样式表达式和弹窗展示
FeatureCollection — 要素集合
{
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "geometry": { ... }, "properties": { ... } },
{ "type": "Feature", "geometry": { ... }, "properties": { ... } }
]
}
FeatureCollection 是 MapLibre GeoJSON 数据源最常用的格式。
在 MapLibre 中使用 GeoJSON
添加 GeoJSON 数据源和图层
// 添加数据源
map.addSource('cities', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: { type: 'Point', coordinates: [116.39, 39.91] },
properties: { name: '北京', pop: 2154 }
}
]
}
})
// 添加圆点图层
map.addLayer({
id: 'cities-circle',
type: 'circle',
source: 'cities',
paint: {
'circle-radius': ['interpolate', ['linear'], ['get', 'pop'], 500, 5, 2000, 15],
'circle-color': '#1890ff'
}
})
动态更新数据
// 获取数据源并更新
const source = map.getSource('cities') as maplibregl.GeoJSONSource
source.setData(newFeatureCollection)
从远程 URL 加载
map.addSource('remote', {
type: 'geojson',
data: 'https://example.com/cities.geojson'
})
使用 fetch 加载后设置
const response = await fetch('/data/cities.geojson')
const geojson = await response.json()
const source = map.getSource('cities') as maplibregl.GeoJSONSource
source.setData(geojson)
坐标系与投影
GeoJSON 坐标系
GeoJSON 使用 WGS 84 (EPSG:4326) 坐标系:
- 经度范围:-180 ~ 180
- 纬度范围:-90 ~ 90
- 坐标顺序:
[经度, 纬度](注意:不是[纬度, 经度])
MapLibre 投影
MapLibre 内部使用 Web Mercator (EPSG:3857) 投影渲染,但数据输入仍使用 WGS 84。
💡 坐标顺序容易混淆:GeoJSON 是
[lng, lat],与百度地图等[lat, lng]不同。
TypeScript 类型支持
安装 GeoJSON 类型定义:
pnpm add -D @types/geojson
使用类型:
import type { FeatureCollection, Feature, Point } from 'geojson'
const data: FeatureCollection = {
type: 'FeatureCollection',
features: []
}
const point: Feature<Point> = {
type: 'Feature',
geometry: { type: 'Point', coordinates: [116.39, 39.91] },
properties: { name: '北京' }
}
本课小结
- GeoJSON 有 7 种几何类型:Point/MultiPoint/LineString/MultiLineString/Polygon/MultiPolygon/GeometryCollection
- Feature = 几何 + 属性,FeatureCollection 是要素集合
- MapLibre 通过 GeoJSON 数据源 + 图层来渲染 GeoJSON 数据
setData()可动态更新 GeoJSON 数据- 坐标顺序为
[经度, 纬度],使用 WGS 84 坐标系
📌 上一节:06. 数据源 Sources 📌 下一节:08. 矢量瓦片与栅格瓦片