聚合图层:六边形与热力
聚合图层的输入是原始点位,输出是空间单元。选择六边形、网格还是热力, 取决于要表达「多少个」还是「有多密」,两者对半径单位的要求也不一样。
聚合是一次 GPU 分箱
HexagonLayer 先把每个点归入六边形单元,统计单元内的点数或权重和,
再按统计值给单元上色。因此 radius 的单位是米,不是像素,
缩放时单元会跟着地面一起变化。
var hexagon = new deck.HexagonLayer({
id: 'density-hex',
data: stations,
getPosition: function (d) { return [d.lng, d.lat]; },
getColorWeight: function (d) { return d.flow; },
colorAggregation: 'SUM',
radius: 900,
coverage: 0.92,
extruded: true,
elevationScale: 12,
elevationRange: [0, 3000],
colorRange: [
[255, 245, 200],
[255, 210, 120],
[255, 160, 60],
[240, 100, 40],
[190, 40, 60]
],
pickable: true,
autoHighlight: true
});
coverage 控制六边形填充比例,1 表示单元紧贴,0.8 会在单元之间留出缝隙。
elevationScale 只是视觉放大,不改变统计数据。
颜色区间是分位数映射。colorRange 的几档颜色默认按统计值的分位切分,
不是等间距数值。需要固定阈值时用 colorDomain 显式指定范围。
热力图:连续密度
HeatmapLayer 在屏幕空间叠加高斯核,半径以像素计。
它不产生可拾取的单元,适合做背景密度层,不适合承载交互。
var heat = new deck.HeatmapLayer({
id: 'density-heat',
data: stations,
getPosition: function (d) { return [d.lng, d.lat]; },
getWeight: function (d) { return d.flow; },
radiusPixels: 42,
intensity: 1.4,
threshold: 0.06,
colorRange: [
[0, 0, 255, 0],
[0, 128, 255, 120],
[0, 255, 200, 180],
[255, 220, 0, 220],
[255, 80, 0, 255]
],
aggregation: 'SUM'
});
threshold 用来压掉低权重的噪点,intensity 提高整体亮度。
两个参数都调过之后仍偏暗,通常是权重没有归一化。
| 参数 | 适用图层 | 单位 | 说明 |
|---|---|---|---|
radius | HexagonLayer / GridLayer | 米 | 单元尺寸,随缩放变化 |
cellSize | GridLayer | 米 | 方格边长 |
radiusPixels | HeatmapLayer | 像素 | 核半径,缩放时不变 |
coverage | HexagonLayer | 0–1 | 单元填充比例 |
getColorWeight | 聚合图层 | 数值 | 参与统计的权重 |
colorAggregation | 聚合图层 | SUM / MEAN / MAX | 单元内权重如何合并 |
elevationScale | HexagonLayer / GridLayer | 倍数 | 仅影响高度显示 |
两种聚合的组合用法
低缩放级别用热力图看整体分布,放大后切换为六边形并显示计数。
两个图层共享同一份数据,通过 visible 切换,避免同时渲染造成叠加失真。
function layersFor(zoom) {
var showHex = zoom >= 11;
return [
new deck.HeatmapLayer({
id: 'density',
data: stations,
getPosition: function (d) { return [d.lng, d.lat]; },
getWeight: function (d) { return d.flow; },
radiusPixels: 36,
visible: !showHex
}),
new deck.HexagonLayer({
id: 'hex',
data: stations,
getPosition: function (d) { return [d.lng, d.lat]; },
getColorWeight: function (d) { return d.flow; },
colorAggregation: 'SUM',
radius: 700,
extruded: true,
visible: showHex
})
];
}
注意事项
- 聚合结果不可逐条拾取。
info.object是单元对象,原始点在其points属性里。 radius过大时一个单元会吞掉整片区域,过小则单元数量暴增,先按视野宽度估算合适的值。- 权重字段缺失时按 1 计数,不会报错,容易误以为权重没生效。
extruded开启后单元是三维柱体,需要俯仰角才能看出高度差异。- 热力图的透明色阶会与底图混合,深色底图上应把低值档的 alpha 调高。
先定统计口径再调视觉。颜色区间、高度倍数都只是表达手段, 单元内的统计值才是数据。口径不稳定时,换一个缩放级别结论就会变。
经纬志(2026)。《聚合图层:六边形与热力》。https://www.jingweizhi.com/deckgl/tutorial/aggregation.html(访问日期 2026-11-03)。