1.弹窗没法向加入点位一样加入到地图内部,entity没法实现
2.使用绝对定位,将地图组件通过定位加入到地图上,注意弹窗层级一定在地图上
3.通过判断点击位置是否是点位来获取entity信息,将信息显示在弹窗
4.将点击处点位的经纬度转为浏览器视图的x,y坐标,设置弹窗位置
5.监听地图的缩放和拖动,实时改变显示的弹窗的位置,使弹窗一直保持在点位上方
效果:
地图组件(.vue)
<template>
<div id="cesiumContainer" class="e-cesium">
<PopUp></PopUp>
</div>
</template>
<script lang="ts" setup>
import { onMounted } from 'vue';
import { mountedEvt } from './hooks';
import PopUp from './components/PopUp/index.vue';
onMounted(() => {
mountedEvt();
});
</script>
<style lang="scss" scoped>
.e {
&-cesium {
height: 100%;
width: 100%;
box-sizing: border-box;
}
}
</style>
hooks.ts文件
import * as Cesium from 'cesium';
import { popInfo } from './config';
let viewer;
export function mountedEvt() {
Cesium.Ion.defaultAccessToken =
'自己的token';
viewer = new Cesium.Viewer('cesiumContainer', {
baseLayerPicker: false, // 关闭图层选择
});
let data = viewer.dataSources.add(
Cesium.GeoJsonDataSource.load('/public/testData/pointLitter.json', {}), // 加载点
);
data.then((dataSource) => {
const entities = dataSource.entities.values;
for (const item in entities) {
const entity = entities[item];
entity.billboard = {
image: '/public/images/gg.png', // 点位图片
color: Cesium.Color.PINK,
width: 40,
height: 40,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 贴地
};
entity.label = {
text: entity.name, // 标签
font: '16px',
pixelOffset: new Cesium.Cartesian3(0, 30, 0),
};
}
});
viewer.zoomTo(data);
addPopEvt();
}
/**
* @Description 弹窗
* @Author: wms
* @Date: 2023-11-17 11:02:33
*/
export const addPopEvt = () => {
let popBox = new Cesium.InfoBox(document.getElementById('popBox'));
viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(
movement,
) {
let pickedObject = viewer.scene.pick(movement.position);
if (
Cesium.defined(pickedObject) &&
pickedObject.id instanceof Cesium.Entity
) {
var entity = pickedObject.id;
if (entity.position) {
// 显示弹窗
popBox.container.style.visibility = 'visible';
// 获取位置信息
let entityPosition = entity.position.getValue(
viewer.clock.currentTime,
);
popInfo.value = entity.properties;
// 监听 Viewer 的 postRender 事件,在地图移动时更新弹窗位置
viewer.scene.postRender.addEventListener(function () {
try {
if (entityPosition !== null) {
let screenPosition =
Cesium.SceneTransforms.wgs84ToWindowCoordinates(
viewer.scene,
entityPosition,
);
if (screenPosition) {
let leftOffset =
screenPosition.x -
popBox.container.clientWidth / 2; // 左右位置
let topOffset =
screenPosition.y -
popBox.container.clientHeight -
18; // 上下位置
popBox.container.style.left = leftOffset + 'px';
popBox.container.style.top = topOffset + 'px';
}
}
} catch (error) {
console.log(error);
}
});
} else {
popBox.container.style.visibility = 'hidden';
}
} else {
// 隐藏弹窗
popBox.container.style.visibility = 'hidden';
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
config.ts文件
import { Ref, ref } from 'vue';
export const popInfo: Ref<any> = ref({});
弹窗组件(components/PopUp/index.vue)
<template>
<div id="popBox" class="pop">
<div class="pop-box">
<div class="pop-box-title">{{ popInfo.title }}</div>
<div class="pop-box-line"></div>
<div class="pop-box-content">
<div class="pop-box-content-item">
<div class="pop-box-content-item-label">
<span class="pop-box-content-item-labelCont">
颜色:
</span>
{{ popInfo.color }}
</div>
<div class="pop-box-content-item-label">
<span class="pop-box-content-item-labelCont">
描述:
</span>
{{ popInfo.symbol }}
</div>
</div>
</div>
</div>
<div class="pop-box-triangle"></div>
</div>
</template>
<script lang="ts" setup>
import { popInfo } from '../../config';
import './index.scss';
</script>
<style lang="scss" scoped></style>
弹窗样式(components/PopUp/index.scss)
.pop {
position: absolute;
display: flex;
flex-direction: column;
width: 280px;
z-index: 99;
visibility: hidden;
&-box {
background-color: rgba(29, 54, 68, 0.8);
&-title {
font-size: 18px;
color: #fff;
padding: 12px;
text-align: center;
color: #fff;
}
&-line {
background-color: #0d1536a9;
height: 1px;
}
&-content {
color: #fff;
padding: 12px;
font-size: 14px;
&-item {
&-labelCont {
color: #fff;
}
}
}
&-triangle {
align-self: center;
width: 0;
height: 0;
border-top: 15px solid rgba(29, 54, 68, 0.8);
border-right: 12px solid transparent;
border-left: 12px solid transparent;
}
}
}
geojson数据(测试数据 pointLitter.json)
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
114,
30
]
},
"properties": {
"title": "99",
"color": "#B9EB14",
"symbol":"风格独特"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
114.001,
30
]
},
"properties": {
"title": "0",
"symbol": "海角天涯",
"color": "#D13C3C"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
114.002,
30
]
},
"properties": {
"title": "8",
"symbol": "特别的晚风",
"marker-size":12,
"color": "#C49D22"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
114.003,
30
]
},
"properties": {
"title": "2",
"symbol": "那年仲夏你背上行囊离开家古道旁我欲语泪先下庙里求签我哭诉青梅等竹马",
"color": "#8EE3A6"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
114.004,
30
]
},
"properties": {
"title": "3",
"symbol": "似水中月情迷着镜中花竹篱笆木琵琶拱桥月下谁在弹唱思念远方牵挂",
"color": "#34BE96"
}
}
]
}