1
wangjuncheng
2025-06-06 7217e02e098b94e421b5a85ec13e0cd2ed35fbeb
src/components/menu/CrossSectionalAnalysis.vue
@@ -1,16 +1,74 @@
<template>
   <div style="display: flex; justify-content: space-between;">
      <div @click="initPickHandler">
         <img v-if="!isPicking" src="@/assets/img/timeline/断面.png" style="width: 26px;height: 26px;" />
         <img v-else src="@/assets/img/timeline/已断面.png" style="width: 26px;height: 26px;" />
      </div>
      <div @click="confirmPoints">
         <img v-if="!isUploaded" src="@/assets/img/timeline/上传.png" style="width: 26px;height: 26px;" />
         <img v-else src="@/assets/img/timeline/已上传.png" style="width: 26px;height: 26px;" />
      </div>
      <div @click="clearPoints">
         <img src="@/assets/img/timeline/清除.png" style="width: 26px;height: 26px;" />
      </div>
      <!-- 第一个按钮:选取断面点 -->
      <el-tooltip placement="top" show-after="1000">
         <template #content>
            断面分析功能说明:
            <br /><br />
            🔹 点击按钮切换状态:
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;- 白色:关闭拾取功能(不可选点)
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;- 黄色:开启拾取功能(可点击地图选择2个断面点)
            <br /><br />
            🔹 使用流程:
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;1. 点击按钮切换为黄色 ➜ 开始拾取坐标点
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;2. 在地图上点击选择 2 个断面点(如需修改,可重新点击)
            <br /><br />
            ⚠️ 温馨提示:
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;每次只能分析一条沟渠的断面,多个断面可能导致计算异常;
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;使用完毕请将按钮切回白色,避免影响其他功能。
         </template>
         <div @click="initPickHandler" :class="{ active: isPicking }">
            <img v-if="!isPicking" src="@/assets/img/timeline/断面.png" style="width: 26px;height: 26px;" />
            <img v-else src="@/assets/img/timeline/已断面.png" style="width: 26px;height: 26px;" />
         </div>
      </el-tooltip>
      <!-- 第二个按钮:上传并分析断面 -->
      <el-tooltip placement="top" show-after="1000">
         <template #content>
            上传并分析断面数据:
            <br /><br />
            📌 条件限制:
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;仅当成功选择 2 个断面点后才可点击
            <br /><br />
            🔁 功能说明:
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;点击后将对当前断面进行分析,稍等片刻即可在图表区域查看结果
            <br /><br />
            ⚠️ 注意事项:
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;该功能仅支持单条沟渠分析,多个断面可能导致计算不稳定或出错
         </template>
         <div @click="confirmPoints" :class="{ disabled: !isReadyForUpload }">
            <img v-if="!isUploaded" src="@/assets/img/timeline/上传.png" style="width: 26px;height: 26px;" />
            <img v-else src="@/assets/img/timeline/已上传.png" style="width: 26px;height: 26px;" />
         </div>
      </el-tooltip>
      <!-- 第三个按钮:清除所有点和分析结果 -->
      <el-tooltip placement="top" show-after="1000">
         <template #content>
            清除所有断面点及分析结果:
            <br /><br />
            🔁 功能说明:
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;点击后将移除地图上的所有断面点以及相关分析图表
            <br /><br />
            ⚠️ 温馨提示:
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;此操作会清空当前分析进度,请确认后再执行
         </template>
         <div @click="clearPoints">
            <img src="@/assets/img/timeline/清除.png" style="width: 26px;height: 26px;" />
         </div>
      </el-tooltip>
   </div>
</template>
@@ -72,7 +130,9 @@
         color: Cesium.Color.RED,
         outlineColor: Cesium.Color.YELLOW,
         outlineWidth: 2,
         pixelSize: 8 // 圆点半径大小
         pixelSize: 8,// 圆点半径大小
         distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
      }
   });
   pickedEntitiesIds.value.push(entity.id); // 记录实体ID
@@ -85,6 +145,8 @@
         positions: [startPoint.cartesian, endPoint.cartesian],
         material: Cesium.Color.YELLOW,
         heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
         distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
      }
   });
   pickedEntitiesIds.value.push(entity.id); // 记录实体ID
@@ -94,59 +156,59 @@
// 新增:绘制模拟点(圆柱 + label)
function drawSimulationPoint(start, end) {
// 计算中点(经纬度平均值)
const midLon = (start.longitude + end.longitude) / 2;
const midLat = (start.latitude + end.latitude) / 2;
const terrainHeight = viewer.scene.globe.getHeight(
   Cesium.Cartographic.fromDegrees(midLon, midLat)
);
   // 计算中点(经纬度平均值)
   const midLon = (start.longitude + end.longitude) / 2;
   const midLat = (start.latitude + end.latitude) / 2;
   const terrainHeight = viewer.scene.globe.getHeight(
      Cesium.Cartographic.fromDegrees(midLon, midLat)
   );
const cylinderBottomHeight = 0;
const cylinderTopHeight = terrainHeight + 190;
const cartesianBottom = viewer.scene.globe.ellipsoid.cartographicToCartesian(
   Cesium.Cartographic.fromDegrees(midLon, midLat, cylinderBottomHeight)
);
const CrosscylinderEntity = viewer.entities.add({
   position: cartesianBottom,
   cylinder: {
      length: 190.0,
      topRadius: 1.0,
      bottomRadius: 1.0,
      material: Cesium.Color.YELLOW,
      outline: true,
      outlineColor: Cesium.Color.YELLOW,
      slices: 64,
      heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000)
   }
});
const labelHeight = cylinderTopHeight + 10;
const cartesianLabel = viewer.scene.globe.ellipsoid.cartographicToCartesian(
   Cesium.Cartographic.fromDegrees(midLon, midLat, labelHeight)
);
   const cylinderBottomHeight = 0;
   const cylinderTopHeight = terrainHeight + 100;
   const cartesianBottom = viewer.scene.globe.ellipsoid.cartographicToCartesian(
      Cesium.Cartographic.fromDegrees(midLon, midLat, cylinderBottomHeight)
   );
   const CrosscylinderEntity = viewer.entities.add({
      position: cartesianBottom,
      cylinder: {
         length: 100.0,
         topRadius: 1.0,
         bottomRadius: 1.0,
         material: Cesium.Color.YELLOW,
         outline: true,
         outlineColor: Cesium.Color.YELLOW,
         slices: 64,
         heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
         distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000)
      }
   });
   const labelHeight = cylinderTopHeight + 10;
   const cartesianLabel = viewer.scene.globe.ellipsoid.cartographicToCartesian(
      Cesium.Cartographic.fromDegrees(midLon, midLat, labelHeight)
   );
const CrosslabelEntity = viewer.entities.add({
   position: cartesianLabel,
   label: {
      text: '断面截面模拟点',
      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),
      heightReference: Cesium.HeightReference.NONE // 使用绝对高度
   }
});
pickedEntitiesIds.value.push(CrosscylinderEntity.id);
pickedEntitiesIds.value.push(CrosslabelEntity.id);
   const CrosslabelEntity = viewer.entities.add({
      position: cartesianLabel,
      label: {
         text: '断面截面模拟点',
         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),
         heightReference: Cesium.HeightReference.NONE // 使用绝对高度
      }
   });
   pickedEntitiesIds.value.push(CrosscylinderEntity.id);
   pickedEntitiesIds.value.push(CrosslabelEntity.id);
}
function clearPoints() {
   for (const id of pickedEntitiesIds.value) {
@@ -165,6 +227,7 @@
      }
      isPicking.value = false;
      // isUploaded.value = false;
      ElMessage.info('已关闭--断面截面--拾取点坐标功能!');
      return;
   }
@@ -207,7 +270,7 @@
      cartesian: point2.cartesian
   });
   isUploaded.value = true;
   isUploaded.value = true;
   ElMessage.success('正在进行--断面截面--数据分析上传,请稍等...');
}