【2025最新】ArcGIS 点聚合功能实现全教程(进阶版) - 实践
2025-09-25 18:04 tlnshuju 阅读(0) 评论(0) 收藏 举报ArcGIS 点聚合功能实现全教程(进阶版)
本教程聚焦点数据生成、多类别样式配置、聚合开关控制及类别筛选等核心功能的进阶实现逻辑,深入解析点聚合功能进阶用法。本文为《【2025最新】ArcGIS for JS点聚合功能实现》进阶版,关于地图初始化、模块导入、基础组件配置等入门内容不再赘述。
文章目录
- ArcGIS 点聚合功能实现全教程(进阶版)
- 效果图
- 实现功能
- 一、核心功能实现步骤
- (一)点要素图层创建
- (二)点聚合功能配置
- (三)辅助功能实现
- 二、其他
- 三、全部代码
- index.html
- tiandituLoader.js
工具 /插件/系统 名 | 版本 | 说明 |
---|---|---|
ArcGIS for JavaScript | 4.33 | 适用4.28 - 4.33版本 |
效果图
效果1 | 效果2 |
---|---|
![]() | ![]() |
实现功能
- 聚合开关切换:通过 “启用 / 禁用聚合” 按钮控制聚合状态,点击时切换图层featureReduction属性(聚合模式 / 非聚合模式),并同步更新按钮文本,实现交互化聚合控制。
- 类别条件筛选:通过下拉框提供 “全部 + 4 个类别” 的筛选选项,选择后触发图层筛选逻辑,仅显示符合category条件的点要素,同时关闭当前弹窗避免信息干扰,实现精准数据筛选。
- 聚合样式:不同类别的聚合簇采用对应的图标。
一、核心功能实现步骤
(一)点要素图层创建
- 定义数据结构:设置字段信息,包含唯一标识、类别与数值字段
fields: [{
name: "ObjectID",
alias: "ObjectID",
type: "oid"
}, {
name: "category",
alias: "类别",
type: "integer"
}, {
name: "value",
alias: "值",
type: "integer"
}]
- 生成随机点数据:通过
generateRandomPoints
函数创建 5000 个随机点,经度范围 0-119,纬度范围 30-60,随机分配 4 个类别
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() * 4);
points.push({
geometry: {
type: "point",
longitude: lon,
latitude: lat
},
attributes: {
ObjectID: i,
category: category,
value: Math.floor(Math.random() * 100)
}
});
}
return points;
}
- 设置要素样式:采用唯一值渲染,为 4 个类别分别设置不同样式,包括简单圆形标记与图片标记
renderer: {
type: "unique-value",
field: "category",
uniqueValueInfos: [
{
value: 0, symbol: {
type: 'simple-marker',
color: [24, 174, 255, 0.5],
size: 16,
style: "circle",
outline: {
color: [24, 174, 255, 0.8],
width: 2
}
},
label: "类别1"
},
// 其他类别样式配置...
]
}
- 配置弹窗模板:点击单点时显示类别与数值信息
popupTemplate: {
title: "{category}",
content: "类别:{category},值:{value}",
}
(二)点聚合功能配置
- 生成聚合配置:通过
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(res => res.primaryScheme);
return {
type: "cluster",
popupTemplate,
labelingInfo,
clusterMinSize,
maxScale: 50000
};
}
- 实现聚合开关:通过
toggleClustering
函数切换聚合状态,点击按钮时修改featureReduction
属性
function toggleClustering() {
let fr = layer.featureReduction;
layer.featureReduction = fr && fr.type === "cluster" ? null : featureReduction;
toggleButton.innerText = toggleButton.innerText === "启用聚合" ? "禁用聚合" : "启用聚合";
}
(三)辅助功能实现
- 图例组件:创建图例并关联地图视图,展示各类别样式说明
const legend = new Legend({
view,
container: "legendDiv",
});
- 类别筛选:监听下拉框变化,通过
layerView.filter
设置筛选条件,筛选特定类别点数据
filterSelect.addEventListener("change", (event) => {
const newValue = event.target.value;
const whereClause = newValue ? \`category = ${newValue}\` : null;
layerView.filter = { where: whereClause };
view.closePopup();
});
- 聚合弹窗样式优化:修改聚合区域边界样式,增强视觉辨识度
reactiveUtils.whenOnce(() => view.popup.viewModel)
.then(() => {
view.popup.viewModel.selectedClusterBoundaryFeature.symbol = {
type: "simple-fill",
style: "solid",
color: "rgba(50,50,50,0.8)",
outline: { width: 0.5, color: "rgba(50,50,50,0.8)" }
};
});
二、其他
符号类型匹配:确保点要素使用
simple-marker
或picture-marker
类型,避免因符号类型错误导致渲染失效类别值匹配:筛选下拉框的
value
属性需与category
字段值一致(0-3),原示例中值为 1-4 需修正为 0-4按钮初始文本:聚合按钮初始文本应设为 “启用聚合”,与切换逻辑匹配
要素加载时机:所有依赖图层的操作需在
layer.when()
回调中执行,确保图层加载完成
三、全部代码
index.html
ArcGIS 点聚合基础示例
html,
body,
#viewDiv {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#infoDiv {
background: white;
padding: 10px;
}
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}",
},
renderer: {
type: "unique-value",
field: "category",
uniqueValueInfos: [
{
value: 0, symbol: {
type: 'simple-marker', // 点要素专用符号类型(核心修复点)
color: [24, 174, 255, 0.5], // 半透明蓝色(与原需求一致)
size: 16, // 点的大小(像素,建议12-20,适配视觉)
style: "circle", // 点的形状(circle/方形/square/三角形/triangle等)
outline: { // 点的描边(增强辨识度)
color: [24, 174, 255, 0.8],
width: 2
}
},
label: "类别1"
},
{
value: 1, symbol: {
type: "picture-marker",
url: "https://picsum.photos/20/20", // 20x20的图片
width: "20px",
height: "20px",
yoffset: "10px" // 图标偏移,使底部对准点位置
}, label: "类别2"
},
{
value: 2, symbol: {
type: 'simple-marker', // 点要素专用符号类型(核心修复点)
color: [24, 14, 255, 0.5], // 半透明蓝色(与原需求一致)
size: 16, // 点的大小(像素,建议12-20,适配视觉)
style: "circle", // 点的形状(circle/方形/square/三角形/triangle等)
outline: { // 点的描边(增强辨识度)
color: [24, 14, 255, 0.8],
width: 2
}
}, label: "类别3"
},
{
value: 3, symbol: {
type: 'simple-marker', // 点要素专用符号类型(核心修复点)
color: [24, 144, 55, 0.5], // 半透明蓝色(与原需求一致)
size: 16, // 点的大小(像素,建议12-20,适配视觉)
style: "circle", // 点的形状(circle/方形/square/三角形/triangle等)
outline: { // 点的描边(增强辨识度)
color: [24, 144, 55, 0.5],
width: 2
}
}, label: "类别4"
}
]
}
});
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 extent
view.popup.viewModel.selectedClusterBoundaryFeature.symbol = {
type: "simple-fill",
style: "solid",
color: "rgba(50,50,50,0.8)",
outline: {
width: 0.5,
color: "rgba(50,50,50,0.8)",
},
};
});
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;
// 核心添加,切换点聚合模式,
const toggleButton = document.getElementById("toggle-cluster");
toggleButton.addEventListener("click", toggleClustering);
// To turn off clustering on a layer, set the
// featureReduction property to null
function toggleClustering() {
let fr = layer.featureReduction;
layer.featureReduction = fr && fr.type === "cluster" ? null : featureReduction;
toggleButton.innerText =
toggleButton.innerText === "启用聚合"
? "禁用聚合"
: "启用聚合";
}
view.whenLayerView(layer).then((layerView) => {
const filterSelect = document.getElementById("filter");
filterSelect.addEventListener("change", (event) => {
const newValue = event.target.value;
const whereClause = newValue ? `category = ${newValue}` : null;
console.log(whereClause)
layerView.filter = {
where: whereClause,
};
view.closePopup();
});
});
})
.catch((error) => {
console.error(error);
});
async function generateClusterConfig(layer) {
// generates default popupTemplate
const popupTemplate = await clusterPopupCreator
.getTemplates({ layer })
.then((popupTemplateResponse) => popupTemplateResponse.primaryTemplate.value);
// generates default labelingInfo
const { 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
类别筛选(category):
全部
类别1
类别2
类别3
类别4
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.mzph.cn/news/917347.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!相关文章
隐藏在众目睽睽之下:从PEB中解除恶意DLL的链接
本文深入探讨了一种恶意软件用于隐藏注入DLL的反取证技术。详细解析了Windows进程环境块(PEB)的结构,并展示了如何通过操作PEB中的三重双向链表来隐藏已加载的恶意DLL,包括具体的代码实现和检测方法。隐藏在众目睽睽…
详细介绍:Java 领域中 Java-EE 的异步编程实现
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
营销型网站公司名称手机wap网站模板 带后台
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,…
网站qq聊天代码深圳网站建设公司服务商
mqtt:轻量级物联网消息推送协议。 目录
一、介绍 1、官方文档 1)npm网 2) 中文网
MQTT中文网_MQTT 物联网接入平台-MQTT.CN
2、官方示例
二、准备工作
1、安装依赖包 2、示例版本
三、使用步骤
1、在单页面引入 mqtt
四、完整示例
tips 一、介…
设计模式六大原则 - 实践
设计模式六大原则 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &q…
深入解析:豆包Seedream 4.0:全面测评、玩法探索与Prompt解读
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
运营商 API 安全最佳实践、案例与方案推荐(2025)|千万级接口的全链路实战
在 5G、云原生与边缘协同的现实架构里,运营商的 API 安全应遵循一条清晰主线:资产可视 → 行为基线 → 联动处置 → 可审计证据。落地层面需要可度量、可复核的硬指标作为抓手,例如 分钟级增量捕获、告警≤0.5s、MT…
HyperWorks许可与多用户支持
在工程项目中,软件许可管理和多用户支持是确保团队协作顺畅进行的核心要素。HyperWorks作为一款领先的工程仿真软件,不仅提供了灵活的许可管理方案,还具备卓越的多用户支持功能,助力团队高效协作,共创卓越成果。
…
免费素材库短视频素材网站如何做网站知乎
大家都知道光模块是影响整个网络性能的关键因素,特别是在工业以太网中,网络连接控制的多为大型工业设备,光模块的稳定性尤为重要,那么,我们该如何选购工业级光模块呢?接下来就由飞畅科技的小编来为大家详细…
破局与进化:火山引擎Data Agent从落地实践到架构未来
本文为火山引擎技术专家陈硕,在AICon全球人工智能与机器学习技术大会上的演讲分享。本文围绕以下五部分展开:Data Agent整体介绍
智能分析Agent产品演进
智能分析Agent技术架构演进
智能分析Agent落地新进展
Data Ag…
建立网站平台做ppt的软件怎么下载网站
文章目录 写在前面Tag题目来源解题思路方法一:链表转数组方法二:自顶向下归并排序方法三:自底向上的归并排序 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内…
使用trace进行排查网络瓶颈
func NewHTTPTraceLogger(ctx context.Context, fileUrl string, fragmentID, attempt int) context.Context {traceStart := time.Now()var dnsStart, connectStart, tlsStart, gotConnTime time.Timetrace := &h…
五项能力斩获满分!天翼云云WAF获IDC权威认可!
近日,国际数据公司(IDC)发布《协同大模型防火墙能力的中国WAAP厂商技术能力评估,2025》报告,围绕Web安全、Bot管理、威胁情报等核心现代应用防护需求,对厂商的产品技术与服务能力展开全面考察。天翼云云WAF产品在…
什么样的代码可以称得上是好代码? - 浪矢
目录
好代码不仅需满足功能需求,还要考虑未来的拓展,问题的排查,用户的体验和成本控制。
在Code Review & 开发行为规范中我从代码开发与实现规范,异常处理规范,日志管理规范以及版本控制与写作规范四个维度梳…
抖胆代理商,DD3118S芯片,USB3.0读卡方案,替代GL3213S方案
抖胆代理商,DD3118S芯片,USB3.0读卡方案,替代GL3213S方案DD3118s是抖胆科技推出的一款读卡器控制芯片,DD3118S基于40nm低功耗工艺设计,集成了USB 3.0、SD 3.0和eMMC 4.5协议支持能力。其最大特点是创新性地采用了…
JavaEE 导读与环境配置 - 实践
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
深圳 响应式网站建设广州网站推广哪家强
在C中,函数参数的传递方式主要有三种:值传递、引用传递和指针传递。下面我会分别解释这三种方式的区别: 值传递(Pass by Value): 值传递是将实际参数的值复制给函数的形式参数。这意味着函数接收的是原始数据的一个副本…
中宁网站建设公司网页美工设计中职期末试卷
【漏洞详情】 漏洞描述:Alibaba Nacos derby 存在远程代码执行漏洞,由于Alibaba Nacos部分版本中derby数据库默认可以未授权访问,恶意攻击者利用此漏洞可以未授权执行SQL语句,从而远程加载恶意构造的jar包,最终导致任意…
南昌网站排名ui设计师的工作内容是什么
为当前组件添加内容模糊效果。 说明: 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 foregroundBlurStyle
foregroundBlurStyle(value: BlurStyle, options?: ForegroundBlurStyleOptions)
为当前组件提供…