wangjuncheng
2025-05-28 4a0b0a87f183abae6aff6174436be2ccbc507be2
src/components/menu/flowRate_waterLevel.vue
@@ -2,15 +2,9 @@
   <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> -->
         <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>
      <!-- 开始计算按钮 -->
      <!-- <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>
@@ -20,11 +14,17 @@
<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: {
@@ -33,14 +33,6 @@
   }
});
watch(
   () => props.playingTime,
   (newVal) => {
      currentTime.value = newVal;
   },
   { immediate: true }
);
// Cesium viewer 初始化相关逻辑
const viewer = window.viewer;
function getPickPosition(windowPosition) {
@@ -59,13 +51,15 @@
}
function addPointToViewer(point, index) {
   const displayTime = currentTime.value || "未设置时间";
   const schemeInfo = selectedScheme.value;
   serviceInfo = schemeInfo.serviceName;
   // 添加标签(确保实体创建时包含label属性)
   // 创建 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',
         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,
@@ -77,29 +71,38 @@
         showBackground: true,
         scale: 1,
         distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
         pixelOffsetScaleByDistance: new Cesium.NearFarScalar(100, 1.0, 5000, 0.3)
         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: 190.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)
      }
   });
   // 添加垂直线
   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)
      }
   // 请求数据并更新 label
   getFlowRateInfo(point.longitude, point.latitude, displayTime).then(result => {
      updateLabel(pickedPoints.value.length - 1, result.depth, result.velocity);
   });
   // 保存 labelEntity 和 lineEntity
   // 存储实体引用
   pickedPoints.value.push({
      labelEntity,
      lineEntity,
      cylinderEntity, // 使用圆柱代替 line 和 circle
      longitude: point.longitude,
      latitude: point.latitude
   });
@@ -107,13 +110,11 @@
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) => {
@@ -121,21 +122,20 @@
      if (position) {
         const index = pickedPoints.value.length;
         addPointToViewer(position, index);
         console.log('执行加点工作');
      }
   }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
function startPicking() {
   // pickedPoints.value = [];
   // viewer.entities.removeAll();
   if (!handler.value) {
      initPickHandler(); // 只有第一次才初始化
      initPickHandler();
   }
   isPickingActive.value = true;
   ElMessage.success('开始拾取坐标,请点击地图选择点位!');
   ElMessage.success(`开始--流量流速--拾取坐标功能,请点击地图选择点位!选取完请及时关闭,避免影响其他功能!`);
}
function stopPicking() {
   if (handler.value) {
      handler.value.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
@@ -147,61 +147,76 @@
function togglePick() {
   if (isPickingActive.value) {
      stopPicking(); // 调用 stopPicking 来正确地停止选取过程
      isPickingActive.value = false; // 确保 isPickingActive 设置为 false
      ElMessage.success('当前坐标已选取完成!水位流速测量准备完毕!');
      stopPicking();
      isPickingActive.value = false;
      ElMessage.info('已关闭--流量流速--拾取点坐标功能!');
      console.log(pickedPoints.value, '最终选取的点');
   } else {
      startPicking();
      isPickingActive.value = true; // 在开始选取前设置为 true
      isPickingActive.value = true;
   }
}
// 当 currentTime 改变时更新所有点的 label 中的时间戳
// 修改watch逻辑
watch(
   () => props.playingTime,
   (newVal) => {
      currentTime.value = newVal || "未设置时间";
      updateAllLabels();
   async (newVal, oldVal) => {
      if (newVal !== oldVal) {
         currentTime.value = newVal || "未设置时间";
         await 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}`;
      }
   });
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 startCalculation() {
   console.log('选取的坐标点:', pickedPoints.value);
   console.log(`当前时间:${currentTime.value}`);
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() {
   // 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);
      if (pointInfo.cylinderEntity) viewer.entities.remove(pointInfo.cylinderEntity);
   });
   pickedPoints.value = [];
}
defineExpose({
   endCalculation
   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>