最终完整代码请看下面的封装一栏
可以把当前效果,动态分成两部分,添加一个点,和添加一个圆,当点击时,动态改变点的颜色,动态改变圆的大小
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可私信备注来意