<template>
|
<div style="display: flex;justify-content: space-between;">
|
<!-- 选点按钮 -->
|
<div @click="togglePick" :class="['pick-button', { active: isPickingActive }]">
|
<img src="@/assets/img/timeline/坐标.png" style="width: 26px;height: 26px;" />
|
<!-- <span v-if="isPickingActive">停止拾取</span>
|
<span v-else>开始拾取</span> -->
|
</div>
|
<!-- 开始计算按钮 -->
|
<!-- <div @click="startCalculation">
|
<img src="@/assets/img/timeline/水位.png" style="margin-top: -4px;width: 34px;height: 34px;" />
|
</div> -->
|
<!-- 结束计算按钮 -->
|
<div @click="endCalculation">
|
<img src="@/assets/img/timeline/清除.png" style="width: 26px;height: 26px;" />
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { defineProps, watch, ref, onMounted, defineExpose } from "vue";
|
import { ElMessage } from 'element-plus';
|
|
const pickedPoints = ref([]);
|
const handler = ref(null);
|
const isPickingActive = ref(false);
|
const currentTime = ref(0);
|
|
const props = defineProps({
|
playingTime: {
|
type: String,
|
required: true
|
}
|
});
|
|
watch(
|
() => props.playingTime,
|
(newVal) => {
|
currentTime.value = newVal;
|
},
|
{ immediate: true }
|
);
|
// Cesium viewer 初始化相关逻辑
|
const viewer = window.viewer;
|
|
function getPickPosition(windowPosition) {
|
if (!viewer) return null;
|
viewer.scene.globe.depthTestAgainstTerrain = true;
|
const cartesian = viewer.scene.pickPosition(windowPosition);
|
if (!cartesian) return null;
|
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
cartographic.height += 200.0;
|
return {
|
cartesian: Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height),
|
longitude: Cesium.Math.toDegrees(cartographic.longitude),
|
latitude: Cesium.Math.toDegrees(cartographic.latitude),
|
height: cartographic.height
|
};
|
}
|
function addPointToViewer(point, index) {
|
const displayTime = currentTime.value || "未设置时间";
|
|
// 添加标签(确保实体创建时包含label属性)
|
const labelEntity = viewer.entities.add({
|
position: point.cartesian,
|
label: {
|
text: `测量点 ${index + 1}\n经度: ${point.longitude.toFixed(6)}\n纬度: ${point.latitude.toFixed(6)}\n时间: ${displayTime}`,
|
font: '14pt monospace',
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
fillColor: Cesium.Color.YELLOW,
|
outlineColor: Cesium.Color.BLACK,
|
outlineWidth: 2,
|
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
backgroundColor: Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'),
|
backgroundPadding: new Cesium.Cartesian2(10, 10),
|
showBackground: true,
|
scale: 1,
|
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
|
pixelOffsetScaleByDistance: new Cesium.NearFarScalar(100, 1.0, 5000, 0.3)
|
}
|
});
|
|
// 添加垂直线
|
const lineEntity = viewer.entities.add({
|
polyline: {
|
positions: [point.cartesian, Cesium.Cartesian3.fromRadians(point.longitude * Math.PI / 180, point.latitude * Math.PI / 180, 0)],
|
width: 2,
|
material: new Cesium.PolylineOutlineMaterialProperty({
|
color: Cesium.Color.RED.withAlpha(0.8),
|
outlineColor: Cesium.Color.WHITE,
|
outlineWidth: 4
|
}),
|
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
|
pixelOffsetScaleByDistance: new Cesium.NearFarScalar(100, 1.0, 5000, 0.3)
|
}
|
});
|
|
// 保存 labelEntity 和 lineEntity
|
pickedPoints.value.push({
|
labelEntity,
|
lineEntity,
|
longitude: point.longitude,
|
latitude: point.latitude
|
});
|
}
|
|
function initPickHandler() {
|
if (!viewer?.scene?.canvas) return;
|
|
if (handler.value) {
|
handler.value.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
handler.value.destroy();
|
handler.value = null;
|
}
|
|
handler.value = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
|
|
handler.value.setInputAction((movement) => {
|
const position = getPickPosition(movement.position);
|
if (position) {
|
const index = pickedPoints.value.length;
|
addPointToViewer(position, index);
|
}
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
}
|
|
function startPicking() {
|
// pickedPoints.value = [];
|
// viewer.entities.removeAll();
|
if (!handler.value) {
|
initPickHandler(); // 只有第一次才初始化
|
}
|
|
isPickingActive.value = true;
|
ElMessage.success('开始拾取坐标,请点击地图选择点位!');
|
}
|
|
function stopPicking() {
|
if (handler.value) {
|
handler.value.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
handler.value.destroy();
|
handler.value = null;
|
}
|
isPickingActive.value = false;
|
}
|
|
function togglePick() {
|
if (isPickingActive.value) {
|
stopPicking(); // 调用 stopPicking 来正确地停止选取过程
|
isPickingActive.value = false; // 确保 isPickingActive 设置为 false
|
ElMessage.success('当前坐标已选取完成!水位流速测量准备完毕!');
|
console.log(pickedPoints.value, '最终选取的点');
|
} else {
|
startPicking();
|
isPickingActive.value = true; // 在开始选取前设置为 true
|
}
|
}
|
// 当 currentTime 改变时更新所有点的 label 中的时间戳
|
// 修改watch逻辑
|
watch(
|
() => props.playingTime,
|
(newVal) => {
|
currentTime.value = newVal || "未设置时间";
|
updateAllLabels();
|
},
|
{ immediate: true }
|
);
|
|
function updateAllLabels() {
|
pickedPoints.value.forEach((pointInfo, index) => {
|
if (pointInfo.labelEntity && pointInfo.labelEntity.label) {
|
pointInfo.labelEntity.label.text =
|
`测量点 ${index + 1}\n经度: ${pointInfo.longitude.toFixed(6)}\n纬度: ${pointInfo.latitude.toFixed(6)}\n时间: ${currentTime.value}`;
|
}
|
});
|
}
|
|
function startCalculation() {
|
console.log('选取的坐标点:', pickedPoints.value);
|
console.log(`当前时间:${currentTime.value}`);
|
}
|
|
function endCalculation() {
|
// console.log('由本功能创建的所有 label 和 polyline entities:');
|
// pickedPoints.value.forEach((pointInfo, index) => {
|
// console.log(`测量点 ${index + 1}:`);
|
// console.log('Label Entity:', pointInfo.labelEntity);
|
// console.log('Polyline Entity:', pointInfo.lineEntity);
|
// });
|
// console.log('当前 Cesium 中所有实体列表:');
|
// viewer.entities.values.forEach((entity, idx) => {
|
// console.log(`实体 #${idx}:`, entity);
|
// });
|
pickedPoints.value.forEach(pointInfo => {
|
if (pointInfo.labelEntity) viewer.entities.remove(pointInfo.labelEntity);
|
if (pointInfo.lineEntity) viewer.entities.remove(pointInfo.lineEntity);
|
});
|
pickedPoints.value = [];
|
}
|
defineExpose({
|
endCalculation
|
});
|
|
</script>
|
|
<style lang="less" scoped></style>
|