前言
在上一章节中,我们已经绘制出实际的GIS地图,实际的需求中,我们可能需要在地图的某些位置添加一些标注,比如建筑、车辆,点击标注弹出详细的信息框。
本章节中,介绍如何在GIS地图中添加标注,并自定义气泡。
一、添加模型
GIS地图中,使用模型来设置标注。
为什么使用模型,而不是图片?GIS是一个3D的场景,使用模型更有立体感,使用图片的话,不能与3D的场景进行很好的结合,导致显示有瑕疵。
通过(https://www.aigei.com/),可下载免费的模型。
// 创建一个模型对象
const position = Cesium.Cartesian3.fromDegrees(108.919_093, 34.136_449, 0.07);
const heading = Cesium.Math.toRadians(0);
const pitch = 0;
const roll = 0;
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr,
);
const entity = viewer.value.entities.add({
name: 'sceneCar',
id: 'car',
position,
orientation,
model: {
uri: `${import.meta.env.VITE_BASE}/assets/model/bmw.glb`,
scale: 2,
maximumScale: 400,
},
});
参数中的
uri是模型的绝对地址,要保证打包部署后,也能通过该地址找到对应的模型,否则地图上无法展示对象的模型。
二、自定义气泡
Cesium中未提供相应的API来自定义气泡,所以我们只能自己进行开发。
- 创建气泡元素
// carPopStyle使用ts进行控制
<div class="ol-popup" :style="carPopStyle" v-if="showCarPop">
<CarPopup @close="handleCloseCarPopup" />
</div>
- 设置气泡样式
.ol-popup {
position: absolute;
width: 350px;
height: 390px;
background-color: white;
border: 1px solid #eee;
border-radius: 4px;
box-shadow: 0 1px 4px rgb(0 0 0 / 15%);
}
.ol-popup::after,
.ol-popup::before {
position: absolute;
top: 100%;
width: 0;
height: 0;
pointer-events: none;
content: ' ';
border: solid transparent;
}
.ol-popup::after {
left: 170px;
margin-left: -10px;
border-width: 10px;
border-top-color: white;
}
.ol-popup::before {
left: 170px;
margin-left: -11px;
border-width: 11px;
border-top-color: #ccc;
}
- 增加点击事件,弹出气泡
// 点击的标注对象
const trackPop = ref<any>(null);
const carPopStyle = ref({
top: '0px',
left: '0px',
});
const handler = new Cesium.ScreenSpaceEventHandler(viewer.value.canvas);
// 监听鼠标点击事件
handler.setInputAction((click: any) => {
// 使用pick函数获取点击位置的实际位置
const pick = viewer.value.scene.pick(click.position);
// 根据id来判断点击的标注
if (pick && pick.id._id === 'car') {
trackPop.value = pick.id.position._value;
// 将GIS地图的坐标,转化为屏幕上的点的坐标
const winpos = viewer.value.scene.cartesianToCanvasCoordinates(
pick.id.position._value,
);
// 计算气泡的坐标
carPopStyle.value = {
left: `${winpos.x - 170}px`,
top: `${winpos.y - 390 - 20}px`,
};
showCarPop.value = true;
} else {
trackPop.value = undefined;
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
- 监听GIS地图的渲染,并实时更新气泡的坐标
通过鼠标缩放、移动地图时,标注坐标对应的屏幕的坐标也会发生改变,所以需要同步更新气泡的屏幕坐标
// 监听地图的渲染
viewer.value.scene.postRender.addEventListener(() => {
if (trackPop.value && showCarPop.value) {
const winpos = viewer.value.scene.cartesianToCanvasCoordinates(
trackPop.value,
);
carPopStyle.value = {
left: `${winpos.x - 170}px`,
top: `${winpos.y - 390 - 20}px`,
};
}
});