| | |
| | | // 通过接口去请求json,将请求的json解析获取泥石流参数 |
| | | export async function fetchWaterSimulationData(serviceInfo) { |
| | | try { |
| | | const response = await fetch(`/simu/${serviceInfo}/layer.json`); // 发起请求 |
| | | // const response = await fetch(`/simu/c2h1dc/layer.json`); // 发起请求 |
| | | // const response = await fetch(`/simu/${serviceInfo}/layer.json`); // 发起请求 |
| | | const response = await fetch(`/simu/c2h1dc/layer.json`); // 发起请求 |
| | | if (!response.ok) { |
| | | throw new Error(`HTTP error! status: ${response.status}`); |
| | | } |
| | |
| | | <div v-for="(date, index) in visibleDates" :key="index" class="date-label"> |
| | | <!-- {{ formatDate(date) }} --> |
| | | </div> |
| | | <!-- 专题渲染: |
| | | <el-switch v-model="isColorRenderEnabled" @change="handleColorRenderChange" style="margin-top:-3px" |
| | | :disabled="!isPlaying || !isWaterPrimitiveCreated" /> --> |
| | | <!-- active-text="开" inactive-text="关" --> |
| | | <div>专题渲染: |
| | | <el-switch v-model="isColorRenderEnabled" @change="handleColorRenderChange" style="margin-top:-3px" |
| | | :disabled="!isPlaying || !isWaterPrimitiveCreated" /> |
| | | <!-- active-text="开" inactive-text="关" --> |
| | | </div> |
| | | </div> |
| | | <div class="timeline-track" ref="timelineTrack" @click="seekToPosition"> |
| | | <div class="timeline-progress" :style="{ width: progressPercentage + '%' }"></div> |
| | |
| | | import { fetchWaterSimulationData } from "@/api/trApi.js"; |
| | | import { EventBus } from "@/eventBus"; |
| | | import { ElMessage } from "element-plus"; |
| | | // 状态管理器 |
| | | import { useSimStore } from "@/store/simulation"; |
| | | import { storeToRefs } from "pinia"; |
| | | const simStore = useSimStore(); |
| | | const { selectedScheme } = storeToRefs(simStore); |
| | | |
| | | const emit = defineEmits(["timeUpdate", "isPlaying", "playbackFinished", "isColorRender"]); |
| | | // 定义props |
| | | const props = defineProps({ |
| | |
| | | ); |
| | | // 播放控制 |
| | | const togglePlay = () => { |
| | | // 这里应该再设定几个限制,如果缺少什么数据,无法进行仿真 |
| | | if (!isPlaying.value && currentTime.value >= duration.value) |
| | | currentTime.value = 0; |
| | | |
| | |
| | | startPlayback(); |
| | | |
| | | if (!isWaterPrimitiveCreated.value) { |
| | | console.log(serviceInfo, '这里是当前方案的服务信息!'); |
| | | // console.log(serviceInfo, '这里是当前方案的服务信息!'); |
| | | // 这里通过water.js中去发送请求获取水面模拟 |
| | | createWaterPrimitive({ |
| | | baseUrl: `/simu/${serviceInfo}`, |
| | | // baseUrl: `/simu/${serviceInfo}`, |
| | | baseUrl: `/simu/c2h1dc`, |
| | | interval: intervalMap[playbackRate.value], |
| | | colorRender: isColorRenderEnabled.value |
| | | }); |
| | |
| | | if (typeof data === 'string') { |
| | | try { |
| | | data = JSON.parse(data); |
| | | console.log('解析后的 data:', data); |
| | | console.log('解析后的降雨数据:', data); |
| | | } catch (e) { |
| | | console.error("data 不是有效的 JSON 字符串"); |
| | | return; |
| | | } |
| | | } |
| | | // 打印降雨强度的单位 |
| | | console.log('降雨强度的单位是:', data.intensityUnit); |
| | | // 根据 intensityUnit 调整 rainfalls 中的 intensity 值 |
| | | if (data.intensityUnit === 'mm/min') { |
| | | data.rainfalls.forEach(r => r.intensity *= 60); |
| | | console.log('将 mm/min 转换为 mm/h 后的 rainfalls:', data.rainfalls); |
| | | } else if (data.intensityUnit === 'mm/5min') { |
| | | data.rainfalls.forEach(r => r.intensity *= 12); |
| | | console.log('将 mm/5min 转换为 mm/h 后的 rainfalls:', data.rainfalls); |
| | | } else if (data.intensityUnit !== 'mm/h') { |
| | | console.warn('未知的 intensity 单位,无法进行转换'); |
| | | } |
| | | |
| | | const rainfallList = data.rainfalls; |
| | | console.log('最终的 rainfallList:', rainfallList); |
| | | |
| | | // 提取 intensity 值 |
| | | rainFallValues.value = rainfallList.map(r => r.intensity); |
| | | minRainValue.value = Math.min(...rainFallValues.value); |
| | | maxRainValue.value = Math.max(...rainFallValues.value); |
| | | console.log(minRainValue.value, maxRainValue.value, 'min and max rain values'); |
| | | console.log('当前方案下最小雨量和最大雨量:', minRainValue.value, maxRainValue.value); |
| | | } |
| | | // 定义降雨等级及其对应的视觉参数 |
| | | const rainLevels = [ |
| | |
| | | size: 0.7, |
| | | speed: 40, |
| | | density: 35, |
| | | color: '#ADD8E6' // 天蓝色,象征持续的中雨 |
| | | color: '#ADD8E6' |
| | | }, |
| | | { |
| | | name: '大雨', |
| | |
| | | size: 1.0, |
| | | speed: 70, |
| | | density: 60, |
| | | color: '#ADD8E6' // 深蓝色,象征密集的大雨 |
| | | color: '#ADD8E6' |
| | | }, |
| | | { |
| | | name: '暴雨', |
| | |
| | | size: 1.3, |
| | | speed: 90, |
| | | density: 80, |
| | | color: '#ADD8E6' // 深蓝黑色,象征强降雨 |
| | | color: '#ADD8E6' |
| | | }, |
| | | { |
| | | name: '大暴雨', |
| | |
| | | size: 1.6, |
| | | speed: 110, |
| | | density: 100, |
| | | color: '#ADD8E6' // 黑色,象征极端暴雨 |
| | | color: '#ADD8E6' |
| | | } |
| | | ]; |
| | | // 根据降雨量返回对应的雨形配置 |
| | |
| | | const alpha = floatIndex - index; |
| | | const rainValue = currentRain + (nextRain - currentRain) * alpha; |
| | | // 打印当前处理的雨量数据 |
| | | console.log(`正在处理的雨量数据点: 当前=${currentRain}, 下一个=${nextRain}, 插值后=${rainValue.toFixed(2)}, 索引=${index}`); |
| | | |
| | | // console.log(`正在处理的雨量数据点: 当前=${currentRain}, 下一个=${nextRain}, 插值后=${rainValue.toFixed(2)}, 索引=${index}`); |
| | | // 如果当前索引未变化且插值差异不大,跳过重复更新 |
| | | if (index === lastUsedIndex && Math.abs(rainValue - lastRainValue) < 0.1) { |
| | | console.log('由于数据无显著变化,跳过本次更新'); |
| | |
| | | rainDensity: rainLevel.density, |
| | | rainColor: rainLevel.color |
| | | }; |
| | | |
| | | console.log('当前雨量数据:', rainValue); |
| | | console.log('当前雨形:', rainLevel); |
| | | console.log('当前雨量数据:', rainValue, '当前雨形:', rainLevel); |
| | | // 调用工具方法更新雨效 |
| | | mapUtils.toggleRain(rainParams, true); |
| | | } |
| | |
| | | dayjs(waterTimestamps.value[closestIndex]).format("YYYY-MM-DD HH:mm:ss") |
| | | ); |
| | | // 调用跳转接口,传递索引值 |
| | | console.log(closestIndex,'最近的索引值'); |
| | | |
| | | setTimeForWaterSimulation(closestIndex); |
| | | |
| | | // 如果当前是暂停状态,调用 pauseWaterSimulation |
| | |
| | | // 当前方案的所有信息 |
| | | const schemeInfo = selectedScheme.value; |
| | | serviceInfo = schemeInfo.serviceName; |
| | | console.log('获取到的 serviceName:', serviceInfo); |
| | | // console.log('获取到的 serviceName:', serviceInfo); |
| | | getRainfallData() |
| | | // 根据layer.json去获取时间轴信息 |
| | | const { waterTimestamps: timestamps } = await fetchWaterSimulationData(serviceInfo); |
| | |
| | | } |
| | | } catch (error) { |
| | | console.error("Error loading water simulation data:", error); |
| | | ElMessage({ |
| | | message: "降雨数据出错,请重新新建模拟方案!", |
| | | type: "warning", |
| | | }); |
| | | } |
| | | }); |
| | | |
| | |
| | | dayjs(last).toISOString(), |
| | | ]; |
| | | duration.value = dayjs(last).diff(dayjs(first), "second"); |
| | | console.log("Updated timeline range:", { |
| | | ...props.waterSimulateParams, |
| | | duration: duration.value, |
| | | }); |
| | | // console.log("Updated timeline range:", { |
| | | // ...props.waterSimulateParams, |
| | | // duration: duration.value, |
| | | // }); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | const { endSimulate } = inject("simulateActions"); |
| | | function handleBack() { |
| | | endSimulate(); |
| | | isWaterPrimitiveCreated.value = false; |
| | | if (ratelevelRef.value) { |
| | | ratelevelRef.value.endCalculation(); |
| | | } |
| | |
| | | setTimeout(() => { |
| | | mapUtils.delRain(); |
| | | }, 3000); |
| | | ElMessage({ message: "模拟进程正在关闭中...", type: "success" }); // 显示消息通知用户模拟进程正在关闭 |
| | | endSimulate(); |
| | | isWaterPrimitiveCreated.value = false; |
| | | destoryWaterPrimitive(); |
| | | EventBus.emit("hide-schemeInfo"); |
| | | ElMessage({ message: "模拟进程正在关闭中...", type: "success" }); |
| | | } |
| | | </script> |
| | | <style scoped> |
| | |
| | | position: relative; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .timeline-progress { |
| | | height: 100%; |
| | | background-color: #4a90e2; |
| | |
| | | top: 0; |
| | | left: 0; |
| | | } |
| | | |
| | | .timeline-cursor { |
| | | width: 12px; |
| | | height: 12px; |
| | |
| | | transform: translate(-50%, -50%); |
| | | z-index: 2; |
| | | } |
| | | |
| | | .time-markers { |
| | | position: absolute; |
| | | width: 100%; |
| | |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | |
| | | /* .date-part { |
| | | margin-bottom: 2px; |
| | | } */ |
| | |
| | | font-size: 11px; |
| | | opacity: 0.8; |
| | | } |
| | | |
| | | .current-date { |
| | | margin-bottom: 5px; |
| | | font-size: 15px; |
| | |
| | | position: point.cartesian, |
| | | label: { |
| | | text: `测量点 ${index + 1}\n经度: ${point.longitude.toFixed(6)}\n纬度: ${point.latitude.toFixed(6)}\n时间: ${displayTime}`, |
| | | font: '14pt monospace', // 减小字体大小 |
| | | font: '14pt monospace', |
| | | style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | | fillColor: Cesium.Color.YELLOW, |
| | | outlineColor: Cesium.Color.BLACK, |
| | | outlineWidth: 2, // 减小轮廓宽度 |
| | | 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), // 减小背景填充 |
| | | backgroundPadding: new Cesium.Cartesian2(10, 10), |
| | | showBackground: true, |
| | | scale: 1, // 设置缩放比例 |
| | | maximumScale: 1.5, // 设置最大缩放比例 |
| | | scale: 1, |
| | | distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000), // 距地面5000米内显示 |
| | | pixelOffsetScaleByDistance: new Cesium.NearFarScalar( |
| | | 100, // Near 距离 (相机离地100米) |
| | | 1.0, // 在近处,放大倍数为1.0(正常) |
| | | 5000, // Far 距离 (相机离地5000米) |
| | | 0.3 // 在远处,缩小到0.3倍 |
| | | ) |
| | | } |
| | | }); |
| | | |
| | |
| | | material: new Cesium.PolylineOutlineMaterialProperty({ |
| | | outlineWidth: 4, |
| | | outlineColor: Cesium.Color.WHITE |
| | | }) |
| | | }), |
| | | distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000), // 距地面5000米内显示 |
| | | pixelOffsetScaleByDistance: new Cesium.NearFarScalar( |
| | | 100, // Near 距离 (相机离地100米) |
| | | 1.0, // 在近处,放大倍数为1.0(正常) |
| | | 5000, // Far 距离 (相机离地5000米) |
| | | 0.3 // 在远处,缩小到0.3倍 |
| | | ) |
| | | |
| | | |
| | | } |
| | | }); |
| | | |
| | |
| | | } |
| | | |
| | | function endCalculation() { |
| | | ElMessage.success('清除所有测量点!'); |
| | | // ElMessage.success('清除所有测量点!'); |
| | | pickedPoints.value = []; |
| | | viewer.entities.removeAll(); |
| | | // currentTime.value = 0; |
| | |
| | | // alert("当前方案尚未完成,无法进入模拟!"); |
| | | // return; |
| | | // } |
| | | if (!item.serviceName) { |
| | | ElMessage({ |
| | | message: "serviceName 不存在,无法继续!", |
| | | type: "warning", |
| | | }); |
| | | return; // 阻止后续逻辑执行 |
| | | } |
| | | // console.log(item,'iteeeeeeeem'); |
| | | // if (!item.serviceName) { |
| | | // ElMessage({ |
| | | // message: "serviceName 不存在,无法继续!", |
| | | // type: "warning", |
| | | // }); |
| | | // return; // 阻止后续逻辑执行 |
| | | // } |
| | | console.log(item,'iteeeeeeeem'); |
| | | simStore.setSelectedScheme(item); |
| | | |
| | | currentScheme.value = item; |
| | |
| | | <template> |
| | | <div class="listCard"> |
| | | <div class="top"><span>方案详情</span> |
| | | <!-- <div @click="togglePick" :class="['pick-button', { active: isPickingActive }]"> |
| | | {{ isPickingActive ? '进行计算' : '开始拾取' }} |
| | | </div> --> |
| | | </div> |
| | | <div class="details"> |
| | | <div v-if="formattedData.length" class="input-group"> |
| | | <div v-for="(item, index) in formattedData" :key="index" class="input-item"> |
| | | <label>{{ item.name }}</label> |
| | | <span>{{ item.value }}</span> |
| | | <span :class="{ 'clickable': item.isClickable }" |
| | | @click="item.isClickable ? openGaugeDialog(item.gauges) : null"> |
| | | {{ item.value }} |
| | | </span> |
| | | </div> |
| | | </div> |
| | | <div v-else> |
| | |
| | | </div> |
| | | </div> |
| | | <Message @close="close" class="mess" v-show="messageShow" :mesData="mesData" /> |
| | | <!-- 添加雨量计弹窗 --> |
| | | <div class="dialoog"> |
| | | <el-dialog v-model="dialogVisible" title="雨量计详情" width="50%" :before-close="handleClose"> |
| | | <div class="table-container"> |
| | | <el-table :data="gaugesData" border stripe height="100%"> |
| | | <el-table-column prop="name" label="名称"></el-table-column> |
| | | <el-table-column prop="x" label="经度(X)"></el-table-column> |
| | | <el-table-column prop="y" label="纬度(Y)"></el-table-column> |
| | | <el-table-column prop="r" label="半径(r)"></el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <!-- <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="dialogVisible = false">关闭</el-button> |
| | | </span> |
| | | </template> --> |
| | | </el-dialog> |
| | | </div> |
| | | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { defineProps, defineEmits, inject, ref, watch } from "vue"; |
| | | import { ElDialog, ElTable, ElTableColumn, ElButton ,ElMessage} from "element-plus"; |
| | | import dayjs from "dayjs"; |
| | | |
| | | // 公共依赖 |
| | | const props = defineProps({ selectedScheme: { type: Object, default: null } }); |
| | | const emit = defineEmits(["back"]); |
| | |
| | | const parsed = JSON.parse(dataStr); |
| | | const fields = { |
| | | total: "降雨总量(mm):", |
| | | duration: "降雨时长(分钟):", |
| | | duration: "降雨时长(小时):", |
| | | intensity: "降雨强度(mm/小时):", |
| | | prediction: "降雨场次:", |
| | | model: "降雨模式:", |
| | | history: "历史降雨:", |
| | | gauges: "雨量计列表:" |
| | | history: "历史降雨:" |
| | | }; |
| | | |
| | | return Object.entries(parsed) |
| | | const result = Object.entries(parsed) |
| | | .filter(([k]) => fields[k]) |
| | | .map(([k, v]) => ({ |
| | | name: fields[k], |
| | | value: Array.isArray(v) ? v.join(", ") : v || "无" |
| | | value: v || "无" |
| | | })); |
| | | |
| | | // 处理雨量计数据 |
| | | if (parsed.gauges && Array.isArray(parsed.gauges)) { |
| | | const gaugeNames = parsed.gauges.map(g => g.name).join(", ") || "无"; |
| | | result.push({ |
| | | name: "雨量计列表:", |
| | | value: '查看雨量计列表', |
| | | isClickable: true, |
| | | gauges: parsed.gauges |
| | | }); |
| | | } |
| | | |
| | | return result; |
| | | } catch (e) { |
| | | return [{ name: "数据:", value: dataStr || "无" }]; |
| | | } |
| | |
| | | |
| | | const entries = Object.entries(newScheme); |
| | | const areaType = newScheme.areaType; |
| | | |
| | | console.log(newScheme, 'news'); |
| | | |
| | | const result = entries.reduce((acc, [key, value]) => { |
| | | if (skipKeys.includes(key)) return acc; |
| | |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | // const pickedPoints = ref([]); |
| | | // const handler = ref(null); |
| | | // const isPickingActive = ref(false); |
| | | // // 拾取相关逻辑 |
| | | // const viewer = window.viewer; |
| | | const dialogVisible = ref(false); |
| | | const gaugesData = ref([]); |
| | | |
| | | // function getPickPosition(windowPosition) { |
| | | // if (!viewer) return null; |
| | | // viewer.scene.globe.depthTestAgainstTerrain = true; |
| | | // const cartesian = viewer.scene.pickPosition(windowPosition); |
| | | // if (!cartesian) return null; |
| | | // 打开雨量计弹窗 |
| | | function openGaugeDialog(gauges) { |
| | | if (Array.isArray(gauges) && gauges.length > 0) { |
| | | gaugesData.value = gauges.map(g => ({ |
| | | name: g.name || "未知", |
| | | x: g.x != null ? g.x.toFixed(2) : "-", |
| | | y: g.y != null ? g.y.toFixed(2) : "-", |
| | | r: g.r || "-" |
| | | })); |
| | | dialogVisible.value = true; |
| | | } else { |
| | | ElMessage({ |
| | | message: "雨量计数据出错,请重新新建模拟方案!", |
| | | type: "warning", |
| | | }); |
| | | } |
| | | } |
| | | |
| | | // const cartographic = Cesium.Cartographic.fromCartesian(cartesian); |
| | | |
| | | // // 在原有高度上增加300米 |
| | | // cartographic.height += 80.0; |
| | | |
| | | // return { |
| | | // cartesian: Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height), |
| | | // longitude: Cesium.Math.toDegrees(cartographic.longitude), |
| | | // latitude: Cesium.Math.toDegrees(cartographic.latitude), |
| | | // height: cartographic.height |
| | | // }; |
| | | // } |
| | | |
| | | // function addPointToViewer(point, index) { |
| | | // const entity = viewer.entities.add({ |
| | | // position: point.cartesian, |
| | | // billboard: { |
| | | // // image: '../path/to/your/icon.png', // 替换为你的图标路径 |
| | | // width: 32, // 图标宽度 |
| | | // height: 32, // 图标高度 |
| | | // verticalOrigin: Cesium.VerticalOrigin.BOTTOM |
| | | // }, |
| | | // label: { |
| | | // text: `Point ${index + 1}\n经度: ${point.longitude.toFixed(6)}\n纬度: ${point.latitude.toFixed(6)}`, |
| | | // font: '14pt monospace', |
| | | // style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | | // outlineWidth: 2, |
| | | // verticalOrigin: Cesium.VerticalOrigin.TOP, |
| | | // pixelOffset: new Cesium.Cartesian2(0, -40), // 调整标签相对于图标的偏移量 |
| | | // fillColor: Cesium.Color.WHITE, |
| | | // outlineColor: Cesium.Color.BLACK |
| | | // } |
| | | // }); |
| | | |
| | | // // 可选:存储实体引用以便后续操作 |
| | | // pickedPoints.value.push(entity); |
| | | // } |
| | | |
| | | // function initPickHandler() { |
| | | // if (!viewer?.scene?.canvas) return; |
| | | // handler.value = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); |
| | | |
| | | // handler.value.setInputAction((movement) => { |
| | | // const position = getPickPosition(movement.position); |
| | | // if (position) { |
| | | // const index = pickedPoints.value.length; |
| | | // pickedPoints.value.push(position); |
| | | // addPointToViewer(position, index); |
| | | // } |
| | | // }, Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | // } |
| | | |
| | | // function togglePick() { |
| | | // isPickingActive.value ? stopPicking() : startPicking(); |
| | | // } |
| | | |
| | | // function startPicking() { |
| | | // pickedPoints.value = []; |
| | | // viewer.entities.removeAll(); |
| | | // !handler.value && initPickHandler(); |
| | | // isPickingActive.value = true; |
| | | // } |
| | | |
| | | // function stopPicking() { |
| | | // if (handler.value) { |
| | | // handler.value.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | // handler.value.destroy(); |
| | | // handler.value = null; |
| | | // } |
| | | |
| | | // isPickingActive.value = false; |
| | | // } |
| | | // 关闭弹窗 |
| | | function handleClose(done) { |
| | | done(); |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | |
| | | letter-spacing: 2px; |
| | | font-weight: bolder; |
| | | } |
| | | |
| | | .clickable { |
| | | color: #5bc0de; |
| | | cursor: pointer; |
| | | text-decoration: underline; |
| | | } |
| | | |
| | | .dialoog { |
| | | ::v-deep .el-dialog__title { |
| | | color: #fff !important; |
| | | } |
| | | |
| | | ::v-deep .el-dialog { |
| | | background-color: rgb(5, 75, 69) !important; |
| | | } |
| | | |
| | | .el-dialog__body { |
| | | padding-top: 10px; |
| | | padding-bottom: 10px; |
| | | } |
| | | |
| | | .table-container .el-table { |
| | | font-size: 14px; |
| | | border-radius: 4px; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
| | | } |
| | | } |
| | | </style> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: "detail", |
| | | components: {}, |
| | | props: { |
| | | areaName: { |
| | | type: String, |
| | | default: "尹家西沟", |
| | | }, |
| | | // 状态管理器 |
| | | import { useSimStore } from "@/store/simulation"; |
| | | import { storeToRefs } from "pinia"; |
| | | const simStore = useSimStore(); |
| | | const { selectedScheme } = storeToRefs(simStore); |
| | | |
| | | export default { |
| | | name: "detail", |
| | | components: {}, |
| | | props: { |
| | | areaName: { |
| | | type: String, |
| | | default: "尹家西沟", |
| | | }, |
| | | data() { |
| | | return { |
| | | show: false, |
| | | detailList: [ |
| | | { |
| | | name: "最大雨强:", |
| | | value: Number(Math.random() * 100).toFixed(2) + " mm/h", |
| | | }, |
| | | { |
| | | name: "平均雨强:", |
| | | value: Number(Math.random() * 10).toFixed(2) + " mm/h", |
| | | }, |
| | | { |
| | | name: "最大水深:", |
| | | value: "1.86 m", |
| | | }, |
| | | { |
| | | name: "平均水深:", |
| | | value: "0.29 m", |
| | | }, |
| | | { |
| | | name: "最大流速:", |
| | | value: "7 m/s", |
| | | }, |
| | | { |
| | | name: "威胁房屋:", |
| | | value: "406 间", |
| | | }, |
| | | { |
| | | name: "威胁人口:", |
| | | value: "145 户", |
| | | }, |
| | | { |
| | | name: "威胁财产:", |
| | | value: "4872 万元", |
| | | }, |
| | | ], |
| | | }, |
| | | data() { |
| | | return { |
| | | show: false, |
| | | detailList: [ |
| | | { |
| | | name: "最大雨强:", |
| | | value: Number(Math.random() * 100).toFixed(2) + " mm/h", |
| | | }, |
| | | { |
| | | name: "平均雨强:", |
| | | value: Number(Math.random() * 10).toFixed(2) + " mm/h", |
| | | }, |
| | | { |
| | | name: "最大水深:", |
| | | value: "1.86 m", |
| | | }, |
| | | { |
| | | name: "最大流速:", |
| | | value: "7 m/s", |
| | | }, |
| | | { |
| | | name: "威胁房屋:", |
| | | value: "406 间", |
| | | }, |
| | | { |
| | | name: "威胁人口:", |
| | | value: "145 户", |
| | | }, |
| | | { |
| | | name: "威胁财产:", |
| | | value: "4872 万元", |
| | | }, |
| | | ], |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.getRainfallData(); // 组件挂载后执行获取雨量数据 |
| | | }, |
| | | methods: { |
| | | getRainfallData() { |
| | | if (!selectedScheme.value || !selectedScheme.value.data) { |
| | | console.warn("selectedScheme 或 data 不存在"); |
| | | return; |
| | | } |
| | | let data = selectedScheme.value.data; |
| | | // 如果是字符串,则尝试解析成对象 |
| | | if (typeof data === 'string') { |
| | | try { |
| | | data = JSON.parse(data); |
| | | } catch (e) { |
| | | console.error("data 不是有效的 JSON 字符串"); |
| | | return; |
| | | } |
| | | } |
| | | const rainfallList = data.rainfalls; |
| | | |
| | | // 提取 intensity 值 |
| | | const rainValues = rainfallList.map(r => r.intensity); |
| | | const minRain = Math.min(...rainValues); |
| | | const maxRain = Math.max(...rainValues); |
| | | const avgRain = rainValues.reduce((sum, val) => sum + val, 0) / rainValues.length; |
| | | |
| | | // 更新 detailList 中的“最大雨强”和“平均雨强” |
| | | this.detailList[0].value = maxRain.toFixed(2) + " mm/h"; // 最大雨强 |
| | | this.detailList[1].value = avgRain.toFixed(2) + " mm/h"; // 平均雨强 |
| | | |
| | | console.log('当前方案下最小雨量、最大雨量、平均雨量:', |
| | | minRain.toFixed(2), |
| | | maxRain.toFixed(2), |
| | | avgRain.toFixed(2) |
| | | ); |
| | | }, |
| | | methods: { |
| | | closeMsg() { |
| | | this.$emit("close") |
| | | }, |
| | | showMsg() { |
| | | this.$emit("open") |
| | | }, |
| | | closeMsg() { |
| | | this.$emit("close") |
| | | }, |
| | | } |
| | | showMsg() { |
| | | this.$emit("open") |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | <style lang="less" scoped> |
| | | .detail { |
| | | background: url("@/assets/img/tools/messagebg.png"); |
| | | background-size: 100% 100%; |
| | | width: 391px; |
| | | height: 420px; |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | z-index: 99; |
| | | } |
| | | .detail { |
| | | background: url("@/assets/img/tools/messagebg.png"); |
| | | background-size: 100% 100%; |
| | | width: 391px; |
| | | height: 420px; |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | z-index: 99; |
| | | } |
| | | |
| | | .detail-top { |
| | | position: absolute; |
| | | top: 5px; |
| | | left: 20px; |
| | | font-weight: 700; |
| | | font-size: 18px; |
| | | font-weight: 700; |
| | | color: #fff; |
| | | line-height: 40px; |
| | | width: 270px; |
| | | cursor: pointer; |
| | | } |
| | | .detail-top { |
| | | position: absolute; |
| | | top: 5px; |
| | | left: 20px; |
| | | font-weight: 700; |
| | | font-size: 18px; |
| | | font-weight: 700; |
| | | color: #fff; |
| | | line-height: 40px; |
| | | width: 270px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .detail-close { |
| | | position: absolute; |
| | | right: 3px; |
| | | top: 10px; |
| | | width: 20px; |
| | | height: 20px; |
| | | text-align: center; |
| | | line-height: 20px; |
| | | text-align: center; |
| | | .detail-close { |
| | | position: absolute; |
| | | right: 3px; |
| | | top: 10px; |
| | | width: 20px; |
| | | height: 20px; |
| | | text-align: center; |
| | | line-height: 20px; |
| | | text-align: center; |
| | | |
| | | font-weight: 700; |
| | | font-size: 18px; |
| | | font-weight: 700; |
| | | color: #fff; |
| | | cursor: pointer; |
| | | } |
| | | font-weight: 700; |
| | | font-size: 18px; |
| | | font-weight: 700; |
| | | color: #fff; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .detail-context { |
| | | position: absolute; |
| | | top: 40px; |
| | | left: 20px; |
| | | width: 350px; |
| | | } |
| | | .detail-context { |
| | | position: absolute; |
| | | top: 40px; |
| | | left: 20px; |
| | | width: 350px; |
| | | } |
| | | |
| | | .detail-item { |
| | | height: 23px; |
| | | margin-top: 15px; |
| | | margin-left: 10px; |
| | | } |
| | | .detail-name { |
| | | float: left; |
| | | font-weight: 700; |
| | | color: #94e0c4; |
| | | } |
| | | .detail-item { |
| | | height: 23px; |
| | | margin-top: 15px; |
| | | margin-left: 10px; |
| | | } |
| | | |
| | | .detail-value { |
| | | float: left; |
| | | color: #e1eee9; |
| | | } |
| | | .detail-name { |
| | | float: left; |
| | | font-weight: 700; |
| | | color: #94e0c4; |
| | | } |
| | | |
| | | .detail-btn { |
| | | background: url("@/assets/img/tools/messagebtn.png") no-repeat; |
| | | position: absolute; |
| | | bottom: 60px; |
| | | right: 60px; |
| | | width: 105px; |
| | | height: 26px; |
| | | text-align: center; |
| | | color: #fff; |
| | | cursor: pointer; |
| | | } |
| | | .detail-value { |
| | | float: left; |
| | | color: #e1eee9; |
| | | } |
| | | |
| | | .detail-btn { |
| | | background: url("@/assets/img/tools/messagebtn.png") no-repeat; |
| | | position: absolute; |
| | | bottom: 60px; |
| | | right: 60px; |
| | | width: 105px; |
| | | height: 26px; |
| | | text-align: center; |
| | | color: #fff; |
| | | cursor: pointer; |
| | | } |
| | | </style> |
| | |
| | | |
| | | <style lang="less" scoped> |
| | | .legend-container { |
| | | padding: 1rem; |
| | | padding: 0.8rem; |
| | | border: 1px solid #ddd; |
| | | border-radius: 8px; |
| | | max-width: 100%; |
| | |
| | | } |
| | | |
| | | .legend-title { |
| | | margin-bottom: 8px; |
| | | width: 100%; |
| | | text-align: center; |
| | | letter-spacing: 2px; |
| | |
| | | } |
| | | |
| | | .legend-color-box { |
| | | width: 60px; |
| | | height: 10px; |
| | | width: 4rem; |
| | | height: 1rem; |
| | | margin-right: 0.5rem; |
| | | margin-left: 0.5rem; |
| | | display: inline-block; |
| | | } |
| | | |
| | |
| | | <el-table-column prop="r" label="半径(r)"></el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <template #footer> |
| | | <!-- <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="dialogVisible = false">关 闭</el-button> |
| | | </span> |
| | | </template> |
| | | </template> --> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | colorRender, // 控制是否启用颜色渲染 |
| | | }); |
| | | |
| | | console.log(`Water simulation started with baseUrl: ${baseUrl}, interval: ${interval}ms, colorRender: ${colorRender}`); |
| | | console.log(`仿真模拟参数: 请求路径 ${baseUrl}, 帧间间隔 ${interval}ms, 是否开启专题渲染 ${colorRender}`); |
| | | } |
| | | /** |
| | | * 初始化水体模拟视图 |
| | |
| | | }, |
| | | }; |
| | | viewer.scene.camera.flyTo(view); |
| | | console.log("Camera view initialized for water simulation."); |
| | | // console.log("Camera view initialized for water simulation."); |
| | | } |
| | | |
| | | /** |
| | |
| | | export function pauseWaterSimulation() { |
| | | if (water) { |
| | | water.pause(); |
| | | console.log("Water simulation paused."); |
| | | console.log("暂停仿真"); |
| | | } else { |
| | | console.warn("No water simulation to pause."); |
| | | } |
| | |
| | | export function resumeWaterSimulation() { |
| | | if (water) { |
| | | water.resume(); |
| | | console.log("Water simulation resumed."); |
| | | console.log("继续仿真"); |
| | | } else { |
| | | console.warn("No water simulation to resume."); |
| | | } |
| | |
| | | console.warn("No timestamps available for water simulation."); |
| | | return; |
| | | } |
| | | |
| | | const idx = Math.floor(Math.random() * imageList.length); |
| | | console.log(`Jumping to timestamp: count:[${imageList.length}], index:[${closestIndex}]`); |
| | | // const idx = Math.floor(Math.random() * imageList.length); //随机索引跳转,实际中用不到,只用作演示 |
| | | // console.log(`Jumping to timestamp: count:[${imageList.length}], index:[${closestIndex}]`); |
| | | water.setTime(imageList[closestIndex]); |
| | | } else { |
| | | console.warn("No water simulation to set time for."); |
| | |
| | | export function toggleWaterColorRender(enabled) { |
| | | if (water) { |
| | | water.colorRender = enabled; |
| | | console.log(`Water color render set to: ${enabled}`); |
| | | console.log(`是否开启专题渲染 ${enabled}`); |
| | | } else { |
| | | console.warn("No water simulation to toggle color rendering."); |
| | | } |
| | |
| | | clearTrailLine(); |
| | | removeEmergencyPoints(); |
| | | removeDataSources(); |
| | | showWaterSimulate.value = false; |
| | | setTimeout(() => { |
| | | showWaterSimulate.value = false; |
| | | isDynamicMode.value = false; |
| | | // 清除威胁对象表格内容 |
| | | EventBus.emit("reset-table"); |