<template>
|
<Left @start="startSimulate" @end="endSimulate" />
|
<echartInfo
|
:isDynamicMode="isDynamicMode"
|
:isFinish="isFinish"
|
v-if="rightRiverShow"
|
/>
|
<TimeLine
|
v-if="showWaterSimulate"
|
@time-update="timeUpdate"
|
@is-playing="isPlaying"
|
:waterSimulateParams="waterSimulateParams"
|
@playbackFinished="playbackFinished"
|
@end="endSimulate"
|
@isColorRender="isColorRender"
|
/>
|
<LegendMNFZ class="legend" v-if="isShowLegend"></LegendMNFZ>
|
<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 LegendMNFZ from "@/components/tools/Legend_mnfz.vue";
|
import Left from "./left/Left.vue";
|
import echartInfo from "@/components/monifangzhen/echartInfo.vue";
|
import DebuffDetail from "@/components/tools/DebuffDetail.vue";
|
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";
|
import { checkedKeys } from "@/store/index";
|
|
import { useSimStore } from "@/store/simulation";
|
import { storeToRefs } from "pinia";
|
const simStore = useSimStore();
|
const { rightRiverShow } = storeToRefs(simStore);
|
|
const waterSimulateParams = ref({});
|
const showWaterSimulate = ref(false);
|
const showDebuffDetail = ref(false);
|
const showDebuffTable = ref(false);
|
const isDynamicMode = ref(false);
|
const isFinish = ref(true);
|
const isShowLegend = ref(false);
|
|
const treeMap = new Map();
|
|
// 提供方法给所有子组件
|
provide("simulateActions", {
|
startSimulate,
|
endSimulate,
|
});
|
|
function startSimulate(form) {
|
// console.log("form", form);
|
showWaterSimulate.value = true;
|
rightRiverShow.value = true;
|
waterSimulateParams.value = form;
|
}
|
function endSimulate() {
|
rightRiverShow.value = false;
|
showDebuffDetail.value = false;
|
clearTrailLine();
|
removeEmergencyPoints();
|
removeDataSources();
|
showWaterSimulate.value = false;
|
setTimeout(() => {
|
isDynamicMode.value = false;
|
// 清除威胁对象表格内容
|
EventBus.emit("reset-table");
|
// 清除降雨数据内容
|
EventBus.emit("clear-echart");
|
}, 1000);
|
}
|
const MaxInfluenceAreaList = ref([]);
|
// 初始化 dataSources 全局数组
|
const dataSources = [];
|
async function getTimeMarkers() {
|
const list = MaxInfluenceAreaList.value;
|
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) => {
|
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;
|
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
|
),
|
},
|
});
|
dataSource.entities.add(billboardEntity);
|
});
|
viewer.dataSources.add(dataSource);
|
dataSources.push(dataSource);
|
});
|
await Promise.all(loadPromises);
|
setupRowClickListener(dataSources);
|
} catch (error) {}
|
}
|
// 清除隐患点
|
function removeDataSources() {
|
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) {
|
// 清除避险点绿色面片
|
clearAreaPolygon();
|
// 如果是 Cesium 实体,使用 coreMap.entities.remove 移除
|
earthCtrl.coreMap.entities.remove(entity);
|
}
|
});
|
treeMap.set("避险场所", []); // 清空存储的避险场所列表
|
}
|
}
|
|
// 虚线避险路线
|
// const position1 = [
|
// {
|
// x: -2172867.1941179745,
|
// y: 4339567.67446477,
|
// z: 4125575.4386990573,
|
// },
|
// {
|
// x: -2172867.1941179745,
|
// y: 4339567.67446477,
|
// z: 4125575.4386990573,
|
// },
|
// {
|
// x: -2172700.396781143,
|
// y: 4339454.037139385,
|
// z: 4125736.906847591,
|
// },
|
// {
|
// x: -2172744.4001612393,
|
// y: 4339361.421455601,
|
// z: 4125804.324253885,
|
// },
|
// {
|
// x: -2172824.3311673277,
|
// y: 4339274.56533081,
|
// z: 4125844.432999503,
|
// },
|
// {
|
// x: -2172822.298957661,
|
// y: 4339226.700024104,
|
// z: 4125896.451233209,
|
// },
|
// {
|
// x: -2172776.0573917977,
|
// y: 4339194.843872361,
|
// z: 4125947.9581145854,
|
// },
|
// {
|
// x: -2172755.2828807314,
|
// y: 4339149.410126468,
|
// z: 4125995.9286539108,
|
// },
|
// {
|
// x: -2172660.9533022284,
|
// y: 4339085.401362197,
|
// z: 4126101.3750262205,
|
// },
|
// {
|
// x: -2172613.460204307,
|
// y: 4339073.342332504,
|
// z: 4126134.479399525,
|
// },
|
// {
|
// x: -2172583.664140033,
|
// y: 4339085.533980615,
|
// z: 4126140.3272964833,
|
// },
|
// {
|
// x: -2172348.977405535,
|
// y: 4338967.122025027,
|
// z: 4126358.7532469626,
|
// },
|
// {
|
// x: -2172276.019363938,
|
// y: 4338943.999121099,
|
// z: 4126416.339696519,
|
// },
|
// {
|
// x: -2172178.064812976,
|
// y: 4338928.9482959965,
|
// z: 4126475.798078439,
|
// },
|
// {
|
// x: -2172171.5451145098,
|
// y: 4338941.186930828,
|
// z: 4126466.425301899,
|
// },
|
// {
|
// x: -2172177.9565195283,
|
// y: 4338940.424956708,
|
// z: 4126463.8688932694,
|
// },
|
// ];
|
|
///////////////////////////// 流光线避险路线/////////////////////////////
|
let pathLayer = null; // 存储创建的图层
|
function showLine() {
|
// 创建新图层
|
pathLayer = earthCtrl.factory.createPathLayer({
|
url: "/json/line.json",
|
color: "#00FF00",
|
width: 12.0,
|
pointColor: "#FFFF73",
|
speed: 2,
|
far: 50000,
|
});
|
}
|
|
// 清除避险路线
|
function clearTrailLine() {
|
if (pathLayer) {
|
pathLayer.clear();
|
}
|
// if (item && typeof item.deleteObject === "function") {
|
// item.deleteObject();
|
// } else if (item && typeof item.clear === "function") {
|
// item.clear();
|
// } else if (item && earthCtrl && earthCtrl.coreMap) {
|
// earthCtrl.coreMap.entities.remove(item);
|
// }
|
// });
|
pathLayer = null;
|
}
|
///////////////////////////// 流光线避险路线/////////////////////////////
|
///////////////////////////// 箭头版避险路线/////////////////////////////
|
// let TrailLine = [];
|
// async function showLine() {
|
// const position1 = [
|
// {
|
// x: -2172867.1941179745,
|
// y: 4339567.67446477,
|
// z: 4125575.4386990573,
|
// },
|
// {
|
// x: -2172867.1941179745,
|
// y: 4339567.67446477,
|
// z: 4125575.4386990573,
|
// },
|
// {
|
// x: -2172700.396781143,
|
// y: 4339454.037139385,
|
// z: 4125736.906847591,
|
// },
|
// {
|
// x: -2172744.4001612393,
|
// y: 4339361.421455601,
|
// z: 4125804.324253885,
|
// },
|
// {
|
// x: -2172824.3311673277,
|
// y: 4339274.56533081,
|
// z: 4125844.432999503,
|
// },
|
// {
|
// x: -2172822.298957661,
|
// y: 4339226.700024104,
|
// z: 4125896.451233209,
|
// },
|
// {
|
// x: -2172776.0573917977,
|
// y: 4339194.843872361,
|
// z: 4125947.9581145854,
|
// },
|
// {
|
// x: -2172755.2828807314,
|
// y: 4339149.410126468,
|
// z: 4125995.9286539108,
|
// },
|
// {
|
// x: -2172660.9533022284,
|
// y: 4339085.401362197,
|
// z: 4126101.3750262205,
|
// },
|
// {
|
// x: -2172613.460204307,
|
// y: 4339073.342332504,
|
// z: 4126134.479399525,
|
// },
|
// {
|
// x: -2172583.664140033,
|
// y: 4339085.533980615,
|
// z: 4126140.3272964833,
|
// },
|
// {
|
// x: -2172348.977405535,
|
// y: 4338967.122025027,
|
// z: 4126358.7532469626,
|
// },
|
// {
|
// x: -2172276.019363938,
|
// y: 4338943.999121099,
|
// z: 4126416.339696519,
|
// },
|
// {
|
// x: -2172178.064812976,
|
// y: 4338928.9482959965,
|
// z: 4126475.798078439,
|
// },
|
// {
|
// x: -2172171.5451145098,
|
// y: 4338941.186930828,
|
// z: 4126466.425301899,
|
// },
|
// {
|
// x: -2172177.9565195283,
|
// y: 4338940.424956708,
|
// z: 4126463.8688932694,
|
// },
|
// ];
|
// const position2 = [
|
// {
|
// x: -2171569.1995107993,
|
// y: 4338474.198855222,
|
// z: 4127198.938949332,
|
// },
|
// {
|
// x: -2171596.1458028457,
|
// y: 4338508.014766663,
|
// z: 4127160.0148374927,
|
// },
|
// {
|
// x: -2171663.8877153755,
|
// y: 4338521.115613981,
|
// z: 4127111.758040112,
|
// },
|
// {
|
// x: -2171815.8899659193,
|
// y: 4338612.264105235,
|
// z: 4126950.0428421027,
|
// },
|
// {
|
// x: -2171839.2819730053,
|
// y: 4338700.186548507,
|
// z: 4126845.712987762,
|
// },
|
// {
|
// x: -2171792.4015423204,
|
// y: 4338769.135301243,
|
// z: 4126802.7938519563,
|
// },
|
// {
|
// x: -2171943.7495626938,
|
// y: 4338851.9854133595,
|
// z: 4126649.5658632508,
|
// },
|
// {
|
// x: -2172026.1490882114,
|
// y: 4338896.137127666,
|
// z: 4126571.6284971433,
|
// },
|
// {
|
// x: -2172182.2854437083,
|
// y: 4338931.410179759,
|
// z: 4126471.0308961133,
|
// },
|
// {
|
// x: -2172175.3377184337,
|
// y: 4338941.338674108,
|
// z: 4126464.288707359,
|
// },
|
// {
|
// x: -2172175.3377184337,
|
// y: 4338941.338674108,
|
// z: 4126464.288707359,
|
// },
|
// ];
|
// // 定义一个函数来创建轨迹线
|
// function createTrailLine(positions, color = "#ffffff") {
|
// let LineInterpolation = earthCtrl.core.LineInterpolation(
|
// earthCtrl.coreMap,
|
// {
|
// positions: positions,
|
// num: 50,
|
// getHeight: true,
|
// }
|
// );
|
|
// let min = LineInterpolation.height;
|
// let max = min.map((item) => item + 35);
|
|
// console.log(min, max);
|
|
// let _TrailLine = earthCtrl.factory.createTrailLineWall(
|
// LineInterpolation.positions,
|
// {
|
// maximumHeights: max,
|
// minimumHeights: min,
|
// color: color, // 线颜色
|
// url: colors, // 如果没有设置 colors,请用纯色或删除此行
|
// }
|
// );
|
// TrailLine.push(_TrailLine);
|
// }
|
|
// // 分别创建两条轨迹线
|
// createTrailLine(position1, "#ff0000"); // 红色轨迹
|
// createTrailLine(position2, "#0000ff"); // 蓝色轨迹
|
// }
|
// // 清除轨迹线对象
|
// function clearTrailLine() {
|
// TrailLine.forEach((item, index) => {
|
// if (item && typeof item.deleteObject === "function") {
|
// item.deleteObject();
|
// } else if (item && typeof item.clear === "function") {
|
// item.clear();
|
// } else if (item && earthCtrl && earthCtrl.coreMap) {
|
// earthCtrl.coreMap.entities.remove(item);
|
// }
|
// });
|
// TrailLine = [];
|
// }
|
///////////////////////////// 箭头版避险路线/////////////////////////////
|
|
function timeUpdate(percentage) {
|
if (percentage > 99.9) {
|
if (showDebuffDetail.value) {
|
return;
|
}
|
checkedKeys.value = ["避险场所"];
|
showDebuffDetail.value = true;
|
getTimeMarkers();
|
addTetrahedron();
|
showLine();
|
}
|
}
|
function openDetail() {
|
showDebuffTable.value = true;
|
}
|
function closeDebuffTable() {
|
showDebuffTable.value = false;
|
showDebuffDetail.value = true;
|
}
|
function getMaxInfluenceAreaData() {
|
getMaxInfluenceArea().then((res) => {
|
MaxInfluenceAreaList.value = res.data.items;
|
});
|
}
|
|
function isPlaying(val) {
|
isDynamicMode.value = val;
|
}
|
|
function playbackFinished(val) {
|
isFinish.value = val;
|
}
|
function isColorRender(val){
|
console.log('这里打印是否显示水位图例的值:',val);
|
isShowLegend.value = val
|
}
|
// 定义全局变量存储当前正在闪动的面片
|
let flashingPolygon = null;
|
|
// 添加事件监听器,接收来自表格组件的事件
|
function setupRowClickListener(dataSources) {
|
if (!Array.isArray(dataSources) || dataSources.length === 0) {
|
return;
|
}
|
EventBus.on("row-clicked", (id) => {
|
const clickedEntity = findEntityById(id, dataSources);
|
if (clickedEntity) {
|
// 如果点击的是同一个实体,则停止闪动并清空选择
|
if (flashingPolygon && flashingPolygon === clickedEntity) {
|
stopFlashing(flashingPolygon);
|
flashingPolygon = null; // 清空当前选中的实体
|
return;
|
}
|
// 如果有其他实体正在闪动,先停止它的闪动
|
if (flashingPolygon && flashingPolygon !== clickedEntity) {
|
stopFlashing(flashingPolygon);
|
}
|
// 开始新的闪动
|
startFlashing(clickedEntity);
|
flashingPolygon = clickedEntity;
|
} else {
|
console.warn(`No entity found with ID: ${id}`);
|
}
|
});
|
}
|
|
// 根据ID查找实体
|
function findEntityById(id, dataSources) {
|
if (!Array.isArray(dataSources) || dataSources.length === 0) {
|
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(() => {
|
endSimulate();
|
});
|
// // 转换坐标系,笛卡尔坐标转为WGS48
|
// const positions = [[-2171569.1995107993, 4338474.198855222, 4127198.938949332]];
|
// const wgs84Positions = positions.map((xyz) => {
|
// const cartesian = Cesium.Cartesian3.fromArray(xyz);
|
// const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
|
// // 弧度转角度
|
// const lon = Cesium.Math.toDegrees(cartographic.longitude);
|
// const lat = Cesium.Math.toDegrees(cartographic.latitude);
|
// const height = cartographic.height; // 单位:米
|
|
// return [lon, lat, height];
|
// });
|
</script>
|
<style lang="less" scoped>
|
@import url("../assets/css/home.css");
|
.legend {
|
// background: url("@/assets/img/right/rightbg.png");
|
color: white;
|
position: fixed;
|
bottom: 6%;
|
right: 20%;
|
z-index: 3333;
|
}
|
</style>
|