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

前端~三维地图(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)
}

相关文章:

  • 黑马教程强化day2-1
  • 七牛云图片上传 前后端全过程
  • vue封装的echarts组件被同一个页面多次引用只显示一个的问题
  • Uncaught (in promise) TypeError: Cannot read properties of null (reading ‘xxx’)
  • Win10重装系统 (重生篇:我在华强修电脑)
  • AIGC方案-java实现视频伪动效果
  • SpringBoot + 自建GitLab + Jenkins + CentOS Stream 9 来实现自动化部署
  • 御微半导体面试总结
  • 内存泄漏系列专题分析之二十:camx swap内存泄漏实例分析
  • Jenkins + Docker + Kubernetes(JKD)自动化部署全链路实践
  • 基于OpenCV的图像增强技术:直方图均衡化与自适应直方图均衡化
  • 零基础设计模式——行为型模式 - 备忘录模式
  • LVS 负载均衡详解:四层转发原理与三种经典模式全面解析
  • eureka如何绕过 LVS 的虚拟 IP(VIP),直接注册服务实例的本机真实 IP
  • 我们来学mysql -- 8.4版本记录慢查询
  • Spring MVC扩展与SSM框架整合
  • 传统机器学习与大模型 + Prompt 的对比示例
  • 计算机系统概述(5)
  • 使用Docker申请Let‘s Encrypt证书
  • 谈文件系统
  • 珠海多语种网站制作/steam交易链接怎么看
  • 天河网站建设平台/做互联网项目怎么推广
  • 免费毕业论文答辩ppt模板/企业关键词排名优化网址
  • 可以用手机做网站吗/百度推广工资多少钱一个月
  • 邯郸网站建设最新报价/如何写软文赚钱
  • 甘肃网站建设哪家便宜/百度网站收录提交