如果你负责的数字孪生项目已经跑通场景加载和基础标注,接下来大概率会收到一个需求:“把市区的餐饮、酒店、学校、停车场网点都标到三维场景上”。数据拿回来以后打开一看,几千行,甚至上万行。于是你把这一批 POI 点直接作为标记渲染到场景里,问题立刻出现:场景开始掉帧,点标记互相遮挡,用户扫一眼根本看不出哪个区域是热点。几十个点的时候看不出差别,几千个点的时候,“有数据”反而变成了“没信息”。
POI 点聚合就是处理这种信息密度的标准方案:把空间上临近的点合并成一个聚合点,显示一个数字或聚合样式,用户放大场景时再逐步展开。CIMPro 作为面向 CIM / 数字孪生场景的三维可视化平台,把这项能力封装进了 POI 点聚合 API,开发者不需要自己写聚合算法,只需要理解“图层、数据、样式、交互”这条调用链。本文会从使用场景、核心概念、调用流程、完整示例和排错思路几个角度讲清楚这套 API 的用法,也会指出真正容易踩的坑。
这里先给出一个判断:点聚合 API 本身不难,难的是把聚合半径、缩放级别、数据量级和交互体验这四件事配合好。如果只是学会了调用接口,没有理解聚合和缩放的关系,上线以后大概率会出现“聚合不生效”或“放大后点全乱了”的问题。所以这篇文章不只列参数,更希望帮你建立一套可落地的 POI 聚合实现思路。
1. 这篇文章真正要解决的问题
1.1 直接渲染几千个 POI 会发生什么
先看最直观的性能问题。三维场景里的点标记,本质上是一个个需要 GPU 绘制的图形元素。几千个 POI 直接渲染,浏览器需要维护几千个独立对象的坐标、样式、纹理和事件绑定。当地图视角旋转、缩放、漫游的时候,每一帧都可能触发大量图元的重绘,帧率从 60 FPS 掉到 20 FPS 以内是常见现象。对于数字孪生项目来说,场景里通常还有倾斜摄影模型、BIM 模型和业务面板,GPU 的渲染预算本来就很紧张,再塞入几千个点标记,卡顿几乎是必然的。
第二个问题是视觉可读性。当多个 POI 在屏幕上重叠时,用户看到的是一片互相压盖的图标,既看不清单个点的名称,也分不清点与点之间的关系。尤其在低缩放级别下,整个城市几百个餐饮网点挤在一起,视觉结果是一团色块。用户想得到的结论是“这片区域餐饮密集”,但得到的体验是“这里有很多不知道是什么的东西”。
第三个问题是交互效率。点多了以后,鼠标点击命中变得困难。你很难准确地点击到想要的那一个点,因为目标点可能被其他点完全遮盖。逐点点击查看详情,在几百个点的尺度上还能接受,在几千个点的尺度上就是灾难。用户需要的是先看到整体分布,再逐层下钻,而不是在一堆图标里做“找不同”。
1.2 点聚合解决的不只是性能
很多人把点聚合等同于“性能优化”,这个理解不够完整。点聚合真正的价值,是在渲染性能和信息可读性之间找到平衡点。在低缩放级别下,聚合物显示一个数字,告诉你这个区域有多少个 POI;随着用户放大场景,聚合簇逐步打开,最终显示出独立的 POI 点。
这个过程本质上是一条“总览-缩放-详情”的信息获取链路。用户先在宏观层面看到聚集规律,再针对感兴趣的区域放大,最终定位到具体对象。这种交互模式在地图类产品中已经被验证了很多年,也是 POI 点聚合比单纯减少数据量更好的原因:它没有丢失任何业务信息,只是把信息放在合适的缩放级别展示。
从材料反映的情况看,很多开发者也把 POI 相关的 API 用于 Excel 处理、数据下载等场景,但本文讨论的是 CIMPro 三维可视化场景中的 POI 展示问题。两者的共同点是都涉及大量 POI 数据的组织,差异在于三维场景中的 POI 还额外承担了空间定位与视觉表达的任务,数据展示的实时性和交互性要求更高。
1.3 哪些人适合阅读这篇文章
如果你正在做智慧城市、智慧园区、智慧商圈这类数字孪生项目,并且未来需要在三维场景中接入大量 POI 数据,这篇文章适合你;如果你的项目已经接入了 POI 图层,但是放大缩小以后聚合表现不稳定,或者几千条数据加载后明显卡顿,这篇文章也适合你。
阅读之前,最好已经具备一定的 JavaScript 开发经验,了解三维场景中的“图层”概念。这样理解聚合图层的创建、数据绑定和事件监听会更快。如果你完全是零基础,建议先拿官方示例跑通一个最小三维场景,再回来看本文的聚合部分。
2. POI 与点聚合:概念和核心原理
2.1 什么是 POI 数据
POI 全称 Point of Interest,中文通常叫兴趣点。在地图和数字孪生场景里,POI 指的是某个位置上的具体对象,比如餐厅、酒店、学校、加油站、停车场、医院、商场等。一条 POI 数据至少包含两个核心字段:经纬度坐标和名称。实际项目中通常还会带业务属性,比如 POI 类型、评分、人流量、营业状态等。
一个常见的 POI 数据片段是这样的:
{ "id": "POI0001", "name": "望江楼餐厅", "type": "餐饮", "lng": 113.2654, "lat": 23.1298, "address": "滨江路18号", "score": 4.5 }这里lng和lat决定了点放在场景里的什么位置,name、type、score这类字段则决定了聚合图层在交互时能展示哪些业务信息。理解这一点很关键,因为点聚合 API 在绑定数据时,通常要求你明确指定哪个字段是经度、哪个字段是纬度,而不是自动识别。
2.2 什么是点聚合
点聚合(Point Clustering)是一种空间数据可视化方法。它在低缩放级别下,把空间位置接近的多个点合并成一个聚合点;聚合点上通常显示一个数字,表示这个区域内有多少个原始 POI。当用户放大场景,聚合点会按照空间位置重新计算,较大的聚合簇会分裂成更小的簇,最终在足够高的缩放级别下显示原始独立点。
可以用一个生活场景类比。你在阳台上看楼下夜市,远处看到的是几片亮光区,每片光区不知道有多少摊位;走近以后,亮光区变成一个个小摊,每个摊位的招牌都看得清。点聚合做的就是这个“从远处看整体,走近看细节”的事情,只不过它不需要你真的走进,只需要拖动鼠标放大缩小。
从技术实现看,点聚合算法通常分为网格聚合、距离聚合和层级聚合三类。网格聚合是把屏幕划分成固定大小的格子,一个格子里的点合并成一个簇;距离聚合是以某个点为中心,半径范围内的点归为一类;层级聚合则是为每个缩放级别维护一套聚合结果。实际的地图 SDK 和可视化平台往往会结合多种策略,CIMPro 的 POI 点聚合 API 把这些策略封装在底层,你通常只需要配置半径和层级范围。
2.3 关键参数:聚合半径与缩放级别
使用 POI 点聚合 API,最容易忽视但影响最大的参数是聚合半径(radius)和缩放级别(level)。
聚合半径通常以像素为单位,表示屏幕上多大的范围内会被合并成一个簇。半径设置过大,用户需要放大很多次才能看到原始点,交互路径太长;半径设置过小,聚合效果不明显,仍然会有大量点重叠。合理的做法是根据业务需求和屏幕尺寸做多组测试,而不是直接照搬示例里的默认值。
缩放级别则决定了簇的展开节奏。低缩放级别下,几乎所有的 POI 都应该聚合;随着级别升高,簇逐渐分裂;到了高缩放级别,原始点应该完全展开。如果缩放级别范围和聚合半径配合不好,可能出现两种负面效果:一是缩放到较高级别时仍然显示聚合数字,用户无法点选具体 POI;二是缩放到较低级别时就已经全部展开,聚合形同虚设。
这里要特别强调一个认知:点聚合不是静态分组。静态分组是指把点按行政区域、栅格等固定范围一次性分好,无论怎么缩放都保持分组结果;点聚合是动态的,它会随视图的缩放级别实时重新计算。理解了这个区别,你就能明白为什么聚合半径、缩放级别必须联动配置。
3. CIMPro 点聚合 API 的前置准备
3.1 CIMPro 是解决什么问题的平台
CIMPro 从产品定位上看,属于面向 CIM(City Information Model,城市信息模型)和数字孪生场景的三维可视化平台。这类平台通常负责把城市级倾斜摄影、BIM 模型、矢量数据、业务系统数据整合到同一个三维场景中,并提供二次开发能力,让实施团队能够基于平台快速搭建业务应用。
在这样的大背景下,POI 点聚合 API 是平台提供的能力之一。它不是独立存在的,而是依赖平台的三维场景、相机控件、图层管理和事件系统。换句话说,使用点聚合 API 之前,你的项目需要已经具备一个可运行的三维场景,并且已经正确初始化了 CIMPro 的运行时环境。
由于不同项目的部署版本和授权方式可能不同,具体初始化代码应以你拿到的平台文档为准。本文的示例重点演示聚合图层的调用逻辑,不纠结于某个版本号的差异。
3.2 本地环境要准备什么
从开发环境看,建议准备以下内容:
- CIMPro 平台运行环境,包括服务端和前端 SDK,版本以项目实际部署为准。
- 一个可运行的三维场景示例工程,最好是官方提供的最小 demo。
- 支持 WebGL 的浏览器,推荐 Chrome 或 Edge 的最新稳定版。
- POI 数据文件,可以是 JSON 或 GeoJSON,也可以是通过后端接口返回的数组结构。
- 前端调试工具,浏览器 DevTools 足够,重点看 Console 和 Network 面板。
如果你打算把 POI 数据放在后端接口里,还需要准备一个简单的数据服务,接口返回统一的 JSON 结构。平台一般不会限制数据来源,重点是字段映射要清晰。
3.3 POI 数据格式与坐标系
数据格式方面,建议统一使用 JSON 数组,字段名保持稳定。例如id、name、type、lng、lat是基础字段,业务字段可以自行扩展。避免使用多层嵌套结构,会加大数据绑定的复杂度。
坐标系是另一个容易被忽略的问题。很多 POI 数据来自公开地图采集,可能是 GCJ-02 坐标系;而三维场景的底图可能使用的是 WGS84 或者项目自定义坐标系。如果坐标系不一致,最直接的表现就是 POI 点整体偏移,可能偏移几十米甚至几百米,在三维城市场景里非常明显。
正确的做法是在数据入库或者前端加载前,统一坐标参考系。不要把转换逻辑散落在前端各个地方,而是应该在一处集中处理。简单项目可以在数据准备阶段用脚本转换,复杂项目建议在数据服务端统一转换后下发。
4. 点聚合 API 核心流程拆解
4.1 整体调用流程
虽然不同平台的 API 命名可能有差异,但 POI 点聚合的调用流程基本是一致的,包含五个阶段:
- 准备 POI 数据:整理好经纬度字段和业务字段。
- 创建聚合图层:在三维场景中创建一个聚合图层对象。
- 绑定数据:把 POI 数据喂给图层,并指定经纬度字段。
- 配置样式与交互:设置聚合点样式、原始点样式、点击事件和缩放行为。
- 更新与清理:在数据变化时更新图层,在不需要时销毁图层。
把这五步记住,你就掌握了点聚合 API 的主干。后面不管接口名字怎么变,都是在为这五步服务。
4.2 创建聚合图层
创建聚合图层是第一步。从封装习惯看,平台一般会提供一个工厂方法,通过参数对象一次性传入图层名称、聚合半径、缩放级别范围等配置。这一步要重点确认聚合半径的值,因为它直接决定了最终展示效果。
创建完成后,图层通常是空壳,还没有数据,也不会显示任何内容。你需要在场景的图层管理器里确认它已经注册成功,否则后续绑定数据时可能报错。
4.3 绑定 POI 数据
绑定数据时,核心是字段映射。你提供的 POI 数据可能叫longitude,也可能叫lng,还可能叫x、y。如果图层不知道哪个字段是经度、哪个是纬度,就无法把点放到正确位置。
另一点是字段的读取效率。几千条数据逐条解析时,如果每条都做一次类型判断或嵌套属性读取,初始化耗时会被拖长。建议在数据准备阶段就输出扁平化结构,字段类型统一为number或string,避免前端做额外加工。
4.4 配置聚合样式与交互
样式配置主要分两类:聚合簇样式和原始点样式。聚合簇一般显示一个圆形底标加数字,数字表示簇内 POI 数量;原始点则显示具体图标,点击后弹详情。聚合簇样式要醒目,但不要遮挡底图;原始点样式要有区分度,让用户能通过颜色或图标快速判断 POI 类型。
交互配置是点聚合 API 的亮点。最常用的是点击事件:点击聚合簇时,缩放到簇的包围范围;点击原始点时,弹出 POI 详情。有些平台还支持鼠标悬停时的预览效果,可以在小型项目里作为升级选项。
4.5 更新与清理
实际业务中,POI 数据不是静态的。用户可能切换城市、切换楼层、切换业态,每次变化都需要更新图层。更新时可以做增量更新,也可以先清空再重新绑定,具体取决于数据量。
清理阶段要注意释放资源。图层销毁后,相关的事件监听器、渲染对象和内存引用都应该一并清理,否则会出现“点已经删了但还在渲染”的残留问题。
5. 完整示例与代码实现
下面用一个典型的智慧商圈场景来演示:场景中加载了某商圈周边 1500 个 POI,包含餐饮、购物、酒店、停车场四类。我们要用 POI 点聚合 API 把这些点展示成一个可缩放、可点击的聚合图层。
5.1 样例数据
首先准备一份扁平化的 POI 数据,保存为poi.json。实际项目中,这份数据通常来自后端接口。
{ "poiList": [ { "id": "POI0001", "name": "望江楼餐厅", "type": "餐饮", "lng": 113.2654, "lat": 23.1298 }, { "id": "POI0002", "name": "中心商场", "type": "购物", "lng": 113.2711, "lat": 23.1372 }, { "id": "POI0003", "name": "云栖酒店", "type": "酒店", "lng": 113.2598, "lat": 23.1266 } ] }这里要求lng和lat是数字类型,不要用字符串。字符串类型的经纬度在参与范围计算时容易出问题。
5.2 创建聚合图层并绑定数据
以下代码演示聚合图层的创建和数据绑定。方法名基于常见三维可视化平台的命名习惯整理,接入 CIMPro 时请以当前版本的 API 文档为准,重点理解调用流程。
// 初始化场景,运行环境保证 cimpro 对象已创建 const scene = cimpro.scene; // 1. 创建聚合图层 const clusterLayer = cimpro.poi.createClusterLayer({ name: "businessPoiLayer", radius: 60, // 聚合半径,单位像素 minLevel: 3, // 最小显示层级,低于该层级不显示 maxLevel: 18 // 最大显示层级,高于该层级显示原始点 }); // 2. 通过接口加载 POI 数据 fetch("/api/poi/list") .then((res) => res.json()) .then((data) => { // 3. 绑定数据并指定经纬度字段 clusterLayer.addData(data.poiList, { longitudeField: "lng", latitudeField: "lat", nameField: "name", typeField: "type" }); });这段代码做了三件事:创建图层、加载数据、绑定字段。radius是 60 像素,意味着屏幕上 60 像素范围内的点会被合并。minLevel和maxLevel限制了图层的可见范围,可以在性能优化时使用。
5.3 配置聚合样式
为了让聚合簇一眼可读,我们给聚合点设置一个蓝色圆形底标,上面显示聚合数量;原始点则按 POI 类型显示不同颜色的图标。
// 设置聚合图层样式 clusterLayer.setStyle({ // 聚合簇样式 cluster: { backgroundColor: "#2E70FF", borderColor: "#FFFFFF", borderWidth: 2, fontColor: "#FFFFFF", fontSize: 14 }, // 原始点样式 point: { defaultIcon: "defaultPoint", size: 24 }, // 按类型区分颜色 typeStyles: { "餐饮": { icon: "foodIcon", color: "#FF6A00" }, "购物": { icon: "shoppingIcon", color: "#00B578" }, "酒店": { icon: "hotelIcon", color: "#7B61FF" }, "停车场": { icon: "parkIcon", color: "#AAAAAA" } } });聚合簇的显示数字由 API 内部根据簇内 POI 数量自动计算,不需要手工维护。如果你希望数字前面加上类型标签,例如“餐饮 12”,需要在业务层先按类型做一次分组,再分别创建聚合图层,这种方式适合业务上需要按类型切换的场景。
5.4 点击聚合簇下钻
点聚合的核心交互是“点击聚合簇,放大到该区域”。在 CIMPro 这类平台中,通常通过相机飞行的方式实现。
// 监听聚合簇点击 clusterLayer.on("clusterClick", function (event) { const cluster = event.cluster; const level = event.level; // 如果点击的是聚合簇,飞行到簇的包围范围 if (level === "cluster") { const bounds = cluster.getBounds(); cimpro.camera.flyTo({ bounds: bounds, duration: 800 }); } }); // 监听原始点点击 clusterLayer.on("pointClick", function (event) { const point = event.point; // 弹出业务详情面板,point 中包含 POI 的完整字段 showPoiDetailPanel(point); });点击聚合簇时,event.cluster对象带着这个簇的包围范围,flyTo方法把相机飞过去,聚合簇会在飞行过程中自动重新计算并展开。点击原始点时,event.point里包含了这条 POI 数据的全部字段,可以直接用于详情展示。
5.5 动态更新数据
业务场景中,用户可能切换业态、切换区域,图层数据需要动态刷新。推荐先清空旧数据,再绑定新数据,避免新旧数据叠加。
// 切换区域时更新 POI 数据 function updatePoiData(areaCode, typeFilter) { // 清空当前图层数据 clusterLayer.clear(); fetch(`/api/poi/list?areaCode=${areaCode}&type=${typeFilter}`) .then((res) => res.json()) .then((data) => { clusterLayer.addData(data.poiList, { longitudeField: "lng", latitudeField: "lat", nameField: "name", typeField: "type" }); }); }这里有一个隐含问题:频繁调用clear和addData会触发多次重绘。如果数据切换频率很高,建议判断数据量变化幅度,数据量小时可以全量更新,数据量大时考虑只更新视野范围内的数据,也就是服务端按范围裁剪后再下发。
5.6 服务端聚合的思路补充
当 POI 数据超过几十万条时,纯前端聚合的压力会非常大,因为前端需要先拿到全量数据再计算,网络传输和内存占用都会成为瓶颈。这时更适合在服务端做一次粗粒度聚合。
服务端聚合的核心思路是:把地图按缩放级别对应的网格大小进行分块,每个网格内的 POI 数量直接作为聚合点属性,前端只渲染聚合结果。这样前端拿到的数据量从几十万条下降到几千条。CIMPro 的 POI 点聚合 API 如果支持传入聚合结果,就可以直接复用现有的聚合图层样式;如果不支持,可以建一个普通 POI 图层来展示服务端聚合点,只是少了前端动态下钻的能力。
6. 运行结果与效果验证
6.1 运行后的预期表现
如果你按照第 5 章的流程执行,在低缩放级别下,场景中应该出现若干个带数字的蓝色聚合点,数字表示该区域的 POI 数量;放大视角后,聚合点逐渐分裂;继续放大到最大层级,原始 POI 点显示出来,并根据类型显示不同的颜色图标。
从事件表现看,点击蓝色聚合点,相机应当飞向该区域;点击原始点,应当弹出对应的详情面板。
6.2 怎么判断聚合是否生效
最简单的判断方法有两个。第一,把浏览器窗口缩到最小缩放级别,观察场景上的点数量:如果聚合生效,点数量会远小于 POI 总量;如果不生效,场景上仍然显示几千个独立点标记。第二,在 Console 里执行图层对象的内省方法,查看聚合簇数量:
const clusterCount = clusterLayer.getClusterCount(); console.log("当前聚合簇数量:", clusterCount);如果打印出来的聚合簇数量远小于 POI 总数,说明聚合链路是通的。getClusterCount的具体方法名以实际 API 文档为准,但这类内省方法通常都存在。
6.3 性能观察方法
性能优化的验证不能靠感觉。建议打开 Chrome DevTools 的 Rendering 面板,开启 FPS 指示器,在手动旋转和缩放三维场景的同时观察帧率变化。对比加载聚合图层前后的帧率,判断聚合是否解决了原来的卡顿问题。
同时看 Network 面板,确认 POI 数据接口的返回耗时和数据大小。如果一次返回几 MB 的 JSON,即使前端聚合做得再好,首次加载也会慢。这种情况更适合启用范围裁剪或服务端聚合。
7. 常见问题与排查思路
下面整理 POI 点聚合使用中最高频的几类问题。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| POI 全部显示成独立点,没有聚合 | 聚合半径设置过小,或缩放级别较高 | 检查 radius 参数和当前场景缩放级别 | 调试阶段把 radius 调大,确认聚合链路正常 |
| 点位置整体偏移,偏差较大 | 坐标系不一致 | 把某个 POI 的坐标与场景底图已知点对比 | 统一坐标参考系,在数据服务端完成坐标转换 |
| 点击聚合簇没有反应 | 未绑定 clusterClick 事件,或未实现相机飞行 | 检查事件监听代码,看 Console 有无报错 | 补全事件绑定,给 flyTo 设置合理的 bounds |
| 放大多级后仍然显示聚合数字 | 聚合簇的最小分裂层级设置过高 | 检查 maxLevel 和缩放级别的联动 | 提高 maxLevel,让簇在预期层级完整展开 |
| 数据量增大后页面卡顿 | 一次加载全量 POI,未做范围裁剪 | 用 Network 面板确认返回数据大小 | 后端按视口范围裁剪,或启用服务端聚合 |
| 图层销毁后点仍然残留在场景里 | 未调用销毁接口,事件监听未解绑 | 查看场景图层管理器中的图层列表 | 调用 destroy 并移除对象引用 |
排查时有一个通用顺序:先看 Console 报错,再看 Network 数据返回,最后检查图层管理状态。大多数聚合问题,要么是数据没绑定成功,要么是事件没建立,要么是参数不符合当前缩放级别。
8. 最佳实践与工程建议
8.1 数据预处理先做减法
POI 数据进入聚合图层之前,先做一次业务清洗。把不必要的字段删掉,把经纬度统一成数字类型,把坐标转换在服务端完成。前端只保留展示和交互必需的字段,可以明显减少数据解析和传输开销。尤其当 POI 数据达到几千条以上时,清洗前后的加载体验差异非常明显。
8.2 聚合半径不要照搬默认值
聚合半径直接影响用户的缩放路径。半径过大,用户要不停放大才能看到具体点;半径过小,聚合没有意义。建议在真实业务数据上做多组测试:分别用 30、50、80、100 像素测试,观察不同缩放级别下的聚合效果,再确定最终值。注意不要只看静态效果,还要拖动缩放几次,感受交互节奏是否顺畅。
8.3 事件交互要做防抖
点击聚合簇触发相机飞行,如果用户快速连续点击多个簇,相机飞行任务会不断叠加,表现就是视角反复横跳。建议在点击事件处理函数里加一个简单的防抖或锁,例如在飞行期间忽略新的飞行请求。这个细节很小,但直接影响用户对平台的印象。
8.4 图层生命周期要管理好
在单页应用里,页面切换、场景销毁、数据切换都可能涉及聚合图层的生命周期。建议把聚合图层封装成一个独立的类,统一管理创建、更新、销毁逻辑。不要在多个业务组件里各自创建实例,否则会出现图层重复、事件重复绑定等难以排查的问题。
8.5 前端聚合与服务端聚合的边界
做一个取舍判断:数据量在 1 万条以内,前端聚合足够;数据量在 1 万到 10 万条,可以尝试前端聚合配合视口裁剪;数据量超过 10 万条,强烈建议服务端聚合。前端聚合的优势是交互流畅,能实时下钻;服务端聚合的优势是传输量和内存占用低,但聚合结果不能随意展开。两者不是互斥的,可以在低缩放级别用服务端聚合结果,在高缩放级别切换为前端全量数据。
8.6 权限与安全注意
POI 数据可能涉及业务敏感信息,比如内部点位、重点设施分布。接口应该做权限控制,避免未授权访问。前端调用时不要在前端代码里硬编码高权限的认证凭证,建议通过后端代理转发,并在服务端做最小权限校验。涉及数据更新操作时,先在小范围测试环境验证,再在生产环境执行。
9. 总结
POI 点聚合 API 的调用链路并不复杂,核心是创建聚合图层、绑定数据、配置样式与交互。真正影响项目质量的,是聚合半径与缩放级别的配合、坐标系的统一、数据量级的预判,以及图层生命周期和事件交互的管理。把这几个问题想清楚,几千条 POI 的展示不会是什么难事;想不清楚,就算接口调用成功,上线后也会在交互细节上翻车。
如果接下来要深入,建议先在自己的真实数据集上完成一次聚合半径的调参实验,记录不同参数下的聚合簇数量和首屏渲染耗时。然后再做一次数据量级压测,看看你的项目在哪个量级上需要从前端聚合切换到服务端聚合。这两件事做完,你对 POI 点聚合 API 的理解就会从“会调用”变成“会用”。最后提醒一句:上线前一定要在低性能的测试机上过一遍缩放流程,数字孪生项目的用户可能大部分都是普通办公电脑,不要让点聚合成为卡顿的替罪羊。