cesium 闪烁点 实体闪烁

该博客介绍了如何使用Cesium创建动态地图效果,包括添加带有文字的点位和动态扩散的圆形。通过封装DragEntity类,实现了点位的加载和动态圆的更新。点击事件被用来使选中的点位闪烁,同时动态圆的半径会按设定的范围和步长变化。此外,还提供了清除效果的方法。
摘要由CSDN通过智能技术生成
# 效果

在这里插入图片描述

最终完整代码请看下面的封装一栏

# 基本思路

可以把当前效果,动态分成两部分,添加一个点,和添加一个圆,当点击时,动态改变点的颜色,动态改变圆的大小

# 实现方法

1. 首先我们需要生成一个球体做我们标记的容器

viewer = new Cesium.Viewer('cesiumContainer',{
            // terrainProvider: Cesium.createWorldTerrain(),
            // animation: false, // 控制场景动画的播放速度控件
            // baseLayerPicker: true, // 底图切换控件
            // baselLayerPicker:false,// 将图层选择的控件关掉,才能添加其他影像数据
            // // fullscreenButton: false, // 全屏控件
            // geocoder: false, // 地理位置查询定位控件
            // homeButton: true, // 默认相机位置控件
            // timeline: false, // 时间滚动条控件
            // infoBox: false, //是否显示信息框
            // sceneModePicker: false, //是否显示3D/2D选择器
            // selectionIndicator: false, // 点击点绿色弹出 是否显示选取指示器组件
            // sceneMode: Cesium.SceneMode.SCENE3D, //设定3维地图的默认场景模式:Cesium.SceneMode.SCENE2D、Cesium.SceneMode.SCENE3D、Cesium.SceneMode.MORPHING
            // navigationHelpButton: false, // 默认的相机控制提示控件
            // scene3DOnly: true, // 每个几何实例仅以3D渲染以节省GPU内存
            // navigationInstructionsInitiallyVisible: false,
            // showRenderLoopErrors: false, //是否显示渲染错误
            // orderIndependentTranslucency:false,//设置背景透明
            
        });

2. 然后利用cesium中 billboard 来添加目标点位
添加点位的数据格式

poin :  [{id:'12321321' , name: "北京西路测试点", type: "固定枪机", state: "在线", position: { x: 116.4568, y: 39.8926} ,text:'X'},
         {id:'43244324' , name: "阿乐修理厂门口", type: "固定枪机", state: "在线", position: {  x: 116.4568, y: 39.8944 } ,text:'+'},
         {id:'43764324', name: "裕华路加油站", type: "固定枪机", state: "在线", position: { x: 116.4566, y: 39.8923 } ,text:'?'},
         {id:'437543345', name: "康佳大药房", type: "固定枪机", state: "在线", position: { x: 116.4513, y: 39.8923 }  ,text:'!'},],

添加点位先上代码(class封装)

//加载点
 dragEntity(){
   let drag = new DragEntity({
     viewer:this.$store.state.viewer, 
   })
   let _this = this
   // this.poin = [{id:234,position:[122.8,39.9],text:"L"},{id:432,position:[122,39],text:"C"}]
   this.poin.forEach(item => {
     let entity = drag.addEntity(item);
     _this.poinEntity[item.id] = entity;
   })
 },
 

创建dragEntity.js文件

/**
 * @param {Viewer} viewer
 * 
*/
export default class DragEntity{
    constructor(val){
        this.viewer = val.viewer,
    }
    addEntity(value){
        //数据格式{id:543595234324_432423,position:[122.8,39.9],text:"L"}
        let pinBuilder = new Cesium.PinBuilder();
        let poin = this.viewer.entities.add({
            id:value.id,
            name: value.name,
            position: Cesium.Cartesian3.fromDegrees(value.position.x, value.position.y),
            billboard: {
              image: pinBuilder.fromText(value.text,Cesium.Color.ROYALBLUE, 48).toDataURL(),
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            },
            monitoItems:{
                    data:value
                },
        });
        return poin
    }
    
}

解读一下,我们封装了一个class类,将添加点的方法封装到类中方便调用,我们用“billboard”方法与cesium中PinBuilder来进行添加目标点,"PinBuilder"不会的可以看一下官网https://sandcastle.cesium.com/?src=Map%20Pins.html&label=All,然后我们将创建好的实体,return出来,用一个对象来进行接收,用对象的目的就是为了以后方便查找。来看一眼效果
在这里插入图片描述
3. 第三步我们来动态扩散圆,只需要修改上面dragEntity.js文件即可,运用ellipse方法加载圆,动态扩散元具体讲解请看https://blog.csdn.net/weixin_46730573/article/details/119505757?spm=1001.2014.3001.5502

/**
 * @param {Viewer} viewer
 * 
*/
export default class DragEntity{
    constructor(val){
        this.viewer = val.viewer,
    }
    addEntity(value){
        let minR=value.minR;//最小半径
        let maxR = value.maxR;// 最大半径
        let deviationR = value.deviationR; // 每次增加的大小
        var r1 = minR
        function changeR1() {  
            r1=r1+deviationR;//deviationR为每次圆增加的大小
            if(r1>=maxR){
                r1=minR;
            }
            return r1;
        }
        function color() {
            let x=1-r1/maxR;
            return Cesium.Color.RED.withAlpha(x);
        }
        //数据格式{id:543595234324_432423,position:[122.8,39.9],text:"L"}
        let pinBuilder = new Cesium.PinBuilder();
        let poin = this.viewer.entities.add({
            id:value.id,
            name: value.name,
            position: Cesium.Cartesian3.fromDegrees(value.position.x, value.position.y),
            billboard: {
              image: pinBuilder.fromText(value.text,Cesium.Color.ROYALBLUE, 48).toDataURL(),
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            },
            ellipse: {
                semiMinorAxis: new Cesium.CallbackProperty(changeR1,false),
                semiMajorAxis: new Cesium.CallbackProperty(changeR1,false),
                material: new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(color,false)),
                outlineColor: Cesium.Color.RED,
                show: false
            },
            monitoItems:{
                data:value
            },
        });
        return poin
    }
}

修改dragEntity函数,添加给动态圆传的半径大小{minR:0, maxR:40, deviationR:1,}

//加载点
    dragEntity(){
      let drag = new DragEntity({
        viewer:this.$store.state.viewer, 
      })
      let _this = this
      this.poin.forEach(item => {
        let entity = drag.addEntity(Object.assign(item,{minR:0, maxR:40, deviationR:1,}));
        _this.poinEntity[item.id] = entity;
      })
    },

现在动态扩散圆我们就加载出来了;

4. 我们来加载点击事件,获取是点击实体

leftDownAction(){
      let viewer = this.$store.state.viewer
        this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        let _this = this
        let id
        _this.handler.setInputAction(function (movement) {
            let pick = viewer.scene.pick(movement.position); 
            if (Cesium.defined(pick) && (pick.id.id) ) {
                // _this.leftDownFlag = true;
                id= pick.id.id;
                 console.log(id)
            }
            
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        
    },

5. 当点击到实体时,点闪烁,点击空白处时,清除闪烁,运用 Cesium.CallbackProperty() 来控制点的闪烁

	clearClick(){
      let _this = this;
      if(_this.oldId){
        _this.poinEntity[_this.oldId].billboard.color = Cesium.Color.WHITE.withAlpha(1);
        _this.poinEntity[_this.oldId].ellipse.show = false;
      }
    },
    callbackProperty(id){
      this.clearClick()
      let flog = true;
      let x = 1;
      let callbackProperty = new Cesium.CallbackProperty(function () {
        if(flog){
            x=x-0.05;
            if(x<=0){
                flog=false;
            }
        }else{
            x=x+0.05;
            if(x>=1){
                flog=true;
            }
        }
        return Cesium.Color.RED.withAlpha(x);
      },false);
      setTimeout(()=>{
        this.poinEntity[id].billboard.color = callbackProperty;
        this.poinEntity[id].ellipse.show = true;
        this.oldId = id;
      },1000)
    },

当点击事件获取到id时调用callbackProperty(id)即可,在这个函数中我们创建了一个callbackProperty 方法为修改属性颜色

# 封装(完整代码)

创建dragEntity.js文件


/**
 * @param {Viewer} viewer
 * 
*/
export default class DragEntity{
    constructor(val){
        this.viewer = val.viewer,
    }
    addEntity(value){
        let minR=value.minR;//最小半径
        let maxR = value.maxR;// 最大半径
        let deviationR = value.deviationR; // 每次增加的大小
        var r1 = minR
        function changeR1() {  
            r1=r1+deviationR;//deviationR为每次圆增加的大小
            if(r1>=maxR){
                r1=minR;
            }
            return r1;
        }
        function color() {
            let x=1-r1/maxR;
            return Cesium.Color.RED.withAlpha(x);
        }
        //数据格式{id:543595234324_432423,position:[122.8,39.9],text:"L"}
        let pinBuilder = new Cesium.PinBuilder();
        let poin = this.viewer.entities.add({
            id:value.id,
            name: value.name,
            position: Cesium.Cartesian3.fromDegrees(value.position.x, value.position.y),
            billboard: {
              image: pinBuilder.fromText(value.text,Cesium.Color.ROYALBLUE, 48).toDataURL(),
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            },
            ellipse: {
                semiMinorAxis: new Cesium.CallbackProperty(changeR1,false),
                semiMajorAxis: new Cesium.CallbackProperty(changeR1,false),
                material: new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(color,false)),
                outlineColor: Cesium.Color.RED,
                show: false
            },
            monitoItems:{
                data:value
            },
        });
        return poin
    }
    
}

在实例中调用

import DragEntity from './dragentity.js'
data(){
    return{
      poinEntity:{},
      oldId:null,//储存上次点位ID
      poin :  [{id:'12321321' , name: "北京西路测试点", type: "固定枪机", state: "在线", position: { x: 116.4568, y: 39.8926} ,text:'X'},
            {id:'43244324' , name: "阿乐修理厂门口", type: "固定枪机", state: "在线", position: {  x: 116.4568, y: 39.8944 } ,text:'+'},
            {id:'43764324', name: "裕华路加油站", type: "固定枪机", state: "在线", position: { x: 116.4566, y: 39.8923 } ,text:'?'},
            {id:'437543345', name: "康佳大药房", type: "固定枪机", state: "在线", position: { x: 116.4513, y: 39.8923 }  ,text:'!'},],
    }
  },
mounted(){
    this.dragEntity()
    this.leftDownAction()
},
methods:{
	// 左键点击事件
    leftDownAction(){
      	let viewer = this.$store.state.viewer
        this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        let _this = this
        let id
        _this.handler.setInputAction(function (movement) {
            let pick = viewer.scene.pick(movement.position); 
            if (Cesium.defined(pick) && (pick.id.id) ) {
                id= pick.id.id;
                 _this.callbackProperty(id)
            }else{
              _this.clearClick();
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        
    },
    // 清除效果
    clearClick(){
      let _this = this;
      if(_this.oldId){
        _this.poinEntity[_this.oldId].billboard.color = Cesium.Color.WHITE.withAlpha(1);
        _this.poinEntity[_this.oldId].ellipse.show = false;
      }
    },
    //添加效果展示
    callbackProperty(id){
      this.clearClick()
      let flog = true;
      let x = 1;
      let callbackProperty = new Cesium.CallbackProperty(function () {
        if(flog){
            x=x-0.05;
            if(x<=0){
                flog=false;
            }
        }else{
            x=x+0.05;
            if(x>=1){
                flog=true;
            }
        }
        return Cesium.Color.RED.withAlpha(x);
      },false);
      setTimeout(()=>{
        this.poinEntity[id].billboard.color = callbackProperty;
        this.poinEntity[id].ellipse.show = true;
        this.oldId = id;
      },1000)
    },
    //加载点和圆
    dragEntity(){
      let drag = new DragEntity({
        viewer:this.$store.state.viewer, 
      })
      let _this = this
      // this.poin = [{id:234,position:[122.8,39.9],text:"L"},{id:432,position:[122,39],text:"C"}]
      this.poin.forEach(item => {
        let entity = drag.addEntity(Object.assign(item,{minR:0, maxR:40, deviationR:1,}));
        _this.poinEntity[item.id] = entity;
      })
    },
}

想要完整demo可私信备注来意

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GIS-CL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值