wangjuncheng
2025-04-21 51af02271fe8a6d3e2db7bef90df1ea5f571a173
src/views/mnfz.vue
@@ -1,23 +1,14 @@
<template>
  <Left @start="startSimulate" @end="endSimulate" />
  <echartInfo :isDynamicMode="isDynamicMode" :isFinish="isFinish" />
  <TimeLine
    v-if="showWaterSimulate"
    @time-update="timeUpdate"
    @is-playing="isPlaying"
    :waterSimulateParams="waterSimulateParams"
    @playbackFinished="playbackFinished"
    @end="endSimulate"
  />
  <DebuffDetail
    v-if="showDebuffDetail"
    @open="openDetail"
    @close="showDebuffDetail = false"
  />
  <echartInfo :isDynamicMode="isDynamicMode" :isFinish="isFinish" v-if="loadingSim" />
  <TimeLine v-if="showWaterSimulate" @time-update="timeUpdate" @is-playing="isPlaying"
    :waterSimulateParams="waterSimulateParams" @playbackFinished="playbackFinished" @end="endSimulate" />
  <DebuffDetail v-if="showDebuffDetail" @open="openDetail" @close="showDebuffDetail = false" />
  <DebuffTable v-if="showDebuffTable" @close="closeDebuffTable" />
</template>
<script setup>
import { EventBus } from "@/eventBus"; // 引入事件总线
import { ref, onMounted, onUnmounted, provide } from "vue";
import TimeLine from "@/components/menu/TimeLine.vue";
import Left from "./left/Left.vue";
@@ -26,6 +17,7 @@
import DebuffTable from "@/components/tools/DebuffTable.vue";
import { getMaxInfluenceArea } from "@/api/index";
import { createPoint, geomToGeoJSON } from "@/utils/map.js";
import { loadAreaPolygon, clearAreaPolygon } from "@/utils/area";
import colors from "@/assets/img/left/colors3.png";
import danger from "@/assets/img/left/danger.png";
@@ -36,6 +28,9 @@
const showDebuffTable = ref(false);
const isDynamicMode = ref(false);
const isFinish = ref(true);
const loadingSim = ref(false);
const treeMap = new Map();
// 提供方法给所有子组件
provide("simulateActions", {
@@ -46,63 +41,138 @@
function startSimulate(form) {
  // console.log("form", form);
  showWaterSimulate.value = true;
  loadingSim.value = true
  waterSimulateParams.value = form;
}
function endSimulate() {
  loadingSim.value = false
  showDebuffDetail.value = false
  clearTrailLine();
  removeEmergencyPoints()
  removeDataSources();
  setTimeout(() => {
    showWaterSimulate.value = false;
    isDynamicMode.value = false;
  }, 2000);
    // 清除威胁对象表格内容
    EventBus.emit("reset-table");
    // 清除降雨数据内容
    EventBus.emit("clear-echart");
  }, 1000);
}
const MaxInfluenceAreaList = ref([]);
// 初始化 dataSources 全局数组
const dataSources = [];
function getTimeMarkers() {
  // 将 list 数据的 geom EPSG:4326 坐标转换为 WGS84 坐标系的 GeoJSON 数据
async function getTimeMarkers() {
  const list = MaxInfluenceAreaList.value;
  list.forEach((item, index) => {
    const geojson = JSON.parse(item.geom); // 解析 geom 字段为 GeoJSON 对象
    Cesium.GeoJsonDataSource.load(geojson).then((dataSource) => {
      // 设置样式,将颜色改为红色
  try {
    const loadPromises = list.map(async (item) => {
      const geojson = JSON.parse(item.geom);
      const dataSource = await Cesium.GeoJsonDataSource.load(geojson);
      dataSource.entities.values.forEach((entity) => {
        // entity.polygon.material = new Cesium.Color(1.0, 0.0, 0.0, 0.6); // 红色,80% 不透明度
        // entity.polygon.material = new Cesium.Color.YELLOW; // 红色,80% 不透明度
        if (!entity.properties) {
          entity.properties = new Cesium.PropertyBag();
        }
        entity.properties.addProperty("id", item.id);
        entity.properties.addProperty("warningLevel", item.warningLevel);
        entity.properties.addProperty("zoneId", item.zoneId);
        entity.polygon.outlineColor = Cesium.Color.YELLOW;
        entity.polygon.outline = true;
        // 使用提供的 X, Y, Z 坐标作为图标位置
        const position = Cesium.Cartesian3.fromDegrees(item.X, item.Y, item.Z);
        // 在中心点上方添加一个图标实体
        const billboardEntity = viewer.entities.add({
          position: position,
          billboard: {
            image: danger, // 图标的路径
            scale: 1.0, // 图标缩放比例
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 图标底部对齐到中心点
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 图标贴地
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500), // 控制可见距离范围 (0米到1500米)
            image: danger,
            scale: 1.0,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500),
          },
        });
        // 将图标实体与当前数据源关联
        dataSource.entities.add(billboardEntity);
      });
      // 添加数据源到 viewer
      viewer.dataSources.add(dataSource);
      dataSources.push(dataSource);
    });
  });
    await Promise.all(loadPromises);
    setupRowClickListener(dataSources);
  } catch (error) {
  }
}
// 清除隐患点
function removeDataSources() {
  dataSources.forEach((dataSource) => {
  dataSources.forEach((dataSource, index) => {
    // 遍历当前数据源的所有实体
    const entities = dataSource.entities.values;
    entities.forEach((entity, entityIndex) => {
      if (entity.billboard) {
        viewer.entities.remove(entity);
      }
    });
    viewer.dataSources.remove(dataSource);
  });
  dataSources.length = 0;
}
// 避险点,绿色富文本
function addTetrahedron(visible) {
  const emergencyAreaList = [];
  //  这里是添加避险点底层面片
  loadAreaPolygon("/json/emergency_area.geojson", true).then((entities) => {
    emergencyAreaList.push(...entities);
  });
  // console.log('polygon', polygon);
  let list = [
    {
      name: "尹建华家",
      longitude: 116.593517,
      latitude: 40.568391,
      altitude: 528.45,
    },
    // {
    //   name: "范振江家",
    //   longitude: 116.591059,
    //   latitude: 40.574068,
    //   altitude: 528,
    // },
    // {
    //   name: "后坡",
    //   longitude: 116.597975,
    //   latitude: 40.558199,
    //   altitude: 528,
    // },
  ];
  // 这里是添加避险点富文本高亮显示
  list.forEach((item) => {
    let point = earthCtrl.factory.createRichTextPoint("避险点", [item.longitude, item.latitude, item.altitude - 10], {
      distanceDisplayCondition: new SmartEarth.Cesium.DistanceDisplayCondition(0, 2000),
      fontColor: "#ffffff",
      fontSize: 20
    }, "0");
    console.log("point", point);
    emergencyAreaList.push(point);
  });
  treeMap.set("避险点", emergencyAreaList);
}
// 删除避险点的富文本实体
function removeEmergencyPoints() {
  const emergencyAreaList = treeMap.get("避险点"); // 获取存储的避险点实体列表
  if (emergencyAreaList && emergencyAreaList.length > 0) {
    emergencyAreaList.forEach((entity) => {
      if (entity && typeof entity.deleteObject === 'function') {
        // 如果有 deleteObject 方法,优先调用
        entity.deleteObject();
      } else if (entity && typeof entity.clear === 'function') {
        // 如果有 clear 方法,调用 clear
        entity.clear();
      } else if (entity && earthCtrl && earthCtrl.coreMap) {
        // 如果是 Cesium 实体,使用 coreMap.entities.remove 移除
        earthCtrl.coreMap.entities.remove(entity);
      }
    });
    treeMap.set("避险点", []); // 清空存储的避险点列表
  }
}
let TrailLine = [];
async function showLine() {
  const position = [
@@ -190,67 +260,6 @@
  });
  TrailLine = [];
}
// function showLine() {
//   earthCtrl.factory.createSimpleGraphic(
//     "polyline",
//     { clampToGround: true },
//     (entity) => {
//       if (entity) {
//         const position = [
//           {
//             x: -2172540.8322597803,
//             y: 4339064.62665997,
//             z: 4126183.3895281963,
//           },
//           {
//             x: -2172480.18394144,
//             y: 4339033.15167176,
//             z: 4126240.9529584926,
//           },
//           {
//             x: -2172454.114348403,
//             y: 4339020.0398392705,
//             z: 4126261.946960697,
//           },
//           {
//             x: -2172377.9670952093,
//             y: 4338976.609385458,
//             z: 4126333.862357211,
//           },
//           {
//             x: -2172299.4142002705,
//             y: 4338951.971578909,
//             z: 4126397.5205803993,
//           },
//           {
//             x: -2172245.1703274297,
//             y: 4338940.86037857,
//             z: 4126436.276389208,
//           },
//           {
//             x: -2172176.7332184147,
//             y: 4338930.525741544,
//             z: 4126477.629952572,
//           },
//           {
//             x: -2172173.8151051304,
//             y: 4338939.043883864,
//             z: 4126469.336927342,
//           },
//           {
//             x: -2172173.7151194704,
//             y: 4338939.023235937,
//             z: 4126469.4107743693,
//           },
//         ];
//         // console.log("positions", positions);
//         addWall(position, [entity]);
//         earthCtrl.factory.SimpleGraphic.remove(entity.id);
//       }
//     }
//   );
// }
function timeUpdate(percentage) {
  if (percentage > 99) {
    if (showDebuffDetail.value) {
@@ -259,6 +268,7 @@
    checkedKeys.value = ["避险点"];
    showDebuffDetail.value = true;
    getTimeMarkers();
    addTetrahedron();
    showLine();
  }
}
@@ -282,7 +292,77 @@
function playbackFinished(val) {
  isFinish.value = val;
}
// 定义全局变量存储当前正在闪动的面片
let flashingPolygon = null;
// 添加事件监听器,接收来自表格组件的事件
function setupRowClickListener(dataSources) {
  if (!Array.isArray(dataSources) || dataSources.length === 0) {
    console.error("Data sources array is undefined or empty!");
    return;
  }
  EventBus.on("row-clicked", (id) => {
    const clickedEntity = findEntityById(id, dataSources);
    if (clickedEntity) {
      if (flashingPolygon && flashingPolygon !== clickedEntity) {
        stopFlashing(flashingPolygon);
      }
      startFlashing(clickedEntity);
      flashingPolygon = clickedEntity;
    } else {
    }
  });
}
function findEntityById(id, dataSources) {
  if (!Array.isArray(dataSources) || dataSources.length === 0) {
    console.error("Data sources array is undefined or empty!");
    return null;
  }
  console.log("Searching for ID:", id);
  for (const dataSource of dataSources) {
    const entities = dataSource.entities.values;
    for (const entity of entities) {
      const entityId = entity.properties?.id?.getValue();
      if (String(entityId) === String(id)) {
        return entity;
      }
    }
  }
  return null;
}
// 开始闪动效果
function startFlashing(polygonEntity) {
  // 存储原始颜色
  const originalColor = polygonEntity.polygon.material.color.getValue();
  polygonEntity._originalColor = originalColor; // 将原始颜色保存到实体中
  // 创建颜色变化的回调函数
  let isFlashing = true; // 标记是否正在闪动
  polygonEntity.polygon.material = new Cesium.ColorMaterialProperty(
    new Cesium.CallbackProperty(() => {
      if (!isFlashing) return originalColor; // 如果停止闪动,恢复原始颜色
      // 切换颜色(例如红色和原始颜色交替)
      const currentTime = Date.now();
      const flashColor = Cesium.Color.RED.withAlpha(1); // 闪动颜色
      return Math.floor(currentTime / 500) % 2 === 0 ? flashColor : originalColor;
    }, false)
  );
  // 将闪动状态保存到实体上,便于后续控制
  polygonEntity._isFlashing = isFlashing;
}
// 停止闪动效果
function stopFlashing(polygonEntity) {
  // 恢复原始颜色
  const originalColor = polygonEntity._originalColor || Cesium.Color.WHITE; // 如果没有原始颜色,默认使用白色
  polygonEntity.polygon.material = new Cesium.ColorMaterialProperty(originalColor);
  // 清空闪动状态
  polygonEntity._isFlashing = false;
  polygonEntity._originalColor = null; // 清除保存的原始颜色
}
onMounted(() => {
  setupRowClickListener()
  getMaxInfluenceAreaData();
});
onUnmounted(() => {