欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 前端~三维地图(cesium)点位聚合

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

2025/7/9 21:29:58 来源:https://blog.csdn.net/Yue_zuozuo/article/details/148560931  浏览:    关键词:前端~三维地图(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)
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词