<template> <!-- 排水防涝 态势研判 预报预警 --> <div class="publicContainer lateWarn"> <!-- gis 地图 --> <!-- <LateWarnMap></LateWarnMap>--> <MapBox :initJson="`/static/libs/mapbox/style/lateWarn.json`" :loadCallback="mapInit"></MapBox> <!-- 右侧具体数据展示 --> <div :class="['zksqImg', ifExpand ? 'leftZk' : 'leftSq']" @click="ifExpand = !ifExpand"></div> <div :class="['rightWarn', 'animate__animated', ifExpand ? 'animate__bounceInRight' : 'animate__bounceOutRight']"> <!-- 预报降雨过程线 --> <div class="partCont"> <div class="mapTitle">未来2h降雨预报</div> <div class="chartDom"> <div id="chartOneYC"></div> </div> </div> <!-- 积水面积趋势 --> <div class="partCont"> <div class="mapTitle" v-if="searchVal == 'depth'">积水面积趋势</div> <div class="mapTitle" v-if="searchVal == 'filling'">满管过程线</div> <div class="chartDom" v-loading="areaLoading"> <div id="chartTwoYC"></div> </div> </div> <!-- 积水风险占比 --> <div class="partCont" v-show="searchVal == 'depth'"> <div class="mapTitle">积水风险</div> <div class="chartDom"> <el-table ref="tableArea" :data="tableData" v-loading="tableLoading" style="width: 100%; margin: 5px 0 10px 0" height="240" :empty-text="'暂无风险'" > <el-table-column prop="riskLevel" label="积水风险级别"> <template #default="scope"> {{ scope.row.riskLevel == 'high' ? '高风险' : scope.row.riskLevel == 'middle' ? '中风险' : scope.row.riskLevel == 'low' ? '低风险' : '--' }} </template> </el-table-column> <el-table-column prop="avgZ" label="平均水深(m)" /> <el-table-column prop="waterloggingArea" label="积水面积(k㎡)" /> </el-table> </div> </div> </div> <!-- 图例颜色,不同模型不同图例内容 --> <div :class="['mapLegendColor', ifExpand ? 'leftZkL' : 'leftSq']" v-if="searchVal == 'depth'"> <p class="title">最大积水深度(米)</p> <p><span class="info"></span> 0.05-0.15</p> <p><span class="primary"></span> 0.15-0.3</p> <p><span class="yellow"></span> 0.3-0.5</p> <p><span class="pink"></span> 0.5-1.0</p> <p><span class="red"></span> 大于1.0</p> </div> <div :class="['mapLegendColor', ifExpand ? 'leftZkL' : 'leftSq']" v-if="searchVal == 'filling'"> <p class="title">管网充满度</p> <p><span class="green"></span>未充满</p> <p><span class="red"></span>满管</p> </div> <!-- 中间操作 --> <div class="centerWarn"> <el-select v-model="searchVal" placeholder="请选择模拟对象" @change="changeObj"> <el-option v-for="item in caseType" :key="item.value" :label="item.label" :value="item.value" /> </el-select> <!-- <el-select v-model="searchValSpeed" placeholder="倍数" style="width: 80px; margin-left: 10px" @change="changeBS"> <el-option v-for="item in bsType" :key="item.value" :label="item.label" :value="item.value" /> </el-select> --> <!-- <TimeLine :list="processVal" @getTimeLineIndex="getTimeLineIndex"> </TimeLine> --> <el-progress :stroke-width="20" :percentage="processVal" status="success" :text-inside="true"></el-progress> <el-button type="warning" @click="startImitate" v-if="ifStart" :disabled="isdisabled">开始</el-button> <el-button type="warning" @click="stopImitate" v-else :disabled="isdisabled">暂停</el-button> </div> </div> </template> <script setup name="lateWarn"> import TimeLine from '@/components/Map/TimeLine.vue'; import MapBox from '@/views/gisMapPage/gisMapBox1'; //gis地图 import chartOption from './riskChart'; import * as echarts from 'echarts'; import { selectYuBaoProcessLine, getYbRainfallByHourEnum, moduleGeometryData } from '@/api/floodSys/floodYP'; import { waterloggingRisk } from '@/api/floodSys/oneMap'; import xiaoganCityBoundary from '@/assets/geojson/xiaoganCityBoundary.json'; const searchVal = ref('depth'); const searchValSpeed = ref('1'); const caseType = ref([ { value: 'depth', label: '积水风险' }, { value: 'filling', label: '管网排水能力' }, ]); const tableData = ref([]); const tableLoading = ref(true); const timer = ref(null); const ifStart = ref(true); const processVal = ref(0); const ifExpand = ref(true); const gisJsonData = ref({}); const features = ref([]); const featureStep = ref(0); const timerChart = ref(null); //内涝风险评估 地图内涝 const gisParams = ref({}); const areaLoading = ref(true); const isdisabled = ref(false); //根据步长更换颜色 const changeFeatureColor = step => { features.value.forEach(feature => { let lineColor = feature.extData[step] < 1 ? '#47E44E' : '#DD3737'; feature.setColor(lineColor); }); }; const getTimeLineIndex = index => { // console.log('getTimeLineIndex',index); if (!(index % 100 == 0)) return; canvasLayer.next(980); }; //内涝风险评估 地图内涝渲染模拟 const gisModuleData = () => { moduleGeometryData(gisParams.value).then(res => { // debugger gisJsonData.value = res.data.result; let maxPoint = res.data.maxPoint.split(','); let minPoint = res.data.minPoint.split(','); if (!!gisJsonData.value.length && gisJsonData.value.length > 1) { isdisabled.value = false; !!newfiberMapbox.map.getLayer('lateWarnImage') && newfiberMapbox.map.removeLayer('lateWarnImage'); !!newfiberMapbox.map.getSource('lateWarnImage') && newfiberMapbox.map.removeSource('lateWarnImage'); addImageLayer(minPoint, maxPoint); } else { isdisabled.value = true; !!newfiberMapbox.map.getLayer('lateWarnImage') && newfiberMapbox.map.removeLayer('lateWarnImage'); !!newfiberMapbox.map.getSource('lateWarnImage') && newfiberMapbox.map.removeSource('lateWarnImage'); } }); }; //添加模型图 const addImageLayer = (minPoint, maxPoint) => { !!!newfiberMapbox.map.getSource('lateWarnImage') && newfiberMapbox.map.addSource('lateWarnImage', { type: 'image', url: gisJsonData.value[gisJsonData.value.length - 1].url, coordinates: [ [Number(minPoint[0]), Number(maxPoint[1])], [Number(maxPoint[0]), Number(maxPoint[1])], [Number(maxPoint[0]), Number(minPoint[1])], [Number(minPoint[0]), Number(minPoint[1])], ], }); !!!newfiberMapbox.map.getLayer('lateWarnImage') && newfiberMapbox.map.addLayer({ id: 'lateWarnImage', type: 'raster', source: 'lateWarnImage', paint: { 'raster-fade-duration': 0, }, }); }; // 预报降雨过程线 let chart1 = null; const initEchartsZS = async () => { chartOption.option22.xAxis[0].data = []; if (!!chart1) chart1.dispose(); chart1 = echarts.init(document.getElementById('chartOneYC')); getYbRainfallByHourEnum().then(res => { let datas = res.data; chartOption.option22.xAxis[0].data = datas.tsStr; chartOption.option22.series[0].data = datas.rainList; chartOption.option22.series[1].data = datas.rainCountList; chartOption.option22.graphic.invisible = datas.tsStr.length > 0; // 暂无数据 chart1.clear(); chart1.setOption(chartOption.option22); }); }; // 积水面积趋势 满管过程线 let chart2 = null; const initEchartsRain = async () => { areaLoading.value = true; chartOption.option11.xAxis[0].data = []; if (!!chart2) chart2.dispose(); chart2 = echarts.init(document.getElementById('chartTwoYC')); selectYuBaoProcessLine({ moduleTypeEnum: searchVal.value }).then(res => { let datas = res.data; if (Object.keys(datas).length == 0) { chartOption.option11.graphic.invisible = false; chartOption.option11.xAxis[0].data = []; chartOption.option11.series[0].data = []; chart2.clear(); chart2.setOption(chartOption.option11); areaLoading.value = false; } else { chartOption.option11.xAxis[0].data = datas.date; chartOption.option11.series[0].data = datas.data; chartOption.option11.yAxis[0].name = 'm'; chartOption.option11.graphic.invisible = datas.date.length > 0; // 暂无数据 chart2.clear(); chart2.setOption(chartOption.option11); areaLoading.value = false; chart2.dispatchAction({ type: 'showTip', seriesIndex: 0, dataIndex: 0, }); } }); }; // 积水风险占比 async function getWaterLogging() { tableLoading.value = true; let res = await waterloggingRisk(); if (res && res.code == 200) { tableData.value = res.data; tableLoading.value = false; } } // 选择不同模拟对象 function changeObj(val) { ifStart.value = true; stopTimer(); searchVal.value = val; gisParams.value = { category: 'duration', hours: '2h', rainFall: '', realTime: true, scenario: '', type: searchVal.value, ybTime: '', }; processVal.value = 0; featureStep.value = 0; // changeBS(); //开始模拟 gisModuleData(); //地图内涝渲染模拟 initEchartsRain(); initEchartsZS(); if (searchVal.value == 'depth') { getWaterLogging(); } } // 开始模拟 function startImitate() { ifStart.value = false; startTimer(); // 定时器开启 } // 定时器开启 function startTimer() { if (processVal.value == 100) processVal.value = 0; if (gisJsonData.value.length < 1) { return; } if (gisJsonData.value.length > 1) { let proStept = Math.round(100 / gisJsonData.value.length); timer.value = setInterval(() => { featureStep.value += 1; newfiberMapbox.map.ogcLayers.filter(i => i.newfiberId == 'newfiber-CanvasLayer')[0].next(1000 / searchValSpeed.value); newfiberMapbox.map .getSource('lateWarnImage') .updateImage({ url: gisJsonData.value[gisJsonData.value.length - 1 - featureStep.value].url }); processVal.value += proStept; // echarts动画 chart2.dispatchAction({ type: 'showTip', seriesIndex: 0, dataIndex: featureStep.value, }); let setp_play = `step${featureStep.value}`; if (processVal.value > 100) { processVal.value = 100; stopImitate(); return; } if (featureStep.value == gisJsonData.value.length - 1) { featureStep.value = 0; processVal.value = 100; stopImitate(); } changeFeatureColor(setp_play); }, 1000 / searchValSpeed.value); } else { timer.value = setInterval(() => { processVal.value += 100; if (processVal.value > 100) { processVal.value = 0; stopImitate(); } }, 1000); } } // 暂停模拟 function stopImitate() { ifStart.value = true; stopTimer(); } // 定时器清除 function stopTimer() { console.log('stop!!!!'); if (timer.value) { clearInterval(timer.value); } if (timerChart.value) { clearInterval(timerChart.value); } } //添加孝感城区边界 const addCityBoundary = () => { !newfiberMapbox.map.getSource('xiaoganCityBoundary') && newfiberMapbox.map.addSource('xiaoganCityBoundary', { type: 'geojson', data: xiaoganCityBoundary }); !newfiberMapbox.map.getLayer('xiaoganCityBoundary') && !newfiberMapbox.map.addLayer({ id: 'xiaoganCityBoundary', type: 'line', source: 'xiaoganCityBoundary', paint: { 'line-color': 'rgba(255, 175, 71,1)', 'line-width': 3, }, }); setTimeout(() => { newfiberMapbox.map.moveLayer('xiaoganWater', 'xiaoganCityBoundary'); }, 3000); }; const mapInit = () => { // addCityBoundary(); changeObj('depth'); }; onMounted(() => { // timer.value = setInterval(() => { // if (!!!newfiberMapbox) { // return; // } else { // addCityBoundary(); // changeObj('depth'); // clearInterval(timer.value); // } // }, 1000); }); onBeforeMount(() => { stopTimer(); }); </script> <style lang="scss"> @import '@/assets/styles/variables.module.scss'; .lateWarn { width: 100%; position: relative; height: 100%; .rightWarn { width: 400px; height: calc(100vh - 110px); background: $mainColor1; position: absolute; top: 30px; right: 30px; z-index: 99; padding: 10px; .partCont { .chartDom { width: 100%; height: calc(31vh - 50px); #chartOneYC, #chartTwoYC, #chartThreeYC { width: 400px; height: calc(31vh - 50px); } } } } .centerWarn { background: $mainColor1; box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3); border-radius: 8px; position: absolute; top: 30px; left: 50px; z-index: 99; padding: 10px; display: flex; align-items: center; width: 1000px; .el-select { width: 150px; } .el-progress { width: 730px; margin: 0px 15px; .el-progress__text span { font-size: 12px; } } } .leftZk { right: 430px; } .leftZkL { right: 435px; } .leftSq { right: 20px; } .zksqImg { width: 16px; height: 147px; background: url('@/assets/newImgs/down.png'); background-size: 100% 100%; transform: rotate(180deg); position: absolute; top: 340px; z-index: 99; cursor: pointer; transition: 0.5s ease-in-out; } } </style>