点聚合 Supercluster
Point Cluster (Supercluster)

你将学到什么
- 引入 Supercluster 做屏幕空间聚合
getClusters(bbox, zoom)按视口与层级取簇- camera.changed 监听视角变化重算
- 聚合点展开时取 最近子点 代表位置
效果说明
加载全国城市 JSON,缩放地图时相近城市合并为单图标;放大后拆散为独立 billboard。
核心概念
Supercluster 流程
GeoJSON Feature[] → supercluster.load()
↓
getClusters([west,south,east,north], zoom)
↓
BillboardCollection.add / removeAlljs
const supercluster = new Supercluster({
radius: 40, // 聚合半径(像素级算法参数)
extent: 512,
minZoom: 0,
maxZoom: 16,
});
supercluster.load(points);视口与层级
js
const bbox = viewer.camera.computeViewRectangle();
const bounds = [west, south, east, north].map(i => Cesium.Math.toDegrees(i));
// 用当前渲染瓦片 level 近似 zoom
const level = viewer.scene.globe._surface._tilesToRender[0]._level;
const clusters = supercluster.getClusters(bounds, level);聚合点代表位置
若 cluster.properties.cluster 为真,从 getLeaves 里找 离簇中心最近 的原始点,避免图标漂在空处。
实现步骤
- fetch 城市 JSON,转为
{ type:'Feature', geometry:{coordinates} } setClusterCollection(viewer, points, callback)封装聚合- 初次
setBillboards(clusters) camera.changed→billboards.removeAll()→ 重新 getClusters → setBillboards
代码要点
js
viewer.camera.changed.addEventListener(function () {
const level = getLevel();
if (!level) return;
const clusters = supercluster.getClusters(getBounds(), level);
billboards.removeAll();
setBillboards(clusters);
});依赖
案例注释要求自行引入 Supercluster(npm 或 script)。官方内置方案见下一篇 官方点聚合。
源码
完整源码见 GitHub。
小结
基础功能 · Cesium.js · 10/19
