100 万点地图怎么渲染?
其实想考你三件事:
渲染技术
数据分层
性能架构
1
2
3
2
3
# 一、最基础方案:WebGL 渲染
如果用普通 DOM / SVG / Canvas:
100 万节点 = 浏览器直接崩
1
所以必须用 GPU 渲染。
常见库:
- Mapbox GL JS
- deck.gl
它们本质是:
WebGL → GPU 并行绘制
1
渲染流程:
数据 → Buffer → GPU → Shader → 渲染
1
GPU 可以一次绘制 几十万 ~ 几百万点。
例如:
deck.gl ScatterplotLayer
1
支持:
百万级点位
1
# 二、第二层优化:空间分层(LOD)
100 万点 没必要全部画。
地图通常采用:
LOD (Level Of Detail)
1
不同 zoom 层级加载不同数据。
例如:
| zoom | 数据 |
|---|---|
| 5 | 城市级 |
| 8 | 区县 |
| 12 | POI |
| 16 | 单点 |
也就是:
远 → 少
近 → 多
1
2
2
# 三、第三层优化:Vector Tile(核心)
真正的生产系统不会直接加载 100 万 GeoJSON。
而是:
Vector Tile
1
原理:
地图切成瓦片
1
z/x/y
1
每个 tile 只加载 当前屏幕数据。
例如:
屏幕最多 20 个 tile
1
每个 tile:
2000 点
1
最终:
20 * 2000 = 40000
1
而不是:
1000000
1
这就是互联网地图核心架构。
VectorTile 技术:
- Mapbox
- OpenLayers
# 四、第四层优化:点位聚合(Cluster)
当 zoom 很小的时候:
一个城市可能有 50000 点
1
用户根本看不清。
所以需要:
Cluster
1
例如:
5000点 → 1个圆
1
显示:
5000
1
放大后:
5000 → 20 cluster
1
再放大:
cluster → 单点
1
很多库内置:
- Mapbox GL JS
- deck.gl
# 五、第五层优化:数据分块加载
不要:
一次返回 100 万
1
应该:
分页 + tile
1
后端通常:
PostGIS
1
按 bbox 查询:
SELECT *
FROM points
WHERE ST_Intersects(...)
1
2
3
2
3
# 六、第六层优化:GPU Instancing
百万点最强优化是:
Instanced Rendering
1
原理:
一次 draw call
渲染 N 个实例
1
2
2
而不是:
draw → 1000000 次
1
很多库内部已经实现:
- deck.gl
# 七、真实生产架构(标准答案)
一个 百万点地图系统架构:
数据层
↓
PostGIS
↓
Tile Server
↓
VectorTile
↓
MapboxGL / deck.gl
↓
WebGL GPU 渲染
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
优化策略:
VectorTile
LOD
Cluster
Instancing
1
2
3
4
2
3
4
# 八、标准答案
如果需要在地图上渲染 100 万点位,我通常会从三个层面优化:
第一是渲染层,使用 WebGL 方案,比如 Mapbox GL 或 deck.gl,让 GPU 批量渲染点位,而不是 DOM 或 Canvas。
第二是数据层,通过 VectorTile 按地图瓦片加载数据,避免一次加载全部数据。屏幕通常只会显示几十个 tile,每个 tile 只包含几千个点。
第三是可视化优化,比如在低 zoom 层级使用 cluster 聚合点位,在高 zoom 层级再展示真实点。
同时 WebGL 层会使用 instanced rendering 减少 draw call,从而支持百万级点位流畅渲染。
# 九、如果继续深挖(高级)
可能会问:
# 1 Mapbox GL 为什么快?
答案:
VectorTile + WebGL
1
# 2 GeoJSON 为什么慢?
因为:
一次加载全部
1
# 3 deck.gl 为什么能支持百万点?
因为:
GPU Instancing
1
上次更新: 2026/03/06, 03:40:06