<template>
|
<div style="display: flex;justify-content: space-between;">
|
<el-tooltip class="box-item" effect="dark" placement="top" show-after="1000">
|
<template #content>
|
水深/流速分析功能说明:
|
<br /><br />
|
🔹 点击按钮切换状态:
|
<br />
|
- 白色:关闭拾取功能(不可选点)
|
<br />
|
- 黄色:开启拾取功能(可点击地图选择分析点)
|
<br /><br />
|
🔹 使用流程:
|
<br />
|
1. 点击按钮切换为黄色状态 ➜ 开始拾取坐标点
|
<br />
|
2. 在地图上点击所需位置 ➜ 添加水深/流速分析点
|
<br />
|
3. 完成选点后,请将按钮切回白色 ➜ 关闭拾取功能
|
<br /><br />
|
⚠️ 温馨提示:
|
<br />
|
使用完毕请务必关闭拾取功能,避免误操作影响其他功能。
|
</template>
|
<div @click="togglePick" :class="['pick-button', { active: isPickingActive }]">
|
<img v-if="!isPickingActive" src="@/assets/img/timeline/流速.png" style="width: 28px;height: 28px;" />
|
<img v-else src="@/assets/img/timeline/已流速.png" style="width: 28px;height: 28px;" />
|
</div>
|
</el-tooltip>
|
<el-tooltip class="box-item" effect="dark" placement="top" show-after="1000">
|
<template #content>
|
清除所有分析坐标点及分析结果:
|
<br /><br />
|
🔁 功能说明:
|
<br />
|
点击后将移除地图上的所有水深/流速分析点以及相关分析图表
|
<br /><br />
|
⚠️ 温馨提示:
|
<br />
|
此操作会清空当前分析进度,请确认后再执行
|
</template>
|
<div @click="endCalculation">
|
<img src="@/assets/img/timeline/清除.png" style="width: 26px;height: 26px;" />
|
</div>
|
</el-tooltip>
|
</div>
|
</template>
|
|
<script setup>
|
import { defineProps, watch, ref, onMounted, defineExpose } from "vue";
|
import { ElMessage } from 'element-plus';
|
import { getFlowRate } from "@/api/trApi.js";
|
import { useSimStore } from "@/store/simulation";
|
import { storeToRefs } from "pinia";
|
const simStore = useSimStore();
|
const { selectedScheme } = storeToRefs(simStore);
|
|
const pickedPoints = ref([]);
|
const handler = ref(null);
|
const isPickingActive = ref(false);
|
const currentTime = ref(0);
|
let serviceInfo = ref(null);
|
|
const props = defineProps({
|
playingTime: {
|
type: String,
|
required: true
|
}
|
});
|
|
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 += 110.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 || "未设置时间";
|
const schemeInfo = selectedScheme.value;
|
serviceInfo = schemeInfo.serviceName;
|
|
// 创建 label 实体
|
const labelEntity = viewer.entities.add({
|
position: point.cartesian,
|
label: {
|
text: `测量点 ${pickedPoints.value.length + 1}\n水深: 等待启动...\n流速: 等待启动...`,
|
font: 'bold 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 groundPosition = Cesium.Cartesian3.fromRadians(
|
point.longitude * Math.PI / 180,
|
point.latitude * Math.PI / 180,
|
0
|
);
|
const cylinderEntity = viewer.entities.add({
|
position: groundPosition, // 底部位置
|
cylinder: {
|
length: 100.0,
|
topRadius: 1.0,
|
bottomRadius: 1.0,
|
material: Cesium.Color.YELLOW,
|
outline: true,
|
outlineColor: Cesium.Color.YELLOW,
|
slices: 32,
|
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
|
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000)
|
}
|
});
|
|
// 请求数据并更新 label
|
getFlowRateInfo(point.longitude, point.latitude, displayTime).then(result => {
|
updateLabel(pickedPoints.value.length - 1, result.depth, result.velocity);
|
});
|
|
// 存储实体引用
|
pickedPoints.value.push({
|
labelEntity,
|
cylinderEntity, // 使用圆柱代替 line 和 circle
|
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() {
|
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();
|
isPickingActive.value = false;
|
ElMessage.info('已关闭--流量流速--拾取点坐标功能!');
|
} else {
|
startPicking();
|
isPickingActive.value = true;
|
}
|
}
|
watch(
|
() => props.playingTime,
|
async (newVal, oldVal) => {
|
if (newVal !== oldVal) {
|
currentTime.value = newVal || "未设置时间";
|
await updateAllLabels();
|
}
|
},
|
{ immediate: true }
|
);
|
|
async function updateAllLabels() {
|
for (const pointInfo of pickedPoints.value) {
|
if (!pointInfo || !pointInfo.labelEntity) continue;
|
|
const result = await getFlowRateInfo(pointInfo.longitude, pointInfo.latitude, currentTime.value);
|
updateLabel(pointInfo, result.depth, result.velocity);
|
}
|
}
|
|
function updateLabel(pointInfo, depth, velocity) {
|
if (pointInfo.labelEntity && pointInfo.labelEntity.label) {
|
pointInfo.labelEntity.label.text = `
|
测量点 ${pickedPoints.value.findIndex(p => p === pointInfo) + 1}
|
水深: ${depth} m
|
流速: ${velocity} m/s
|
`.trim();
|
}
|
}
|
function endCalculation() {
|
pickedPoints.value.forEach(pointInfo => {
|
if (pointInfo.labelEntity) viewer.entities.remove(pointInfo.labelEntity);
|
if (pointInfo.cylinderEntity) viewer.entities.remove(pointInfo.cylinderEntity);
|
});
|
pickedPoints.value = [];
|
}
|
|
defineExpose({
|
endCalculation,
|
stopPicking
|
});
|
function getFlowRateInfo(lon, lat, time) {
|
const params = {
|
lon: lon,
|
lat: lat,
|
time: time,
|
serviceName: serviceInfo
|
};
|
return getFlowRate(params).then(data => {
|
// console.log('获取到的数据:', data);
|
if (data && data.code === 200) {
|
return {
|
depth: data.data.depth.toFixed(2),
|
velocity: data.data.velocity.toFixed(2)
|
};
|
} else {
|
return { depth: 'N/A', velocity: 'N/A' };
|
}
|
}).catch(error => {
|
console.error('获取数据时发生错误:', error);
|
return { depth: 'N/A', velocity: 'N/A' };
|
});
|
}
|
</script>
|
<style lang="less" scoped></style>
|