07. GeoJSON 数据实战

4 阅读2分钟

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. 矢量瓦片与栅格瓦片