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

前端~三维地图(cesium)点位聚合

实现效果如下

在这里插入图片描述

实现步骤

  1. 后端接口获取全部点位数据
  2. EntityCluster 是DataSource的一个属性,DataSource 中在通过加载entities 自动展示聚合数据,DataSouce 可以之前加载行政边界时候用过,可以通过load 加载数据,DataSource 是一个接口,有很多实现类,但是我们这边是从后端接口获取的,不是geoJson 数据,可以使用CustomDataSource 自定义数据源,然后赋值entities
  3. 修改聚合样式,Cesium 可以通过pinBuilder 实现点位以及聚合后的数字,修改里面的文字即可,也可以通过设置自定义图片实现。
  4. 自定义样式,按照聚合数量的多少选择不同的图片,同时设置图片的大小
  5. 很多人也可能是为了找这个图标,我提供一个方法,阿里云图标库 ,直接搜索聚合找自己想要的样式就可以

具体代码实现 MapCollection.ts

// 百瑞通泄露预警平台地图业务相关
import * as Cesium from 'cesium'
import { EgasService } from '@/api/installService'
import { MapEntityType } from '@/views/egas/gis/MapEvent'
import { CustomDiffuseCircleMaterialProperty } from '@/views/egas/gis/material/CustomDiffuseCircleMaterialProperty'export const addBaithonEquipmentPoints = async (viewer: Cesium.Viewer) => {// 1.清空地图上所有点位await clearAllPoints(viewer)// 2.获取站点数据const result: any = await EgasService.baithonEquipmentPointDataList()// 3.通过DataSource 设置点位聚合const dataSource = new Cesium.CustomDataSource('myData')result.data.forEach((item: any) => {if (item.isAlarms) {dataSource.entities.add({name: MapEntityType.BAITHON_POINT,// 通过properties 携带参数properties: new Cesium.PropertyBag(item),position: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, 0),billboard: {// 图片路径image: `/imgs/map_icon/location_warning.png`,// 像素偏移pixelOffset: new Cesium.Cartesian2(0, -10)},ellipse: {semiMajorAxis: 150,semiMinorAxis: 150,material: new CustomDiffuseCircleMaterialProperty({color: new Cesium.Color(1.0, 0.0, 0.0, 1.0),speed: 2.0,circleCount: 2,gradient: 0.2})}})} else {dataSource.entities.add({name: MapEntityType.BAITHON_POINT,properties: new Cesium.PropertyBag(item),position: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, 0),billboard: {image: `/imgs/map_icon/location_normal.png`,// 像素偏移pixelOffset: new Cesium.Cartesian2(0, -10)}})}})// 4.设置聚合属性dataSource.clustering.enabled = truedataSource.clustering.pixelRange = 15dataSource.clustering.minimumClusterSize = 3// 设置聚合属性监听dataSource.clustering.clusterEvent.addEventListener(async (clusteredEntities, cluster) => {cluster.label.show = falsecluster.label.font = '14px Helvetica'cluster.billboard.heightReference = Cesium.HeightReference.CLAMP_TO_GROUNDcluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM// 按照聚合数量进行图片设置if (clusteredEntities.length >= 20) {combineIconAndLabel('./imgs/map_icon/cluster/cluster_04.png',clusteredEntities.length,64).then((item) => {cluster.billboard.image = item.toDataURL()cluster.billboard.width = 72cluster.billboard.height = 72})} else if (clusteredEntities.length >= 12) {combineIconAndLabel('./imgs/map_icon/cluster/cluster_03.png',clusteredEntities.length,64).then((item) => {cluster.billboard.image = item.toDataURL()cluster.billboard.width = 56cluster.billboard.height = 56})} else if (clusteredEntities.length >= 8) {combineIconAndLabel('./imgs/map_icon/cluster/cluster_02.png',clusteredEntities.length,64).then((item) => {cluster.billboard.image = item.toDataURL()cluster.billboard.width = 48cluster.billboard.height = 48})} else {combineIconAndLabel('./imgs/map_icon/cluster/cluster_01.png',clusteredEntities.length,64).then((item) => {cluster.billboard.image = item.toDataURL()cluster.billboard.width = 40cluster.billboard.height = 40})}// cluster.billboard.image = pinImgcluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOMcluster.billboard.heightReference = Cesium.HeightReference.CLAMP_TO_GROUNDcluster.billboard.show = true})// 5.dataSource 添加到图层中await viewer.dataSources.add(dataSource)await viewer.flyTo(dataSource)
}export const clearAllPoints = (viewer: Cesium.Viewer) => {const entitiesToRemove: Cesium.Entity[] = []viewer.entities.values.forEach((entity) => {if (entity.name === MapEntityType.BAITHON_POINT) {entitiesToRemove.push(entity)}})entitiesToRemove.forEach((entity) => {viewer.entities.remove(entity)})
}
/*** @description: 将图片和文字合成新图标使用(参考Cesium源码)* @param {*} url:图片地址* @param {*} label:文字* @param {*} size:画布大小* @return {*} 返回canvas*/
const combineIconAndLabel = (url, label, size) => {// 创建画布对象const canvas = document.createElement('canvas')canvas.width = sizecanvas.height = sizeconst ctx = canvas.getContext('2d')return Cesium.Resource.fetchImage(url).then((image) => {// 异常判断try {ctx.drawImage(image, 0, 0)} catch (e) {console.log(e)}// 渲染字体// font属性设置顺序:font-style, font-variant, font-weight, font-size, line-height, font-familyctx.fillStyle = Cesium.Color.WHITE.toCssColorString()ctx.font = 'bold 20px Microsoft YaHei'ctx.textAlign = 'center'ctx.textBaseline = 'middle'ctx.fillText(label, size / 2, size / 2 + 4)return canvas})
}
export const clearWarning = async (viewer: Cesium.Viewer) => {await addBaithonEquipmentPoints(viewer)
}
http://www.xdnf.cn/news/13452.html

相关文章:

  • 从零打造前沿Web聊天组件:从设计到交互
  • TikTok在英国用户量达3000万
  • 增强自注意力机制CeAtt,增强局部细节!
  • Scrapy爬虫框架:数据采集的瑞士军刀(附实战避坑指南)!!!
  • 如何开始HarmonyOS 5与Godot引擎融合开发?
  • 代码随想录训练营二十六天| 654.最大二叉树 617.合并二叉树 700.二叉搜索树的搜索 98.验证二叉搜索树
  • 如何将照片从Android传输到Mac?
  • IntelliJ IDEA 豆沙绿护眼色设置
  • defineAsyncComponent
  • STM32实战:智能家居控制面板设计方案
  • 2024年12月6级第二套第一篇
  • Android11三网共存
  • Nuxt3 中使用 pnpm 安装的 NuxtImg 使用会提示找不到图片
  • 加性同态加密的原理与函数解析
  • 【凌智视觉模块】rv1106 部署 ppocrv4 检测模型 rknn 推理
  • 在 Azure 机器学习中注册 MLflow 模型
  • Postman核心功能解析
  • React Native 跨平台开发:iOS 与安卓原生模块高效交互
  • AR互动协助:开启企业协作新纪元​
  • 【开源解析】:Python打造专业级USB安全弹出工具(附完整源码)
  • 计算机体系结构中的MPU是什么?
  • spring:使用注解@获取第三方bean实例
  • MATLAB-磁偶极子的空间磁场强度仿真
  • Linux:多线程---线程控制(线程创建线程等待线程终止)
  • DSPy Prompt自动生成最佳实践
  • 包含30个APP移动端网站UI的psd适用于餐厅咖啡店面包店快餐店
  • Kotlin基础语法四
  • Spring MVC扩展与SSM框架整合
  • 不同厂商保障UEFI/BIOS安全的技术与机制详解
  • 【机器学习-线性回归-7】中心极限定理在机器学习线性回归中的重要性