Cesium 介绍之 点位弹框实现(可随地图移动)
点位弹框
openlayer中对点位弹框进行了封装,可以用 ol.Overlay 组件来实现,实现相对方便。但在Cesium中不存在该类,需要手动实现该功能。
export default{
mounted(){
this.addRenderListener(viewer);
},
methods:{
// 重新开启点位弹框视图
startShowDialog() {
// 点位弹框是否可视
if (this.visible) {
// cartesian 笛卡尔坐标——用于地图移动时重新计算点位弹框所在屏幕位置,打开下一次弹框时需要记录上一次的屏幕坐标位置
const { x, y } = SceneTransforms.wgs84ToWindowCoordinates(window.cesiumViewer.scene, this.cartesian);
if (x && y) {
// 重新设置点位弹框的位置
} else {
// 关闭弹框
}
}
},
// preRender——在场景更新后以及渲染场景之前触发
addRenderListener(viewer) {
viewer.scene.preRender.addEventListener(this.startShowDialog);
},
// 根据gps信息获取屏幕坐标 —— 用于点位弹框
getScreenCoordinate(gpsX, gpsY, curPosition) {
const pick = curPosition ? window.cesiumViewer.scene.pick(curPosition) : null;
if (pick && pick.id) {
// 根据cartographic获取实时高度
const cartographic = Cartographic.fromCartesian(pick.primitive._actualPosition);
const cartesian = Cartesian3.fromDegrees(gpsX, gpsY, cartographic.height);
const position = SceneTransforms.wgs84ToWindowCoordinates(window.cesiumViewer.scene, cartesian);
return { cartesian, position };
} else {
const cartesian = getPositionByGps(gpsX, gpsY);
const position = SceneTransforms.wgs84ToWindowCoordinates(window.cesiumViewer.scene, cartesian);
return { cartesian, position };
}
}
}
}
编写点位弹框组件(popup.vue)、需要对外部
cesium-popup设置定位position:fixed
// 点位弹框外框架对弹框内容进行插槽
<template>
<div
ref="cesiumPopup"
class="cesium-popup"
:style="{
width: popupWidth + 'px',
left: position.x + 'px',
top: position.y + 'px'
}"
>
<slot />
</div>
</template>
export default{
watch:{
// 监听屏幕坐标变化,改变点位弹框位置
coordinate(v) {
this.handlePosition(v);
}
},
methods:{
async handlePosition(coordinate) {
await this.$nextTick();
const { offsetWidth, offsetHeight } = this.$refs.cesiumPopup;
const diffW = offsetWidth - this.tempWidth;
const diffH = offsetHeight - this.tempHeight;
if (Math.abs(diffH) > 1 || Math.abs(diffW) > 1) {
this.tempWidth = offsetWidth;
this.tempHeight = offsetHeight;
}
if (Array.isArray(coordinate) && coordinate.length) {
const [gpsX, gpsY] = coordinate;
this.position = {
x: gpsX - this.tempWidth / 2 + this.pOffset[0],
y: gpsY - this.tempHeight + this.pOffset[1]
};
}
}
}
}