Cesium点位弹窗

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"
            }
        }
        
    ]
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小满blue

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值