Newer
Older
urbanLifeline_YanAn / src / views / oneMap / FloodStuationReview / sqhgBottomBox.vue
@jimengfei jimengfei on 17 Oct 21 KB updata
<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>
  <!-- 降雨效果 -->
    <CanvasRain v-if="showRainFlow"></CanvasRain>
</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();
// 降雨效果
import CanvasRain from '@/views/oneMap/cityGK/canvasRain.vue'; //降雨效果
// 面板内容展开收起控制
const props = defineProps({
  checkTime: {
    type: String,
  },
});
// 降雨效果
const showRainFlow = ref(false);
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: 'rgb(38, 129, 240,1)' },
    { value: '5-16', color: 'rgba(222,230,0,1)' },
    { value: '16-25', color: 'rgba(255,184,15,1)' },
    { value: '>25', color: 'rgb(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;
    // showRainFlow.value = false;
  } else {
    runTime = 3000;
    // showRainFlow.value = true;
  }

  runDayInterval.value = setTimeout(() => {
    stepNum.value++;
    if (stepNum.value <= 24) {
      setRainImage(stepNum.value - 1);
      // 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;
  // newfiberMapbox.map.removeLayer('canvas-layer0');
  // newfiberMapbox.map.removeSource('canvas-source0');
  hoursList.value.activeIndex = stepNum.value;
  clearInterval(runDayInterval.value);
  if (runDayInterval.value) {
    runDayInterval.value = null;
    refresh.value = Math.random();
  }
  // if (newfiberMapbox.map.getLayer('canvas-layer0')) {
  //   newfiberMapbox.map.removeLayer('canvas-layer0');
  //   newfiberMapbox.map.removeSource('canvas-source0');
  // }
}

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 = 250 || 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 colorScale = [
  { value: '0', color: 'rgba(7, 213, 118, 0)' },
  { value: '0.2', color: 'rgb(38, 129, 240,.7)' },
  { value: '5', color: 'rgba(222,230,0,0.7)' },
  { value: '16', color: 'rgba(255,184,15,0.7)' },
  { value: '25', color: 'rgb(255, 26, 26,.7)' },
  { value: '250', color: 'rgb(255, 26, 26,.7)' },
];
let imageFiles = [];
let canvas = [];
let plot = null;
const initRainImage = async imagesList => {
  console.log('imagesList', 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]);
};
initRainImage(images);

watch(
  () => props.checkTime,
  val => {
    if (val != '') {
      hgEndActive.value = '';
      emptyRun();
      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>