根据项目要求:用户在点击切换下方卡片式的“时次”时候,下方左侧和右侧的地图可以进行联动,即用户点击、放大左侧时,右侧会有同等操作
具体的实现:
在components组件中添加index.vue文件,该组件作为子组件,里面是一些地图的初始化操作
使用props属性去接收父组件rainCheckContent.vue中的data和container值
写initViewer方法,并在页面加载时mounted要调用该方法
根据小哥提供的cesium双屏联动总结了下:
1.实现思路:
移动其中一个地图 监听到中心点,将中心点信息同步给其他地图
监听函数viewer.camera.changed.addEventListener(your callback)
2.解决卡顿:
(1)viewer.camera.changed.addEventListener参数不能填写匿名函数,要把回调函数定义出来,传进去 这个时候效果已经好到了百分之50了
(2)要添加这一句 viewer.scene.preRender.addEventListener(your callback);这时候效果已经达到百分之百了
补充:卡顿与否和vue是否监听了viewer无关 ,放心的把view存在data里面
在rainCheckContent.vue页面中的代码:
初始化变量
父子通信传值接收
项目又要求在地图叠加产品图,这里先做了一个静态的示例,在地图上贴了一个固定的图片
下面就是开始进行接口联调的工作了,将固定的数据都换成后台提供的真实数据,后台提供的数据大致长这样:
因此我设置了两个对象分别存放左边和右边图片的url和position,即yubaoImage,shikuangImage。开始联调接口,取得接口中的所有数据存放在res里面。
//实况预报图片查询
async queryPic() {
let itemTypeValue = ''
if (this.radioValueStep === '3小时') {
itemTypeValue = 'rain3'
}
if (this.radioValueStep === '24小时') {
itemTypeValue = 'rain24'
}
let params4 = {
time: this.timeValue.format('YYYY-MM-DD HH:mm:SS'),
itemType: itemTypeValue,
dataType: this.radioValueMode
}
await this.queryForecastPicDatas(params4).then(res => {
// console.log(this.queryForecastPic)
console.log(res)
this.queryMapDatas = res
})
},
用户通过点击事件changeRadio3Time,点击每个时次,拿到当前点击的时次下的forecastProductPath和forecastBound即可
changeRadio3Time(e, index) {
let currentTimesData = {}
this.yubaoImage = {
url: '',
position: []
}
this.shikuangImage = {
url: '',
position: []
}
for (let item in this.queryMapDatas) {
if ((index + 1) * 3 == item) {
console.log(this.queryMapDatas[item])
currentTimesData = this.queryMapDatas[item]
// console.log(currentTimesData.forecastBound) // 接口取到的坐标:70.0,180.0,0.0,60.0 实际要转换为:[70.0, 0.0, 180.0, 60.0],
let bounds = eval("(" + "[" + currentTimesData.forecastBound + "]" + ")")
let boundsActua = eval("(" + "[" + currentTimesData.ActualBound + "]" + ")")
// console.log(bounds[0].toFixed(1))
//存储当前时次预报场数据
this.yubaoImage = {
url: Ip + '/Data/' + currentTimesData.forecastProductPath,
// position: [70.0, 0.0, 180.0, 60.0],
position: [bounds[0], bounds[2], bounds[1], bounds[3]],
}
//存储当前时次实况场数据
this.shikuangImage = {
url: this.baseUrl + currentTimesData.ActualProductPath,
position: [boundsActua[0], boundsActua[2], boundsActua[1], boundsActua[3]],
}
}
}
},
index.vue完整代码如下:
<template>
<!-- <div id="cesiumContainer"></div> -->
<!-- <div id="cesiumContainerRight"></div> -->
<!-- 控制地图联动(子组件) -->
<div class="container" :id="containter"></div>
</template>
<script>
import { mapMutations } from 'vuex'
import HtMapViewer from '../../webMap/htMapViewer'
import ImageEntity from '../../webMap/entities/ImageEntity'
import { eventEnum } from '../../webMap/enum/event_enum'
//1.去除vue与cesium的双向绑定,解决卡顿
var viewer = null;
export default {
data() {
return {
event: null,
viewer: null,
}
},
props: ["containter", "data"],
mounted() {
this.initViewer()
},
// 深度监听data对象属性的变化
watch: {
data(newValue) {
console.log("data对象改变了", newValue);
// this.initViewer()
// 数据更新时候重新加载一次贴图
if (this.data) {
// debugger
let imageEntity = new ImageEntity('tt', this.data.url, this.data.position.map(e=>{
return Number(e)
}), true)
this.viewer.addEntity(imageEntity)
}
},
deep: true
},
methods: {
...mapMutations('mapStore', ['getLonAndLat', 'getView']),
initViewer() {
this.viewer = new HtMapViewer(
this.containter, [133.8047789764142, 40.40880264446077, 4434921.235756896],
//修改初始化地图坐标
// [121.53775, 31.48143, 2511531.462963185],
false,
false,
'tdt_w', {}
)
if (this.data) {
console.log(this.data)
let imageEntity = new ImageEntity('tt', this.data.url, this.data.position, true)
this.viewer.addEntity(imageEntity)
}
this.openChangedEvt()
this.viewer.scene.preRender.addEventListener(this.chageHandler); // 解决地图卡顿
},
//地图联动思路:移动其中一个地图,监听到中心点,将中心点信息同步给其他地图的监听函数
openChangedEvt() {
this.event = this.viewer.camera.changed.addEventListener(this.chageHandler) // 传回调函数解决地图卡顿
},
closeChangedEvt() {
if (!this.event) return
this.event();
this.event = null;
},
upDatePositionByOtherMap(position) {
this.event();
this.viewer.setView([position.lon, position.lat, position.height])
this.openChangedEvt()
},
// 回调函数
chageHandler() {
this.$emit('moveBrother', { position: this.viewer.getCenterPosition(), id: this.containter })
}
}
}
</script>
<style lang="scss" scoped>
.container {
width: 100%;
height: 100%;
position: absolute;
}
</style>