| | |
| | | <template> |
| | | <div class="district"> |
| | | <div class="left-top"> |
| | | <span>监测位置</span> |
| | | <template> |
| | | <div class="district"> |
| | | <div class="left-top"> |
| | | <span>监测位置</span> |
| | | </div> |
| | | |
| | | <div class="left-content district-content"> |
| | | <div style="margin-left: 5px; margin-bottom: 5px"> |
| | | <span style="color: white">北京市:</span> |
| | | <el-select |
| | | @change="handleChange1" |
| | | v-model="selectValue1" |
| | | placeholder="Select" |
| | | size="mini" |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="item in BJoptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </div> |
| | | <div style="margin-left: 5px"> |
| | | <span style="color: white">重点沟:</span> |
| | | <el-select |
| | | @change="handleChange" |
| | | v-model="selectValue" |
| | | placeholder="Select" |
| | | size="mini" |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="item in options" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </div> |
| | | |
| | | <div class="left-content district-content"> |
| | | <div style="margin-left: 5px"> |
| | | <span style="color: white">重点沟:</span> |
| | | <el-select @change="handleChange" v-model="selectValue" placeholder="Select" size="large" |
| | | style="width: 240px"> |
| | | <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | <!-- 滚动区域 --> |
| | | <div style="overflow-y: auto; height: 91%; position: relative"> |
| | | <!-- 加载遮罩层 --> |
| | | <div v-if="loading" class="loading-overlay"> |
| | | <div class="loading-content"> |
| | | <el-icon class="loading-icon"><Loading /></el-icon> |
| | | <span class="loading-text">数据加载中...</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 滚动区域 --> |
| | | <div style="overflow-y: auto; height: 95%"> |
| | | <!-- 加载遮罩层 --> |
| | | <div v-if="loading" class="loading-overlay"> |
| | | <div class="spinner"></div> |
| | | </div> |
| | | <div v-else v-for="(item, key) in districtList" :key="key" class="district-item" @click="handleClick(item)"> |
| | | <div class="district-item-icon"></div> |
| | | <div class="district-item-text">{{ item.hdName }}</div> |
| | | </div> |
| | | <div |
| | | v-else |
| | | v-for="(item, key) in districtList" |
| | | :key="key" |
| | | class="district-item" |
| | | @click="handleClick(item)" |
| | | > |
| | | <div class="district-item-icon"></div> |
| | | <div class="district-item-text">{{ item.hdName }}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, watch, onBeforeUnmount } from "vue"; |
| | | import { createPoint, removeEntities } from "@/utils/map"; |
| | | import { createPoint,clearAllPoints } from "@/utils/map"; |
| | | import { useSimStore } from "@/store/simulation"; |
| | | import { initeWaterPrimitiveView } from "@/utils/water"; //相机flyTo函数,后续options列表中有对应经纬度后弃用 |
| | | import { useRoute, onBeforeRouteUpdate } from 'vue-router'; |
| | | import { useRoute, onBeforeRouteUpdate } from "vue-router"; |
| | | import { Loading } from "@element-plus/icons-vue"; |
| | | |
| | | const districtList = ref([]); |
| | | |
| | | |
| | | const simStore = useSimStore(); |
| | | onBeforeRouteUpdate((to, from, next) => { |
| | | if (to.path !== '/yhgl') { |
| | | handleCleanup(); |
| | | } |
| | | next(); |
| | | }); |
| | | |
| | | const route = useRoute(); |
| | | |
| | | onBeforeUnmount(() => { |
| | | if (route.path !== '/yhgl') { |
| | | handleCleanup(); |
| | | if (route.path !== "/yhgl") { |
| | | clearAllPoints(); |
| | | } |
| | | }); |
| | | const selectValue = ref("孙胡沟"); |
| | | |
| | | const selectValue1 = ref("北京市"); |
| | | |
| | | const BJoptions = ref([]); |
| | | |
| | | const options = ref([ |
| | | { |
| | |
| | | }, |
| | | ]); |
| | | |
| | | const districtList = ref([]); |
| | | const loading = ref(true); // 控制加载状态 |
| | | |
| | | function handleClick(district) { |
| | | // 此处调用是因为GisView页面会在点击下一乡镇之前把上一个选择的区域的隐患点清除掉(如果刚好选择了孙胡沟,那么下一个点击将会清空孙胡沟的隐患点) |
| | | initializeDevicePoints(); |
| | | const entity = viewer.entities.getById(district.hdId); |
| | | if (entity) { |
| | | viewer.flyTo(entity, { |
| | |
| | | }); |
| | | } |
| | | } |
| | | const handleCleanup = async () => { |
| | | await Promise.all(districtList.value.map(item => removeEntities(item.hdId))); |
| | | } |
| | | |
| | | const initializeDevicePoints = async () => { |
| | | await Promise.all(districtList.value.map(async (item, index) => { |
| | | // 根据需求可增删 |
| | | item.id = item.hdId; |
| | | item.name = item.hdName; |
| | | item.latitude = item.lat; |
| | | item.longitude = item.lon; |
| | | item.showBillboard = true; |
| | | item.type = item.disasterType; |
| | | item.className = "district"; |
| | | await createPoint(item); |
| | | // 打印每个设备的名称和设备类型 |
| | | // console.log(`设备名称: ${item.id}, 设备类型: ${item.name}`); |
| | | })); |
| | | await Promise.all( |
| | | districtList.value.map(async (item, index) => { |
| | | // 根据需求可增删 |
| | | item.id = item.hdId; |
| | | item.name = item.hdName; |
| | | item.latitude = item.lat; |
| | | item.longitude = item.lon; |
| | | item.showBillboard = true; |
| | | item.type = item.disasterType; |
| | | item.className = "district"; |
| | | await createPoint(item); |
| | | // 打印每个设备的名称和设备类型 |
| | | // console.log(`设备名称: ${item.id}, 设备类型: ${item.name}`); |
| | | }) |
| | | ); |
| | | }; |
| | | // 根据区域名称过滤数据 |
| | | |
| | | const filterDataByArea = async (areaName) => { |
| | | handleCleanup(); |
| | | clearAllPoints(); |
| | | if (!areaName || !simStore.DangerPoint || simStore.DangerPoint.length === 0) { |
| | | districtList.value = []; |
| | | return; |
| | |
| | | ); |
| | | |
| | | if (JSON.stringify(districtList.value) !== JSON.stringify(filteredData)) { |
| | | districtList.value = filteredData; |
| | | |
| | | await initializeDevicePoints(); |
| | | } |
| | | }; |
| | |
| | | }; |
| | | let isInitialized = false; |
| | | |
| | | watch(() => simStore.DangerShowSwitch, async (newValue, oldValue) => { |
| | | if (newValue) { |
| | | if (!isInitialized) { |
| | | await initializeDevicePoints(); |
| | | isInitialized = true; |
| | | } |
| | | } else { |
| | | handleCleanup(); |
| | | isInitialized = false; |
| | | } |
| | | }); |
| | | // watch( |
| | | // () => simStore.DangerShowSwitch, |
| | | // async (newValue, oldValue) => { |
| | | // console.log("当前状态:", newValue); |
| | | |
| | | // if (newValue) { |
| | | // if (!isInitialized) { |
| | | // await initializeDevicePoints(); |
| | | // isInitialized = true; |
| | | // } |
| | | // } else { |
| | | // clearAllPoints(); |
| | | // isInitialized = false; |
| | | // } |
| | | // } |
| | | // ); |
| | | // 监听 simStore.DangerPoint 变化 |
| | | watch( |
| | | () => simStore.DangerPoint, |
| | |
| | | filterDataByArea(selectValue.value); |
| | | loading.value = false; // 数据加载完成 |
| | | } else { |
| | | handleCleanup(); |
| | | clearAllPoints(); |
| | | districtList.value = []; |
| | | loading.value = true; // 数据未准备就绪 |
| | | } |
| | |
| | | ); |
| | | |
| | | onMounted(() => { |
| | | handleCleanup() |
| | | initeWaterPrimitiveView() |
| | | clearAllPoints(); |
| | | // initeWaterPrimitiveView(); |
| | | // 默认先检查一遍数据 |
| | | if (simStore.DangerPoint && simStore.DangerPoint.length > 0) { |
| | | filterDataByArea("孙胡沟"); |
| | |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .loading-overlay { |
| | | position: absolute; |
| | | top: 120px; |
| | | left: 0px; |
| | | right: 0px; |
| | | bottom: 10px; |
| | | background-color: rgba(236, 233, 233, 0.5); |
| | | /* 半透明遮罩 */ |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | z-index: 999; |
| | | } |
| | | |
| | | .spinner { |
| | | width: 40px; |
| | | height: 40px; |
| | | border: 4px solid #fff; |
| | | border-top: 4px solid transparent; |
| | | border-radius: 50%; |
| | | animation: spin 1s linear infinite; |
| | | } |
| | | |
| | | @keyframes spin { |
| | | to { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | .district { |
| | | position: absolute; |
| | | width: 345px; |
| | |
| | | .district-content { |
| | | padding: 10px; |
| | | box-sizing: border-box; |
| | | height: calc(100% - 70px); |
| | | position: relative; |
| | | } |
| | | |
| | | .district-item-icon { |
| | |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | .loading-overlay { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | // background-color: rgba(0, 0, 0, 0.7); |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | z-index: 100; |
| | | // border-radius: 4px; |
| | | } |
| | | |
| | | .loading-content { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | color: #fff; |
| | | } |
| | | |
| | | .loading-icon { |
| | | font-size: 24px; |
| | | margin-bottom: 8px; |
| | | animation: rotating 2s linear infinite; |
| | | } |
| | | |
| | | .loading-text { |
| | | color: white; |
| | | font-size: 14px; |
| | | text-align: center; |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | @keyframes rotating { |
| | | 0% { |
| | | transform: rotate(0deg); |
| | | } |
| | | 100% { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | /deep/ .el-select__placeholder { |