<template> <!-- 汛情回顾状态框 --> <div class="rainMapLeng flex flex-align-center" v-if="showRainLegend"> <div class="flex flex-align-center" v-for="i in showRainList" :key="i"> <span :style="{ background: i.color }"></span>{{ i.value }} </div> </div> <div class="timeList"> <div class="colorRadio flex"> <div class="btn blue flex flex-align-center"> <span></span> <div>小雨</div> </div> <div class="btn yellow flex flex-align-center"> <span></span> <div>中雨</div> </div> <div class="btn orange flex flex-align-center"> <span></span> <div>大雨</div> </div> <div class="btn read flex flex-align-center"> <span></span> <div>暴雨</div> </div> </div> <div class="rainList flex"> 请选择最大雨强 <ul class="flex"> <li @click="changeHourTime(i.key)" :class="hgEndActive == i.key ? 'active' : ''" v-for="i in hgEngList" :key="i.key"> {{ i.name }} </li> </ul> </div> </div> <div class="timeScheduleBox flex flex-align-center flex-justcontent-spacebetween"> <div class="playBtn" @click="(hgEngPlay = !hgEngPlay), runDayTime()"> <img v-if="hgEngPlay" src="@/assets/images/fhpl/hgp2.png" /><img v-else src="@/assets/images/fhpl/hgp1.png" /> </div> <div class="playBg"><div class="playIn" :style="{ width: stepLin }"></div></div> </div> <div class="timeScheduleBox flex flex-justcontent-end"> <ul class="playRadio"> <li v-for="(k, i) in hoursScale" :key="i" :class="{ blue: (k.weather == '小雨' && i < stepNum) || (k.weather == '小雨' && k.chuse), yellow: (k.weather == '中雨' && i < stepNum) || (k.weather == '中雨' && k.chuse), orange: (k.weather == '大雨' && i < stepNum) || (k.weather == '大雨' && k.chuse), read: (i < stepNum && (k.weather == '暴雨' || k.weather == '大暴雨' || k.weather == '特大暴雨')) || ((k.weather == '暴雨' || k.weather == '大暴雨' || k.weather == '特大暴雨') && k.chuse), }" > <div>{{ k.time }}</div> </li> </ul> </div> <div class="timeChart"> <ChartLs :echartData="hoursList" :refresh="refresh" /> </div> </template> <script setup> import * as hsApi from '@/api/hsApi.js'; import { ref, reactive, toRefs, onMounted, onBeforeUnmount } from 'vue'; import ChartLs from '@/views/oneMap/Echarts/ChartLs.vue'; const { proxy } = getCurrentInstance(); // 面板内容展开收起控制 const props = defineProps({ checkTime: { type: String, }, }); let hgEngPlay = ref(false); let stepLin = ref('0'); let refresh = ref(0); let hgEndActive = ref(''); let showRainList = ref([]); let hoursList = ref({}); let hoursScale = ref([]); let stepNum = ref(0); const showRainLegend = ref(false); const images = [ 'https://server1.wh-nf.cn:6082/tif/0819_0.tif', 'https://server1.wh-nf.cn:6082/tif/0819_1.tif', 'https://server1.wh-nf.cn:6082/tif/0819_2.tif', 'https://server1.wh-nf.cn:6082/tif/0819_3.tif', 'https://server1.wh-nf.cn:6082/tif/0819_4.tif', 'https://server1.wh-nf.cn:6082/tif/0819_5.tif', 'https://server1.wh-nf.cn:6082/tif/0819_6.tif', 'https://server1.wh-nf.cn:6082/tif/0819_7.tif', 'https://server1.wh-nf.cn:6082/tif/0819_8.tif', 'https://server1.wh-nf.cn:6082/tif/0819_9.tif', 'https://server1.wh-nf.cn:6082/tif/0819_10.tif', 'https://server1.wh-nf.cn:6082/tif/0819_11.tif', 'https://server1.wh-nf.cn:6082/tif/0819_12.tif', 'https://server1.wh-nf.cn:6082/tif/0819_13.tif', 'https://server1.wh-nf.cn:6082/tif/0819_14.tif', 'https://server1.wh-nf.cn:6082/tif/0819_15.tif', 'https://server1.wh-nf.cn:6082/tif/0819_16.tif', 'https://server1.wh-nf.cn:6082/tif/0819_17.tif', 'https://server1.wh-nf.cn:6082/tif/0819_18.tif', 'https://server1.wh-nf.cn:6082/tif/0819_19.tif', 'https://server1.wh-nf.cn:6082/tif/0819_20.tif', 'https://server1.wh-nf.cn:6082/tif/0819_21.tif', 'https://server1.wh-nf.cn:6082/tif/0819_22.tif', 'https://server1.wh-nf.cn:6082/tif/0819_23.tif', ]; const ranLeng = [ [ { value: '0-0.2', color: 'rgba(7, 213, 118, 0)' }, { value: '0.2-5', color: 'rgba(7, 213, 118, 1)' }, { value: '5-25', color: 'rgba(38, 129, 240,1)' }, { value: '>25', color: 'rgba(255, 26, 26, 1)' }, ], [ { value: '0-5', color: 'rgba(7, 213, 118, 0)' }, { value: '5-15', color: 'rgba(7, 213, 118, 1)' }, { value: '15-30', color: 'rgba(38, 129, 240,1)' }, { value: '30-70', color: 'rgba(247, 223, 56, 1)' }, { value: '70-140', color: 'rgba(230, 85, 41, 1)' }, { value: '>140', color: 'rgba(255, 26, 26, 1)' }, ], [ { value: '0-5', color: 'rgba(7, 213, 118, 0)' }, { value: '5-15', color: 'rgba(7, 213, 118, 1)' }, { value: '15-30', color: 'rgba(38, 129, 240,1)' }, { value: '30-70', color: 'rgba(247, 223, 56, 1)' }, { value: '70-140', color: 'rgba(230, 85, 41, 1)' }, { value: '>140', color: 'rgba(255, 26, 26, 1)' }, ], [ { value: '0-10', color: 'rgba(7, 213, 118, 0)' }, { value: '10-25', color: 'rgba(7, 213, 118, 1)' }, { value: '25-50', color: 'rgba(38, 129, 240,1)' }, { value: '50-100', color: 'rgba(247, 223, 56, 1)' }, { value: '100-250', color: 'rgba(230, 85, 41, 1)' }, { value: '>250', color: 'rgba(255, 26, 26, 1)' }, ], ]; const hgEngList = [ { key: 1, name: '1小时' }, { key: 3, name: '3小时' }, { key: 12, name: '12小时' }, { key: 24, name: '24小时' }, ]; //获取底部数据 function getTimeData() { hsApi.rainMapDataBack({ time: props.checkTime }).then(res => { if (res.code == 200) { hoursList.value = res.data; hoursList.value.activeIndex = 0; let array = []; let list = JSON.parse(JSON.stringify(hoursList.value.rainTrend)); list.forEach((e, i) => { let obj = { weather: e, time: proxy.moment(hoursList.value.date[i]).format('H'), rain: hoursList.value.history[i], chuse: false, }; array.push(obj); }); hoursScale.value = array; refresh.value = Math.random(); hgEngPlay.value = false; } }); } let runDayInterval = ref(); function runDayTime() { hgEndActive.value = ''; showRainLegend.value = true; showRainList.value = ranLeng[0]; hoursScale.value.forEach(e => { e.chuse = false; }); if (hgEngPlay.value) { // newfiberMap.setCenter({ // "roll": 0, // "pitch": -89.87733174015287, // "heading": 360, // "lng": 114.30934084478585, // "lat": 30.44275262912909, // "zoom": 112193.80415470112 // }); newfiberMapbox.map.setZoom(12); timeLoop(); } else { hgEngPlay.value = false; clearInterval(runDayInterval.value); } } function timeLoop() { let runTime = 500; if (hoursList.value.rainTrend[Number(stepNum.value)] == '无雨') { runTime = 2000; } else { runTime = 3000; } runDayInterval.value = setTimeout(() => { stepNum.value++; if (stepNum.value <= 24) { initRainImage([images[stepNum.value]]); // NewFiberMapUtils.disposeRainfall(hoursList.value.rainTrend[Number(stepNum.value)-1]) stepLin.value = `${stepNum.value * 4.1666}%`; let levels = ranLeng[0].map((i, idx) => ({ ...i, value: Number(i.value.split('-')[0]) })); // console.log('stepNum.value',stepNum.value - 1); // console.log('levels',levels.map(i => i.value)); // console.log('dataas',hoursList.value.resultList[Number(stepNum.value)-1].map(i => i.value)); // NewFiberMapUtils.getKringImg(0, true, {data:hoursList.value.resultList[Number(stepNum.value)-1],code:200}, newfiberMap, levels); timeLoop(); } else { emptyRun(); } changeChartData(); }, runTime); } function emptyRun() { stepLin.value = '0%'; stepNum.value = 0; hgEngPlay.value = false; showRainLegend.value = false; // NewFiberMapUtils.disposeRainfall('') // newfiberMap.setLayersVisible(["krigingImage"],false) hoursList.value.activeIndex = stepNum.value; clearInterval(runDayInterval.value); if (runDayInterval.value) { runDayInterval.value = null; refresh.value = Math.random(); } } function changeChartData() { hoursList.value.activeIndex = stepNum.value; refresh.value = Math.random(); } function changeHourTime(num) { hgEndActive.value = num; emptyRun(); showRainLegend.value = true; showRainList.value = num == 1 ? ranLeng[0] : num == 3 ? ranLeng[1] : num == 12 ? ranLeng[2] : ranLeng[3]; let parms = { type: num, time: props.checkTime, }; hsApi.rainMapDataListBack(parms).then(res => { if (res.code == 200) { // 24小时前端处理 if (hgEndActive.value == 24) { hoursScale.value.forEach(e => { e.chuse = true; }); } else { hoursScale.value.forEach(e => { e.chuse = false; }); res.data.max.forEach(s => { hoursScale.value.forEach(e => { if (e.time == proxy.moment(s).format('H')) { e.chuse = true; } }); }); } // newfiberMap.setCenter({ // "roll": 0, // "pitch": -89.87733174015287, // "heading": 360, // "lng": 114.30934084478585, // "lat": 30.44275262912909, // "zoom": 112193.80415470112 // }); // NewFiberMapUtils.disposeRainfall(res.data.weather) // let levels = ranLeng[{1:0,3:1,12:2,24:3}[num]].map((i,idx) => ({...i,value:Number(i.value.split('-')[0])})); // NewFiberMapUtils.getKringImg(num, true, {data:res.data.resultList,code:200}, newfiberMap, levels); } }); } async function urlToFile(url, fileName) { // 使用 fetch 获取图片并转换为 Blob const response = await fetch(url); const blob = await response.blob(); // 将 Blob 转换为 File 对象 const file = new File([blob], fileName, { type: blob.type }); return file; } const createCanvas = id => { let canvas = document.createElement('canvas'); canvas.id = 'canvas' + id; canvas.style.display = 'none'; document.body.append(canvas); return canvas; }; const createPlot = async (e, canvas) => { var tif = await GeoTIFF.fromArrayBuffer(e.target.result); var tifImg = await tif.getImage(); var readRasters = await tifImg.readRasters(); plot == null && (plot = new plotty.plot({ canvas, data: readRasters[0], width: tifImg.getWidth(), height: tifImg.getHeight(), domain: [0, 256], colorScale: 'mycolorscale', })); plot.setData(readRasters[0], tifImg.getWidth(), tifImg.getHeight()); plot.render(); }; const createCanvasLayer = (canvasId, i, bbox) => { bbox = [ [bbox[0], bbox[3]], [bbox[2], bbox[3]], [bbox[2], bbox[1]], [bbox[0], bbox[1]], ]; if (newfiberMapbox.map.getLayer('canvas-layer' + i)) { newfiberMapbox.map.removeLayer('canvas-layer' + i); newfiberMapbox.map.removeSource('canvas-source' + i); } newfiberMapbox.map.addSource('canvas-source' + i, { type: 'canvas', canvas: canvasId, coordinates: bbox, animate: true, }); newfiberMapbox.map.addLayer({ id: 'canvas-layer' + i, type: 'raster', source: 'canvas-source' + i, }); newfiberMapbox.map.moveLayer('canvas-layer' + i); }; const plotInit = (colorScale = colorScale) => { const minVal = colorScale[0].value; const maxVal = colorScale[colorScale.length - 1].value; let color = colorScale.filter(i => Number(i.value) / maxVal <= 1); if (color[color.length - 1].value / maxVal < 1) color.push({ value: maxVal, color: colorScale[color.length].color }); plotty.addColorScale( 'mycolorscale', color.map(i => i.color), color.map(i => (i.value / maxVal).toFixed(5)) ); }; let colorScale = [ { value: '0', color: 'rgba(7, 213, 118, 0)' }, { value: '0.1', color: 'rgba(7, 213, 118, 0)' }, { value: '5', color: 'rgba(7, 213, 118, 1)' }, { value: '15', color: 'rgba(38, 129, 240,1)' }, { value: '30', color: 'rgba(247, 223, 56, 1)' }, { value: '70', color: 'rgba(230, 85, 41, 1)' }, { value: '140', color: 'rgba(255, 26, 26, 1)' }, ]; let imageFiles = []; let canvas = []; let plot = null; const initRainImage = async imagesList => { imageFiles = await Promise.all(imagesList.map(url => urlToFile(url, _.last(_.split(url, '/'))))); canvas = createCanvas(0); plotInit(colorScale); createCanvasLayer(canvas.id, 0, [109.36903069276376, 36.53005543707354, 109.62694602722712, 36.7105574823517]); setRainImage(0); // let i = 0; // let interval = setInterval(() => { // if (i >= imageFiles.length) i = 0; // setRainImage(i++); // }, 1000); }; const setRainImage = index => { var reader = new FileReader(); reader.onload = e => createPlot(e, canvas); reader.readAsArrayBuffer(imageFiles[index]); }; watch( () => props.checkTime, (val) => { if(val!=''){ getTimeData(); } }, { immediate: true } ); onBeforeUnmount(() => { emptyRun(); if (newfiberMapbox.map.getLayer('canvas-layer0')) { newfiberMapbox.map.removeLayer('canvas-layer0'); newfiberMapbox.map.removeSource('canvas-source0'); } newfiberMapbox.map.setZoom(13); }); </script> <style lang="scss" scoped> .rainMapLeng { position: absolute; right: 0px; bottom: 270px; background: linear-gradient(0deg, rgba(0, 93, 114, 0.8) 0%, rgba(0, 93, 114, 0.8) 100%); height: 40px; div { margin: 0 10px; font-size: 14px; color: #fff; cursor: pointer; &:nth-child(1) { span { border: 1px solid #fff; } } span { display: block; width: 16px; height: 16px; margin-right: 4px; border-radius: 4px; } } } .timeList { padding: 12px 20px 10px; overflow: hidden; .colorRadio { float: left; .btn { margin-right: 20px; span { width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; } div { width: 42px; line-height: 22px; border: 1px solid rgba(0, 191, 253, 0); border-radius: 4px; text-align: center; font-weight: 400; font-size: 14px; } &.blue { span { background: rgba(0, 191, 253, 1); } div { border-color: rgba(0, 191, 253, 1); color: rgba(0, 191, 253, 1); background: linear-gradient(0deg, #08324f 0%, #0b3360 100%); } } &.yellow { span { background: rgba(222, 230, 0, 1); } div { border-color: rgba(222, 230, 0, 1); color: rgba(222, 230, 0, 1); background: linear-gradient(0deg, #4f4b06 0%, #4f4e06 98%); } } &.orange { span { background: rgba(255, 184, 15, 1); } div { border-color: rgba(255, 184, 15, 1); color: rgba(255, 184, 15, 1); background: linear-gradient(0deg, #4f3d06 0%, #4f3d06 98%); } } &.read { span { background: rgba(255, 26, 26, 1); } div { border-color: rgba(255, 26, 26, 1); color: rgba(255, 26, 26, 1); background: linear-gradient(0deg, #3e0808 0%, #420808 100%); } } } } } .playIn { height: 100%; background: linear-gradient(90deg, #1890ff, #1ee7e7); border-radius: 6px; position: relative; overflow: hidden; &::before { content: ''; position: absolute; right: 0; top: 0; left: 0; height: 12px; border-radius: 6px; background: url(@/assets/images/fxhg/hgpx.png) repeat-x; background-size: 16px 12px; } &::after { content: ''; position: absolute; right: 0; top: 0; width: 72px; height: 12px; background: url(@/assets/images/fxhg/hgpr.png) no-repeat; background-size: 100% 100%; } } .rainList { float: right; line-height: 24px; font-size: 14px; font-weight: 400; color: #ffffff; ul { margin: 0; padding: 0; list-style: none; li { width: 54px; text-align: center; background: #00344fff; margin-left: 10px; cursor: pointer; &.active { background: #002d44; border-radius: 2px; border: 1px solid #1cf5fc; } } } } .playRadio { display: flex; width: calc(100% - 30px); padding: 0; margin: 0; padding-top: 34px; position: relative; li { width: 4.1666%; padding-top: 10px; display: flex; justify-content: center; position: relative; overflow: hidden; &::before { content: ''; position: absolute; right: 0; top: 0; left: 0; height: 12px; border-radius: 6px; // background: url(@/assets/images/oneMap/hgpx.png) repeat-x; background-size: 16px 12px; } &::after { content: ''; position: absolute; right: 0; top: 0; width: 72px; height: 12px; // background: url(@/assets/images/oneMap/hgpr.png) no-repeat; background-size: 100% 100%; } } .rainList { float: right; line-height: 24px; font-size: 14px; font-weight: 400; color: #ffffff; ul { margin: 0; padding: 0; list-style: none; li { width: 54px; text-align: center; background: #00344fff; margin-left: 10px; cursor: pointer; &.active { background: #002d44; border-radius: 2px; border: 1px solid #1cf5fc; } } } } } .timeScheduleBox { padding: 0 20px; overflow: hidden; .playBtn { width: 22px; height: 22px; cursor: pointer; img { width: 100%; height: 100%; } } .playBg { width: calc(100% - 30px); height: 18px; background: rgba(77, 149, 217, 0.15); border-radius: 9px; padding: 3px; overflow: hidden; } .playIn { height: 100%; background: linear-gradient(90deg, #1890ff, #1ee7e7); border-radius: 6px; position: relative; overflow: hidden; &::before { content: ''; position: absolute; right: 0; top: 0; left: 0; height: 12px; border-radius: 6px; // background: url(@/assets/images/oneMap/hgpx.png) repeat-x; background-size: 16px 12px; } &::after { content: ''; position: absolute; right: 0; top: 0; width: 72px; height: 12px; // background: url(@/assets/images/oneMap/hgpr.png) no-repeat; background-size: 100% 100%; } } .playRadio { display: flex; width: calc(100% - 30px); padding-top: 34px; position: relative; li { width: 4.1666%; padding-top: 10px; display: flex; justify-content: center; position: relative; &::before { content: ''; position: absolute; width: 2px; height: 7px; background: #799fc8; top: -7px; left: 50%; margin-left: -1px; } &::after { content: ''; position: absolute; width: 8px; height: 8px; background: #799fc8; top: -20px; left: 50%; margin-left: -4px; border-radius: 50%; display: none; } div { width: 22px; line-height: 22px; background: #799fc8; font-family: DINPro; font-weight: 400; font-size: 16px; color: #ffffff; text-align: center; } &.blue { &::before { background: #00bffd; } &::after { background: #00bffd; display: block; } div { background: #00bffd; } } &.yellow { &::before { background: #dee600; } &::after { background: #dee600; display: block; } div { background: #dee600; } } &.orange { &::before { background: #ffb80f; } &::after { background: #ffb80f; display: block; } div { background: #ffb80f; } } &.read { &::before { background: #ff1a1a; } &::after { background: #ff1a1a; display: block; } div { background: #ff1a1a; } } } &::before { content: ''; position: absolute; right: 0; top: 34px; left: 0; height: 2px; background: #799fc8; } } } .timeChart { height: calc(100% - 140px); overflow: hidden; // background: red; } </style>