FEATURED · 精选文章

deck.gl 聚合图层完全指南:Grid、Hexagon、Contour 与 CPU/GPU 聚合架构解析

发布时间 / 2026/9/14 15:36:46
来源 / 创域科博编辑部
栏目 / 资讯中心
deck.gl 聚合图层完全指南:Grid、Hexagon、Contour 与 CPU/GPU 聚合架构解析 deck.gl 聚合图层完全指南Grid、Hexagon、Contour 与 CPU/GPU 聚合架构解析【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl聚合图层Aggregation Layers是 deck.gl 中一类先汇总、再可视化的特殊图层它们把大量原始数据点聚合为网格grid、六边形hexagon、等值线contour或热力heatmap等替代表示从而让百万级点数据也能被清晰、高效地呈现。本指南以deck.gl/aggregation-layers模块为核心系统讲解五大内置聚合图层的用法与参数深入剖析 CPU 与 GPU 两条聚合路径的原理、性能差异与选型考量并演示如何基于AggregationLayer基类与Aggregator接口编写自定义聚合图层、甚至在无图层的情况下独立执行聚合。读完本文你将掌握聚合图层的完整 API、底层架构与性能调优方法。聚合图层是什么根据官方文档 overview.md 的定义聚合图层负责对输入数据执行聚合并以替代性表示方式可视化它们——典型形态包括网格分箱grid binning、六边形分箱hexagon binning、等值线contour和热力图heatmap。该模块位于modules/aggregation-layers从源码结构modules/aggregation-layers/src可以看到它由common/通用聚合基类与聚合器、contour-layer/、grid-layer/、heatmap-layer/、hexagon-layer/、screen-grid-layer/六大部分组成。官方提供五个开箱即用的聚合图层ContourLayer等值线与等值带GridLayer网格热力图HeatmapLayer核密度热力图HexagonLayer六边形热力图ScreenGridLayer屏幕空间直方图网格安装方式npmnpm install deck.gl # 或按需安装 npm install deck.gl/core deck.gl/layers deck.gl/aggregation-layers各图层从deck.gl/aggregation-layers导出并继承 Base Layer 的基础属性GridLayer与HexagonLayer额外继承 CompositeLayer 的属性。五大聚合图层速览ContourLayer等值线与等值带ContourLayer按给定的cellSize先聚合数据得到标量场再对其运行 Marching Squares 算法生成等值线Isoline或等值带IsobandIsoline是一组分隔高于/低于某阈值区域的线段的集合只需一个阈值Isoband是填充处于某阈值区间内区域的面的集合需要两个阈值。核心配置参数默认值说明cellSize1000每个网格单元的尺寸米支持过渡动画gpuAggregationtrue浏览器支持时在 GPU 上执行聚合aggregationSUM单元值聚合运算SUM/MEAN/MIN/MAX/COUNTcontours[{threshold: 1}]等值配置数组见下zOffset0.005每个顶点附加的微小 z 偏移用于控制重叠等值线的绘制次序、避免 z-fightinggetPositionobject object.position取每个对象的坐标getWeight1每个对象的权重可为常量或函数contours数组中的每个对象支持以下键thresholdnumber等值线或number[2]等值带。等值带使用[threshold[0], threshold[1])作为阈值区间即渲染 threshold[0]且 threshold[1]的区域——下界含、上界不含colorRGBA 颜色数组默认[255, 255, 255, 255]省略 Alpha 时取 255strokeWidth仅等值线有效线宽像素默认1zIndex等值绘制次序值越高越靠上默认自动分配0到n的唯一值配合zOffset可精确排布重叠的等值线与等值带。官方示例旧金山自行车停车位数据SPACES作为权重import {Deck} from deck.gl/core; import {ContourLayer} from deck.gl/aggregation-layers; const layer new ContourLayer({ id: ContourLayer, data: https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/sf-bike-parking.json, cellSize: 200, contours: [ {threshold: 1, color: [255, 0, 0], strokeWidth: 2, zIndex: 1}, {threshold: [3, 10], color: [55, 0, 55], zIndex: 0}, {threshold: 5, color: [0, 255, 0], strokeWidth: 6, zIndex: 2}, {threshold: 15, color: [0, 0, 255], strokeWidth: 4, zIndex: 3} ], getPosition: d d.COORDINATES, getWeight: d d.SPACES, pickable: true });拾取Picking时PickingInfo.object代表一条等值线路径或一个等值带多边形其contour字段指向contours配置中对应的那一项。渲染上ContourLayer内部包含两个子图层lines等值线由 PathLayer 渲染与bands等值带由 SolidPolygonLayer 渲染。注意contours属性采用浅比较判断是否变化应保持数组引用只在需要变更时更新。GridLayer网格热力图GridLayer把数据聚合进规则网格单元的颜色与高度由其中包含的对象决定是一个 CompositeLayer。除cellSize默认1000米与gpuAggregation默认true外其颜色与高度可以分别配置colorAggregation/elevationAggregation默认SUM可选SUM/MEAN/MIN/MAX/COUNTgetColorWeight/getElevationWeight每个对象的颜色/高度权重默认1可为常量或函数getColorValue/getElevationValue分箱后对每个单元内的objects数组整体求值如points.length一旦提供会覆盖上述 weight aggregation 组合且会禁用 GPU 聚合gridAggregator自定义分箱函数接收(position, cellSize)返回表示 cell ID 的 2 个整数数组提供后同样强制回退 CPU 聚合。渲染参数包括coverage默认1单元尺寸乘数钳制在 0–1不影响分箱、extruded默认true是否启用高度、colorScaleType默认quantize可选linear/quantize/quantile/ordinal、colorDomain默认自动取运行期实际 min/max、colorRange默认 colorbrewer 6 类 YlOrRd、elevationScaleType默认linear可选quantile、elevationDomain/elevationRange默认[0, 1000]、elevationScale默认1高度乘数、upperPercentile/lowerPercentile/elevationUpperPercentile/elevationLowerPercentile百分位过滤与material挤出多边形光照材质见 using-effects 材质设置。一个经典示例GPU 聚合 3D 挤出import {Deck} from deck.gl/core; import {GridLayer} from deck.gl/aggregation-layers; const layer new GridLayer({ id: GridLayer, data: https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/sf-bike-parking.json, gpuAggregation: true, extruded: true, getPosition: d d.COORDINATES, getColorWeight: d d.SPACES, getElevationWeight: d d.SPACES, elevationScale: 4, cellSize: 200, pickable: true });拾取时PickingInfo.object包含col/row行列索引、colorValue/elevationValue聚合后的颜色/高度值、count单元内点数以及仅在 CPU 聚合下可用的pointIndices与points单元内数据对象后者要求数据为数组。GridLayer渲染一个名为cells的子图层它是对 ColumnLayer 的扩展。HexagonLayer六边形热力图HexagonLayer与GridLayer高度对称区别在于分箱形状为尖顶pointy-topped六边形核心几何参数是radius默认1000米六边形半径。其colorAggregation/elevationAggregation、getColorWeight/getElevationWeight、getColorValue/getElevationValue、hexagonAggregator等聚合配置以及coverage、extruded默认false、各类 scale / domain / range / percentile 渲染参数语义均与 GridLayer 相同。默认的hexagonAggregator改编自 d3-hexbin源码见modules/aggregation-layers/src/hexagon-layer/hexbin.ts其中pointToHexbinCPU 版本与pointToHexbinGLSLGLSL 版本是同一套六边形寻址算法的两种实现——CPU 版用于回退路径GLSL 版内嵌在 GPU 聚合着色器中。其子图层同样名为cells由 ColumnLayer 渲染。HeatmapLayer高斯核密度热力图HeatmapLayer在内部实现 高斯核密度估计Gaussian Kernel Density Estimation以连续色带呈现数据空间分布聚合始终在 GPU 上完成。其核心渲染参数参数默认值说明radiusPixels30权重扩散的圆形半径像素支持过渡动画colorRangecolorbrewer 6 类 YlOrRd热力色板intensity1像素最终权重的乘数 1偏向色带高端 1偏向低端threshold0.05低权重像素淡化比例相对最大权重的比值0–1用于柔和色块边界指定colorDomain时忽略colorDomainnull[minValue, maxValue]权重→颜色映射域SUM模式下解释为每平方米权重MEAN模式下解释为权重未指定时按当前视口自动取[maxValue * threshold, maxValue]因此颜色会随视口变化如需稳定配色如配合图例应显式指定aggregationSUM仅支持SUM与MEAN无效值回退为SUMSUM模式重叠圆叠加权重MEAN模式取加权平均weightsTextureSize2048权重纹理尺寸越小性能越好512×512 约 5–7ms2048×2048 约 50–100ms但像素化更明显debounceTimeout500视口变化触发聚合的防抖间隔毫秒大数据 大radiusPixels时可避免交互卡顿副作用是交互结束后需等待结果更新getPosition/getWeight默认 accessor /1坐标与权重 accessor平台限制在 WebGPU 上该图层使用实例化四边形与 16 位浮点渲染目标来保留高斯核密度估计无需 WebGL 点精灵在 WebGL 的 iOS Safari 上由于 WebGL 上下文不支持渲染到浮点纹理会回退到 8 位低精度模式——此时权重必须是整数且任意像素的累计权重不能超过 255。ScreenGridLayer屏幕空间直方图网格ScreenGridLayer在屏幕空间把数据聚合为直方图分箱并叠加渲染为网格。它没有cellSize取而代之的是cellSizePixels默认100分箱的像素边长与cellMarginPixels默认2钳制在[0, 5]不影响分箱。aggregation默认SUM可选SUM/MEAN/MIN/MAX/COUNT、colorScaleType默认linear仅支持linear与quantize、colorDomain、colorRange固定 6 色数组等配置语义与前文一致。一个显著特性是聚合在屏幕空间完成因此地图缩放或平移后图层必须重新聚合——这使其更适合中小规模数据集但用对场景时视觉效果非常直观。拾取对象包含col视口左侧起 0 计数、row视口顶部起 0 计数、value、count、pointIndices与points后两者仅 CPU 聚合时可用。CPU 与 GPU 聚合原理、性能与选型两条聚合路径的实现位置从源码结构看modules/aggregation-layers/src/common目录承载了聚合的通用机制aggregation-layer.ts是聚合图层基类aggregator/下则并行实现了 CPUAggregatorcpu-aggregator/子目录与 GPU 侧的 WebGL 聚合器gpu-aggregator/webgl-aggregator.ts统一实现 Aggregator 接口。gpuAggregation: true时图层优先走 GPU 路径在浏览器不支持、图层以 WebGPU 渲染WebGPU 不支持 WebGL 版 GPU 聚合、提供了gridAggregator/hexagonAggregator、或提供了getColorValue/getElevationValue等情况下GridLayer / HexagonLayer 会自动回退到 CPU 聚合。选择考量官方指南逐条解析以下六点来自 overview.md是启用 GPU 聚合前必须权衡的维度兼容性CompatibilityGPU 聚合所需的客户端特性已被常青浏览器普遍支持覆盖全球市场 95% 以上但已有用户反馈部分设备/芯片的驱动差异可能影响结果。数据规模Data sizeCPU 聚合耗时与输入数据规模基本呈线性关系GPU 聚合需要一次性开销来设置着色器与上传缓冲区但处理更多数据的边际成本极小。大于 100K 的数据集上 GPU 显著更快小数据集上 GPU 可能反而比 CPU 慢。数据分布Data distributionCPU 聚合的内存与至少包含一个数据点的单元数成正比GPU 聚合的内存与全部可能单元数成正比包括中间的空白单元。因此 GPU 更擅长密集聚集的数据而非稀疏蔓延的数据。过滤扩展Filtering基于 GPU 的扩展如 DataFilterExtension 与 MaskExtension仅与 GPU 聚合协同工作。精度PrecisionGPU 着色器只支持 32 位浮点数。虽然图层实现了缓解精度损失的补偿措施但 GPU 聚合结果与 CPU 并不保证完全一致这是预期行为项目内置了测试以确保两者一致性在可接受范围内。分箱内数据点访问Access to binned pointsGPU 聚合不暴露某个单元内包含哪些数据点。若你需要此类能力例如点击单元后列出其中的位置要么使用 CPU 聚合要么在交互时手动过滤数据。官方性能指标下表来自 overview.md使用随机数据对比 CPU 与 GPU 聚合的吞吐量#objectsCPU #iterations/secGPU #iterations/secNotes25K535359GPU 慢 33%100K119437GPU 快 267%1M12.7158GPU 快 1144%数据采集自 2016 年款 15 英寸 MacBook ProCPU2.8 GHz Intel Core i7GPUAMD Radeon R9 M370X 2 GB仅代表当时硬件下的相对趋势。可以看到数据量越大GPU 聚合的相对优势越悬殊——这正是官方建议在恰当场景下开启 GPU 聚合可显著加速应用的数据依据。选型决策速查结合上述考量可以给出如下实操判断数据 100K、且分布相对密集优先gpuAggregation: true默认即是数据量小如 25K或分布极稀疏GPU 的开销与全量单元内存可能得不偿失可显式关闭需要单元内点列表 / 自定义任意聚合函数 / 配合非 GPU 扩展必须走 CPU 路径自动回退或手动配置需要稳定颜色映射做对比展示显式指定colorDomain/elevationDomain避免自动域随视口漂移需要百分位过滤或quantile/ordinal色阶且数据高频更新这些特性在 GPU 聚合下会产生一次 GPU→CPU 的读回成本频繁更新时需评估开销。高级用法自定义聚合图层与独立聚合正如 overview.md 所述该模块支持两种高级玩法实现自定义聚合图层或完全不借助图层独立执行聚合。AggregationLayer 基类AggregationLayer实验性是deck.gl/aggregation-layers中所有图层的基类继承自 CompositeLayer源码位于modules/aggregation-layers/src/common/aggregation-layer.ts。任何子类都必须实现四个方法getAggregatorType()返回聚合器类型字符串如gpu。每次图层更新通常因 props 或 state 变化都会重新求值若类型与上一次不同旧的聚合器会被销毁并调用createAggregator创建新实例。createAggregator(type)接收getAggregatorType()的返回值返回一个 Aggregator 实例可通过this.state.aggregator访问。onAttributeChange(attributeId)当某个属性更新时调用用于同步聚合器 props并通过aggregator.setNeedsUpdate请求重算。renderLayers()返回子图层列表在此处可通过aggregator.getBins、aggregator.getResult与aggregator.getResultDomain获取聚合结果。Aggregator 接口Aggregator 接口把聚合抽象为两步排序Sort按某种属性把数据点分入分箱bins聚合Aggregate对每个分箱从其成员的一组指标values计算数值输出result多个输出可独立获得channels。一个实现接收数据点数量、每个数据点的分组映射为整型数组binId、每个通道的数值value、以及归约方法operation如 SUM输出分箱 ID 列表、每箱每通道的聚合值result、以及每个通道聚合值的 [min, max]domain。接口方法如下// 设置聚合运行时属性 aggregator.setProps({ pointCount: 10000, attributes: {...}, operations: [SUM, MEAN], binOptions: {groupSize: 5}, onUpdate: (channel) {} }); // 标记某通道需要更新不传参则更新全部通道 aggregator.setNeedsUpdate(0); // 在访问结果前调用负责分配资源并按需重算 aggregator.update(); // 在结果缓冲区绘制到屏幕前调用供依赖渲染时上下文的聚合即时更新 aggregator.preDraw(); // 获取某个分箱的信息 const bin aggregator.getBin(100); // bin.id: number[] 唯一分箱 ID // bin.value: number[] 各通道聚合值 // bin.count: number 箱内数据点数量 // bin.pointIndices: number[] | undefined 箱内数据点索引GPU 实现可能不填充 // 获取全部 bin ID 的二进制属性访问器update 未调用时返回 null const binIdsAttribute aggregator.getBins(); // 获取指定通道聚合值的二进制属性访问器 const resultAttribute aggregator.getResult(0); // 获取指定通道聚合值的 [min, max] const [min, max] aggregator.getResultDomain(0); // 释放全部资源 aggregator.destroy();此外实现还需暴露binCount成员表示聚合结果的分箱数量。官方给出的形象示例是按年龄分布做调查直方图参与者为数据点按 5 岁间隔分箱21 岁者进入 binId[20]每箱计算两个通道——参与人数每人贡献值 1SUM与平均分每人贡献其分数MEAN最终得到分箱[15, 20, 25, 30, 35, 40]、通道 0 结果[1, 5, 12, 10, 8, 3]、通道 1 结果[6, 8.2, 8.5, 7.9, 7.75, 8]及其各自 domain。CPUAggregatorCPUAggregator 在 CPU 上实现上述接口。构造参数包括dimensionsbin ID 的维度1 或 2、getBin把每个数据点映射到 bin ID 的访问器包含sources属性名数组与getValue(data, index, options)回调返回[dimensions]元素数组或null跳过该点、getValue按通道定义权重取值访问器数组。除 Aggregator 的 setProps 全部参数外还支持customOperations用自定义归约器覆盖内置运算其中对应位置的operations元素将被忽略。例如为通道 1 计算中位数function median(pointIndices: number[], getValue: (index: number) number) { const values pointIndices.map(getValue); values.sort((a, b) a - b); return values[values.length 1]; } aggregator.setProps({ customOperations: [null, median, null] });完整的直方图示例按binSize分箱、对weight求和位于 cpu-aggregator.md其中演示了如何用 Attribute 装载position/weight数据并通过setPropsupdate()驱动聚合。WebGLAggregatorWebGLAggregator 在 GPU 上实现同一接口源码位于modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-aggregator.ts。其构造参数除dimensions外还包括channelCount通道数最多 3、vs顶点着色器必须定义getBin(out int binId)或getBin(out ivec2 binId)以及按通道数对应签名的getValue、bufferLayout、modules与defines均为 luma.gl Model 配置。Props 方面除接口公共参数外还要求binIdRange每维 binId 的[start, end]范围越界 ID 被忽略与moduleSettings着色器工具的 uniform 映射。其直方图着色器示例如下uniform float binSize; in float position; in float weight; void getBin(out int binId) { binId int(floor(position / binSize)); } void getValue(out float value) { value weight; }有趣的是GPU 与 CPU 路径共享同一套六边形寻址算法——modules/aggregation-layers/src/hexagon-layer/hexbin.ts中同时导出了 CPU 版pointToHexbin与 GLSL 版pointToHexbinGLSL这正是 HexagonLayer 在两条聚合路径上保持一致分箱结果的底层保证。性能优化实战建议综合各图层文档与上述架构分析可沉淀出以下可直接落地的优化清单为大数据集开启 GPU 聚合默认gpuAggregation: true已是最优选择数据超过 100K 时收益显著官方基准 1M 点下 GPU 吞吐约为 CPU 的 11 倍以上。降低 HeatmapLayer 的weightsTextureSize512×512 纹理的权重最大值计算仅需约 5–7ms而 2048×2048 需要 50–100ms在可接受像素化程度的前提下小纹理能显著降低每帧开销。为 HeatmapLayer 设置debounceTimeout大数据集叠加较大的radiusPixels时交互期聚合更新可能导致卡顿设置正数防抖间隔可将聚合延后到交互停顿后执行。避免在 GPU 聚合下高频使用昂贵特性quantile/ordinal色阶与各类百分位过滤upperPercentile等在 GPU 路径下都会产生 GPU→CPU 的一次性读回成本数据频繁更新时应改用linear/quantize或 CPU 聚合。显式固定 domain 以稳定映射跨数据集对比或展示图例时显式传入colorDomain/elevationDomain避免自动域导致的颜色/高度漂移。按需选择 CPU 路径需要单元内点列表pointIndices/points、自定义聚合函数getColorValue/getElevationValue或与 CPU-only 扩展配合时主动接受自动回退保证功能优先。用zIndexzOffset排布 ContourLayer 的重叠等值避免 z-fighting同时通过strokeWidth控制线宽权重表达。相关文档与源码索引官方聚合图层总览docs/api-reference/aggregation-layers/overview.md各图层 APIContourLayer · GridLayer · HeatmapLayer · HexagonLayer · ScreenGridLayer高级用法AggregationLayer · Aggregator · CPUAggregator · WebGLAggregator源码模块根目录 modules/aggregation-layers/srccommon/aggregation-layer.ts、common/aggregator/、hexagon-layer/hexbin.ts及各图层子目录相关基础概念Base Layer · CompositeLayer · Attribute · DataFilterExtension · MaskExtension【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻