当前位置: 首页 > news >正文

【2025最新】ArcGIS for JS点聚合功能实现

ArcGIS 点聚合功能实现

一、教程概述

本教程基于 ArcGIS API for JavaScript 4.33 版本,详细讲解如何实现地图点聚合功能。通过随机生成 5000 个地理点数据,结合天地图底图,实现点数据的自动聚合展示、聚合标签、弹窗及图例等核心功能,适用于大数据量地理点的可视化场景。

文章目录

  • ArcGIS 点聚合功能实现
    • 一、教程概述
    • 效果图
    • 二、实现的核心功能
      • (二)基础页面结构
    • 三、核心功能分步实现
      • (一)模块导入与初始化
      • (二)生成随机点数据
      • (三)创建要素图层
      • (四)初始化地图与视图
      • (五)配置点聚合功能
      • (六)添加控件与交互优化
    • 四、全部代码
      • index.html
      • tiandituLoader.js

工具 /插件/系统 名版本说明
ArcGIS for JavaScript4.33适用4.28 - 4.33版本

效果图

效果图 1效果图 2效果图 3
在这里插入图片描述在这里插入图片描述在这里插入图片描述

二、实现的核心功能

  1. 点聚合功能:实现点数据的自动聚合与分散,依据比例尺动态调整(超过 50000 比例尺不聚合);配置聚合点的专属弹窗,展示统计信息;生成聚合标签,直观呈现聚合数量。
  2. 详情弹框:支持点击聚合点查看详情,实现聚合区域的清晰标识。
  3. 添加图例控件展示图层信息。
  4. 加载天地图作为底图 案例中已经将渲染天地图(点击直达)文章中的内容额外封装成为loadTiandituBasemap方法,文章内提供了文中所需的封装代码,有其他需要的可自行封装,这里不多赘述。

(二)基础页面结构

创建包含地图容器和信息面板的 HTML 结构,设置全屏样式确保地图占满可视区域:

<div id="viewDiv"></div><div id="infoDiv" class="esri-widget"><div id="legendDiv"></div></div><style>html, body, #viewDiv {height: 100%;width: 100%;margin: 0;padding: 0;}#infoDiv {background: white;padding: 10px;}</style>

三、核心功能分步实现

(一)模块导入与初始化

采用 ES 模块方式导入所需 ArcGIS 核心模块,确保按需加载关键组件:

// 导入天地图加载工具import { loadTiandituBasemap } from './js/tiandituLoader.js';// 导入 ArcGIS 核心模块const [Map, MapView, FeatureLayer, Legend, Expand, clusterLabelCreator, clusterPopupCreator, reactiveUtils] = await \$arcgis.import(["@arcgis/core/WebMap.js","@arcgis/core/views/MapView.js","@arcgis/core/layers/FeatureLayer.js","@arcgis/core/widgets/Legend.js","@arcgis/core/widgets/Expand.js","@arcgis/core/smartMapping/labels/clusters.js","@arcgis/core/smartMapping/popup/clusters.js","@arcgis/core/core/reactiveUtils.js",]);// 加载天地图底图配置const { tiandituBasemap } = await loadTiandituBasemap();

(二)生成随机点数据

创建 generateRandomPoints 函数,生成指定数量的地理点数据,包含随机经纬度、类别及数值属性:

function generateRandomPoints(count) {const points = [];for (let i = 0; i < count; i++) {// 经度范围:0-119°E,纬度范围:30-60°Nconst lon = Math.random() * 119;const lat = Math.random() * 30 + 30;// 随机分配 0-2 三类数据const category = Math.floor(Math.random() * 3);points.push({geometry: { type: "point", longitude: lon, latitude: lat },attributes: {ObjectID: i,category: category,value: Math.floor(Math.random() * 100)}});}return points;}

(三)创建要素图层

定义包含点数据的要素图层,配置字段结构、输出字段及基础弹窗模板:

const layer = new FeatureLayer({source: generateRandomPoints(5000), // 加载5000个随机点title: "点聚合",fields: [{ name: "ObjectID", alias: "ObjectID", type: "oid" },{ name: "category", alias: "类别", type: "integer" },{ name: "value", alias: "值", type: "integer" }],outFields: ["*"], // 输出所有字段popupTemplate: { title: "{name}", content: [] }});

(四)初始化地图与视图

创建地图实例并绑定天地图底图,配置地图视图的容器、中心点及初始缩放级别:

// 初始化地图const map = new Map({basemap: tiandituBasemap, // 绑定天地图底图layers: [layer] // 添加要素图层});// 初始化地图视图const view = new MapView({container: "viewDiv", // 绑定地图容器map,center: [116.39, 39.9], // 中心点:北京坐标zoom: 4 // 初始缩放级别});

(五)配置点聚合功能

通过 generateClusterConfig 函数配置聚合参数,包含弹窗模板、标签样式及聚合触发条件:

async function generateClusterConfig(layer) {// 生成聚合弹窗模板const popupTemplate = await clusterPopupCreator.getTemplates({ layer }).then(res => res.primaryTemplate.value);// 生成聚合标签样式const { labelingInfo, clusterMinSize } = await clusterLabelCreator.getLabelSchemes({ layer, view }).then(schemes => schemes.primaryScheme);// 返回聚合配置return {type: "cluster",popupTemplate, // 聚合弹窗labelingInfo, // 聚合标签clusterMinSize, // 最小聚合尺寸maxScale: 50000 // 最大聚合比例尺(超过此值不聚合)};}// 图层加载完成后启用聚合layer.when().then(generateClusterConfig).then(featureReduction => {layer.featureReduction = featureReduction;}).catch(error => console.error(error));

(六)添加控件与交互优化

  1. 聚合弹窗样式优化:修改聚合区域的边界样式,提升视觉效果
reactiveUtils.whenOnce(() => view.popup.viewModel).then(() => {view.popup.viewModel.selectedClusterBoundaryFeature.symbol = {type: "simple-fill",style: "solid",color: "rgba(50,50,50,0.15)",outline: { width: 0.5, color: "rgba(50,50,50,0.25)" }};});
  1. 添加图例控件:创建图例并通过折叠面板添加到地图右上角
// 创建图例const legend = new Legend({ view, container: "legendDiv" });// 创建折叠面板const infoExpand = new Expand({view,content: document.getElementById("infoDiv"),expandIcon: "list-bullet",expanded: true // 默认展开});// 添加到地图UIview.ui.add(infoExpand, "top-right");

四、全部代码

index.html

<!doctype html>
<html lang="zh-CN"><head><meta charset="utf-8" /><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /><title>ArcGIS 点聚合基础示例</title><link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/light/main.css" /><script src="https://js.arcgis.com/4.33/"></script><style>html,body,#viewDiv {height: 100%;width: 100%;margin: 0;padding: 0;}#infoDiv {background: white;padding: 10px;}</style><script type="module">import { loadTiandituBasemap } from './js/tiandituLoader.js';const [Map,MapView,FeatureLayer,Legend,Expand,clusterLabelCreator,clusterPopupCreator,reactiveUtils,] = await $arcgis.import(["@arcgis/core/WebMap.js","@arcgis/core/views/MapView.js","@arcgis/core/layers/FeatureLayer.js","@arcgis/core/widgets/Legend.js","@arcgis/core/widgets/Expand.js","@arcgis/core/smartMapping/labels/clusters.js","@arcgis/core/smartMapping/popup/clusters.js","@arcgis/core/core/reactiveUtils.js",]);const { tileInfo, config, getUrlTemplate, tiandituBasemap, Basemap, WebTileLayer } = await loadTiandituBasemap();const layer = new FeatureLayer({source: generateRandomPoints(5000),title: "点聚合",fields: [{name: "ObjectID",alias: "ObjectID",type: "oid"}, {name: "category",alias: "类别",type: "integer"}, {name: "value",alias: "值",type: "integer"}],outFields: ["*"],popupTemplate: {title: "{category}",content: "类别:{category},值:{value}",},});const map = new Map({basemap: tiandituBasemap,layers: [layer],});const view = new MapView({container: "viewDiv",map,center: [116.39, 39.9],zoom: 4,});reactiveUtils.whenOnce(() => view.popup.viewModel).then(() => {// Override the default symbol representing the cluster extentview.popup.viewModel.selectedClusterBoundaryFeature.symbol = {type: "simple-fill",style: "solid",color: "rgba(50,50,50,0.15)",outline: {width: 0.5,color: "rgba(50,50,50,0.25)",},};});const legend = new Legend({view,container: "legendDiv",});const infoDiv = document.getElementById("infoDiv");view.ui.add(new Expand({view,content: infoDiv,expandIcon: "list-bullet",expanded: true,}),"top-right",);layer.when().then(generateClusterConfig).then((featureReduction) => {layer.featureReduction = featureReduction;}).catch((error) => {console.error(error);});async function generateClusterConfig(layer) {// generates default popupTemplateconst popupTemplate = await clusterPopupCreator.getTemplates({ layer }).then((popupTemplateResponse) => popupTemplateResponse.primaryTemplate.value);// generates default labelingInfoconst { labelingInfo, clusterMinSize } = await clusterLabelCreator.getLabelSchemes({ layer, view }).then((labelSchemes) => labelSchemes.primaryScheme);return {type: "cluster",popupTemplate,labelingInfo,clusterMinSize,maxScale: 50000,};}function generateRandomPoints(count) {const points = [];for (let i = 0; i < count; i++) {const lon = (Math.random() * 119) ; // 经度范围const lat = (Math.random() * 30) + 30;  // 纬度范围// 随机分配类别const category = Math.floor(Math.random() * 3);points.push({geometry: {type: "point",longitude: lon,latitude: lat},attributes: {ObjectID: i,category: category,value: Math.floor(Math.random() * 100)}});}return points;}</script>
</head><body> <div id="viewDiv"></div><div id="infoDiv" class="esri-widget"><div id="legendDiv"></div></div>
</body></html>

tiandituLoader.js


/*** 天地图加载公共模块* 功能:封装天地图底图加载逻辑,返回配置好的Basemap实例* 依赖:ArcGIS API 4.x*/
export async function loadTiandituBasemap() {try {// 1. 按需导入ArcGIS核心模块const [WebTileLayer,Basemap,TileInfo] = await $arcgis.import(["@arcgis/core/layers/WebTileLayer","@arcgis/core/Basemap","@arcgis/core/layers/support/TileInfo",]);// 2. 配置参数(可根据需求调整)const config = {tk:你的密匙, // 天地图密钥spatialReference: { wkid: 4326 },       // 目标坐标系(WGS84)subDomains: ["0", "1", "2", "3", "4", "5", "6", "7"], // 多子域名tileMatrixSet: "c",                     // 天地图瓦片矩阵集layerType: {vec: "vec", // 矢量底图cva: "cva"  // 矢量注记}};// 3. 定义瓦片信息(匹配WGS84坐标系的瓦片规则)const tileInfo = new TileInfo({dpi: 90.71428571427429,rows: 256,cols: 256,compressionQuality: 0,origin: { x: -180, y: 90 },spatialReference: config.spatialReference,lods: [{ level: 2, levelValue: 2, resolution: 0.3515625, scale: 147748796.52937502 },{ level: 3, levelValue: 3, resolution: 0.17578125, scale: 73874398.264687508 },{ level: 4, levelValue: 4, resolution: 0.087890625, scale: 36937199.132343754 },{ level: 5, levelValue: 5, resolution: 0.0439453125, scale: 18468599.566171877 },{ level: 6, levelValue: 6, resolution: 0.02197265625, scale: 9234299.7830859385 },{ level: 7, levelValue: 7, resolution: 0.010986328125, scale: 4617149.8915429693 },{ level: 8, levelValue: 8, resolution: 0.0054931640625, scale: 2308574.9457714846 },{ level: 9, levelValue: 9, resolution: 0.00274658203125, scale: 1154287.4728857423 },{ level: 10, levelValue: 10, resolution: 0.001373291015625, scale: 577143.73644287116 },{ level: 11, levelValue: 11, resolution: 0.0006866455078125, scale: 288571.86822143558 },{ level: 12, levelValue: 12, resolution: 0.00034332275390625, scale: 144285.93411071779 },{ level: 13, levelValue: 13, resolution: 0.000171661376953125, scale: 72142.967055358895 },{ level: 14, levelValue: 14, resolution: 8.58306884765625e-005, scale: 36071.483527679447 },{ level: 15, levelValue: 15, resolution: 4.291534423828125e-005, scale: 18035.741763839724 },{ level: 16, levelValue: 16, resolution: 2.1457672119140625e-005, scale: 9017.8708819198619 },{ level: 17, levelValue: 17, resolution: 1.0728836059570313e-005, scale: 4508.9354409599309 },{ level: 18, levelValue: 18, resolution: 5.3644180297851563e-006, scale: 2254.4677204799655 },{ level: 19, levelValue: 19, resolution: 2.68220901489257815e-006, scale: 1127.23386023998275 },{ level: 20, levelValue: 20, resolution: 1.341104507446289075e-006, scale: 563.616930119991375 }]});// 4. 构建天地图URL模板(支持多子域名)const getUrlTemplate = (layer) => {return `http://t0.tianditu.gov.cn/${layer}_${config.tileMatrixSet}/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${layer}&STYLE=default&TILEMATRIXSET=${config.tileMatrixSet}&TILEMATRIX={level}&TILEROW={row}&TILECOL={col}&FORMAT=tiles&tk=${config.tk}`;};// 5. 创建矢量底图图层const vecLayer = new WebTileLayer({urlTemplate: getUrlTemplate(config.layerType.vec),subDomains: config.subDomains,copyright: "天地图 © 国家地理信息公共服务平台",spatialReference: config.spatialReference,tileInfo: tileInfo});// 6. 创建矢量注记图层const cvaLayer = new WebTileLayer({urlTemplate: getUrlTemplate(config.layerType.cva),subDomains: config.subDomains,copyright: "天地图 © 国家地理信息公共服务平台",spatialReference: config.spatialReference,tileInfo: tileInfo});// 7. 创建自定义底图并返回const tiandituBasemap = new Basemap({baseLayers: [vecLayer],referenceLayers: [cvaLayer],title: "天地图矢量图(WGS84)",id: "tianditu-vector-wgs84"});return {tileInfo,config,getUrlTemplate,tiandituBasemap,WebTileLayer,Basemap};} catch (error) {console.error("天地图加载失败:", error);throw new Error("天地图公共模块加载异常,请检查依赖和配置");}
}
http://www.dtcms.com/a/395149.html

相关文章:

  • Leecode hot100 - 114. 二叉树展开为链表 基础方法到提高方法
  • 把 iOS 混淆纳入自动化测试与 CICD 从构建、回归到灰度的工程化实战
  • 初识Redis:解锁高性能缓存的魔法钥匙
  • 基于传递矩阵法计算多层结构声表面波声速
  • 中间件和分类
  • MV2DFusion:利用模态特定目标语义进行多模态三维检测
  • BeanFactory接口作用(二)
  • 速通ACM省铜第十二天 赋源码(Kirei Attacks the Estate)
  • 海外仓一件代发怎样优化拣货流程?用什么WMS能减少错拣漏拣?
  • SQL Server 定时作业
  • 大模型笔试选择题:题组1
  • 关于STL
  • clickhouse使用问题记录
  • Java 大视界:基于 Java 的大数据实时流处理在金融高频交易数据分析中的创新应用
  • 【脑电分析系列】第25篇:情绪识别与认知研究中的EEG应用:一个完整的实验设计与数据分析流程
  • Tensorflow基础——数据类型、计算图
  • 在Anaconda中安装TensorFlow1.14.0与TensorFlow2.0.0
  • 面试题:分布式锁要点总结(Redisson)
  • C++第四篇:函数增强
  • C#上位机软件:1.7 熟悉VS并开启你的第一个C#程序
  • Nextcloud App增加模块内嵌网页
  • 04-django配置日志-loguru
  • docker离线部署gpt-oss-20b流程,从下载到安装再到可以使用
  • 关系数据库MySQL的常用基础命令详解实战
  • 面向动态环境的MEC突破:MLGO微算法科技推出自适应权重深度确定性策略梯度(AWDDPG)算法,革新多用户任务迁移技术
  • Ansys Zemax | 确保自由曲面设计的可制造性
  • 智造新势力:看“文化+科技”如何重塑制造新范式
  • 【算法训练营Day25】动态规划part1
  • 打破网络壁垒:使用内网穿透轻松实现远程桌面访问
  • 2025 PyCharm IDE 社区版与专业版合并后,新手该如何安装?(附 Toolbox 图形化安装教程)