Newer
Older
KaiFengPC / src / views / spongePerformance / waterlogging / prevention / index.vue
@zhangdeliang zhangdeliang 7 days ago 20 KB update
<template>
  <!-- 示范期考核-内涝防治 -->
  <div class="assessmentPage">
    <el-tabs v-model="tabActive" @tab-click="changeTab" class="tabsContent">
      <el-tab-pane label="模型法" name="model"></el-tab-pane>
      <el-tab-pane label="监测法" name="monitor"></el-tab-pane>
    </el-tabs>

    <!-- gis地图 -->
    <MapBox :initJson="`/static/libs/mapbox/style/preventionSFQ.json`" l7=""></MapBox>

    <!-- 模型法 -->
    <div v-if="tabActive == 'model'">
      <div class="tuli">
        <div style="margin: 10px; font-size: 18px">图例</div>
        <div class="tuli_img">
          <img src="/2.jpg" alt="" />
          <div>内涝区域</div>
        </div>
      </div>
      <div class="content" style="width: 800px">
        <el-table
          ref="tableModal"
          :data="tableData"
          max-height="500"
          v-loading="tableLoading"
          @row-click="clickModal"
          highlight-current-row
        >
          <el-table-column label="考核年度" prop="year" />
          <el-table-column label="降雨重现期" prop="targetCxq" />
          <el-table-column label="设计雨量(mm)" prop="rainfall" />
          <el-table-column label="最大内涝面积(㎡)" prop="totalFloodArea" />
          <el-table-column label="占建成区比例(%)" prop="floodPercent" />
          <el-table-column label="目标(%)" prop="targetPercent" />
          <el-table-column label="达标情况" prop="isStandard">
            <template #default="{ row }">
              {{ row.isStandard === '1' ? '达标' : '未达标' }}
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>

    <!-- 监测法 -->
    <div v-if="tabActive == 'monitor'">
      <div class="tuli">
        <div style="margin: 10px; font-size: 18px">图例</div>
        <div class="tuli_img">
          <img src="/1.1.jpg" alt="" />
          <div>内涝点</div>
        </div>
      </div>

      <div class="content">
        <div class="selectTitle">
          <div class="name">监测法测算结果</div>
          <!-- <el-select v-model="currentYear" @change="changeMonitorYear" style="width: 100px" size="small">
            <el-option label="2021年" value="2021"></el-option>
            <el-option label="2022年" value="2022"></el-option>
            <el-option label="2023年" value="2023"></el-option>
          </el-select> -->
          <el-select v-model="currentYear" @change="changeMonitorYear" style="width: 100px" size="small">
            <el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value"></el-option>
          </el-select>
        </div>

        <PieChart :echartData="echartData" :title="`建成区面积\n${areaData}k㎡`" :refresh="refresh" class="chartHeight"></PieChart>

        <div class="selectTitle">
          <div class="name">内涝点监测感知情况</div>
          <el-popover placement="top-start" :width="80" trigger="hover">
            <template #reference> <img :src="getImageUrl('res.png', 'newImgs/HaiMianScreen')" alt="" /></template>
            <template #default>
              <div class="typeMap">内涝点积水评判标准:积水时长>30分钟且积水深度≥15cm</div>
            </template>
          </el-popover>
        </div>
        <el-table :data="tableDataNL" height="450" v-loading="tableLoadingNL">
          <el-table-column label="内涝点名称" prop="name" />
          <el-table-column label="积水时长(h)" prop="yearTotalHour" />
          <el-table-column label="积水深度(cm)" prop="yearMaxDepth" />
        </el-table>
      </div>
    </div>

    <div class="PopupWaterlogging" id="PopupWaterlogging" v-if="pipePopupShow">
      <div class="titleTop">
        <el-tabs class="PopupWaterloggingtabs">
          <el-tab-pane label="降雨过程线">
            <div class="allContent">
              <div>开始时间:{{ yearMaxStartTime }}</div>
              <div>结束时间:{{ yearMaxEndTime }}</div>
              <empty v-if="pipePopupdata" emptyText="暂无降雨数据" :width="100" :height="100" style="margin-top: 50px"></empty>
              <div id="chartPopupRain"></div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
      <div class="closePopup">
        <el-icon :size="18" @click="closePopup"><Close /></el-icon>
      </div>
    </div>
    <div class="mapLegendColor modelmapLegend" v-if="tabActive == 'model'">
      <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>
</template>
<script setup>
import MapBox from '@/views/gisMapPage/gisMapBox1'; //gis地图
import PieChart from '@/components/Echarts/pieChart.vue'; //饼图
import bus from '@/bus';
import { moduleFloodResult, monitorEvaluateResult } from '@/api/spongePerformance/prevention';
import { graphicReport } from '@/api/dataAnalysis/syntherticData';
import { getConfigKey } from '@/api/system/config'; //获取参数值
import chartOption from '@/components/Echarts/pieChart_1.js';
import * as echarts from 'echarts';
import { nextTick } from 'vue';
const pipePopupShow = ref(false);
const pipePopupdata = ref(false);
const { proxy } = getCurrentInstance();
const currentYear = ref('');
const yearList = ref([]);
const timer = ref(null);
const tabActive = ref('model');
const tableModal = ref(null);
const tableLoading = ref(false);
const tableData = ref([]);
const areaData = ref('');
const resultList = ref([]);
const waterEchart = shallowRef(null);
const yearMaxStartTime = ref('');
const yearMaxEndTime = ref('');
const stCodes = ref('');
const selectData = ref([]);
const selectCode = ref('');
const seleceName = ref('');
const unitName = ref('');
const propertyMonitorXList = ref([]);
const echartData = ref([
  { name: '内涝区域', value: 0 },
  { name: '未发生内涝', value: 0 },
]);
const refresh = ref(1);
const tableDataNL = ref([]);
const tableLoadingNL = ref(false);
const dataListNL = ref([]);

// 模型法数据获取
async function getModalData() {
  tableLoading.value = true;
  let res = await moduleFloodResult();
  if (res && res.code == 200) {
    tableData.value = res.data;
    if (Boolean(tableData.value.length)) {
      tableData.value.forEach(i => {
        i.targetCxq = i.targetCxq + '年一遇24h';
      });
    }
    tableModal.value.setCurrentRow(tableData.value[0], true); //表格默认第一个高亮选中
    resultList.value = tableData.value[0].resultList;
    let moduleGeojson = getFeatureGeojson(tableData.value[0].partitionList);
    let moduleBoundaryGeojson = getGeojsonBoundary(moduleGeojson);
    let modulelabelGeojson = getGeojsonCenter(moduleGeojson);
    //gis渲染内涝区域
    addModuleLayer(moduleGeojson, 'moduleFlood', '#95f204');
    addModuleBoundary(moduleBoundaryGeojson, 'moduleFloodBoundary');
    addGeojsonLable(modulelabelGeojson, 'moduleFloodlabel', '#ffffff');
  }
  tableLoading.value = false;
}
// 模型法表格点击
function clickModal(row) {
  resultList.value = row.resultList;
  let moduleGeojson = getFeatureGeojson(row.partitionList);
  let moduleBoundaryGeojson = getGeojsonBoundary(moduleGeojson);
  let modulelabelGeojson = getGeojsonCenter(moduleGeojson);
  //gis渲染内涝区域
  newfiberMapbox.map.getSource('moduleFlood').setData(moduleGeojson);
  newfiberMapbox.map.getSource('moduleFloodBoundary').setData(moduleBoundaryGeojson);
  newfiberMapbox.map.getSource('moduleFloodlabel').setData(modulelabelGeojson);
}
//获取geojson
const getFeatureGeojson = dataList => {
  let features = [];
  dataList.forEach(data => {
    let feature = turf.feature(Terraformer.WKT.parse(data.geometry), data);
    features.push(feature);
  });
  return {
    type: 'FeatureCollection',
    features: features,
  };
};
//获取geojson中心点
const getGeojsonCenter = geojson => {
  let features = [];
  geojson.features.forEach(element => {
    let center = turf.center(element.geometry);
    center.properties = element.properties;
    features.push(center);
  });
  return {
    type: 'FeatureCollection',
    features: features,
  };
};
//获取geojson边界
const getGeojsonBoundary = geojson => {
  let features = [];
  geojson.features.forEach(element => {
    let line = turf.polygonToLine(element.geometry);
    features.push(line);
  });
  return {
    type: 'FeatureCollection',
    features: features,
  };
};
//添加模型法地图
const addModuleLayer = (geojson, layerName, color) => {
  !newfiberMapbox.map.getSource(layerName) && newfiberMapbox.map.addSource(layerName, { type: 'geojson', data: geojson });
  !newfiberMapbox.map.getLayer(layerName) &&
    newfiberMapbox.map.addLayer({
      id: layerName,
      type: 'fill',
      source: layerName,
      paint: {
        'fill-color': '#95f204',
        'fill-opacity': 0.5,
      },
    });
};
const addModuleBoundary = (geojson, layerName) => {
  !newfiberMapbox.map.getSource(layerName) && newfiberMapbox.map.addSource(layerName, { type: 'geojson', data: geojson });
  !newfiberMapbox.map.getLayer(layerName) &&
    newfiberMapbox.map.addLayer({
      id: layerName,
      type: 'line',
      source: layerName,
      paint: {
        'line-color': '#95f204',
        'line-width': 3,
      },
    });
};
const addGeojsonLable = (geojson, layerName, color) => {
  !newfiberMapbox.map.getSource(layerName) && newfiberMapbox.map.addSource(layerName, { type: 'geojson', data: geojson });
  !newfiberMapbox.map.getLayer(layerName) &&
    !newfiberMapbox.map.addLayer({
      id: layerName,
      type: 'symbol',
      source: layerName,
      paint: {
        'text-color': geojson.features[0].properties.color ? ['get', 'color'] : color,
        'text-halo-color': 'rgba(0,0,0,1)',
        'text-halo-width': 2,
      },
      layout: {
        'text-allow-overlap': true,
        'text-field': ['get', 'partitionName'],
        'text-font': ['KlokanTech Noto Sans Regular'],
        'text-size': 16,
        'text-line-height': 3,
        'text-anchor': 'bottom',
        'text-max-width': 50,
        'text-offset': [0, -1],
      },
    });
};
// tab切换
function changeTab(e) {
  tabActive.value = e.props.name;
  if (tabActive.value == 'model') {
    bus.emit('removeMapDatas', ['error_zishui']);
    if (newfiberMapbox.map.getLayer('waterLoging')) {
      newfiberMapbox.map.removeLayer('waterLoging');
      newfiberMapbox.map.removeSource('waterLoging');
    }
    newfiberMapbox.popupService.popups.forEach(popup => {
      nextTick(() => {
        newfiberMapbox.removePopup(popup);
      });
    });
    getModalData();
  } else {
    getMonitorData();
    if (newfiberMapbox.map.getLayer('moduleFlood')) {
      newfiberMapbox.map.removeLayer('moduleFlood');
      newfiberMapbox.map.removeLayer('moduleFloodBoundary');
      newfiberMapbox.map.removeLayer('moduleFloodlabel');
      newfiberMapbox.map.removeSource('moduleFlood');
      newfiberMapbox.map.removeSource('moduleFloodBoundary');
      newfiberMapbox.map.removeSource('moduleFloodlabel');
    }
  }
}

// 获取监测法数据
async function getMonitorData() {
  tableLoadingNL.value = true;
  let res = await monitorEvaluateResult();
  if (res && res.code == 200) {
    dataListNL.value = res.data;
    yearList.value = [];
    if (dataListNL.value.length == 0) return;
    dataListNL.value.map(item => {
      yearList.value.push({
        value: item.year,
        label: item.year + '年',
      });
    });
    console.log(yearList.value, ' yearList.value');
    currentYear.value = dataListNL.value[0].year;
    changeMonitorYear(currentYear.value);
  }
  tableLoadingNL.value = false;
}
// 监测法年份切换
function changeMonitorYear(val) {
  currentYear.value = val;
  let rows = dataListNL.value.filter(item => item.year == val);
  tableDataNL.value = rows[0].allWaterLoggingPointList;
  echartData.value[0].value = rows[0].floodArea; //内涝
  echartData.value[1].value = areaData.value - rows[0].floodArea; //内涝未发生
  refresh.value = Math.random();
  //gis渲染内涝点
  intiMapDataPoint();
}

// 地图渲染点位
function intiMapDataPoint() {
  if (newfiberMapbox.map.getLayer('waterLoging')) {
    newfiberMapbox.map.removeLayer('waterLoging');
    newfiberMapbox.map.removeSource('waterLoging');
  }
  newfiberMapbox.popupService.popups.forEach((popup, index) => {
    nextTick(() => {
      newfiberMapbox.removePopup(popup);
    });
  });
  let geojson1 = turf.featureCollection(
    tableDataNL.value.map(item =>
      turf.point([item.longitude, item.latitude], {
        ...item,
        waterlogName: `${item.name}`,
        waterlogTime: `${item.yearTotalHour} h`,
        waterlogDepth: `${item.yearMaxDepth} m`,
        color: item.isFlood == '1' ? '#d9001b' : item.isFlood == '0' ? '#95f204' : '',
      })
    )
  );
  addWaterloggingLayer(geojson1, 'waterLoging');
  // let key = 'error_zishui';
  // bus.emit('getGeojsonByType', {
  //   type: 'error_zishui',
  //   callback: geojson => {
  //     setTimeout(() => {
  //       bus.emit('removeMapDatas', ['error_zishui']);
  //       if (!!!geojson.features.length) bus.emit('setGeoJSON', { json: geojson1, key });
  //       bus.emit('setLayerVisible', { layername: key, isCheck: true });
  //     }, 2000);
  //   },
  // });
  geojson1.features.forEach(feature => {
    // console.log(feature.properties, 123321);
    let popupClass;
    feature.properties.isFlood == '0' ? (popupClass = 'successPopup') : (popupClass = 'errorPopup');
    !!feature.properties.isFlood ? (feature.properties.isFlood = '0') : (feature.properties.isFlood = '1');
    return newfiberMapbox.addPopup(
      new mapboxL7.Popup({
        title: '',
        html: `
          <div class=${popupClass}><div class='title'>${feature.properties.waterlogName}</div>
          <div class='part'>积水总时长:${feature.properties.waterlogTime || 0}</div>
          <div class='part'>最大积水深度:${feature.properties.waterlogDepth || 0}</div>
          <div class='part'>雨量站监测累计雨量:${feature.properties.yearMaxRain || 0}mm</div>
          </div>`,
        lngLat: {
          lng: feature.geometry.coordinates[0],
          lat: feature.geometry.coordinates[1],
        },
        anchor: 'center',
        offsets: [20, 80],
        autoClose: false,
      })
    );
  });
}
//地图渲染内涝点
const addWaterloggingLayer = async (geojson, layerName) => {
  !!!newfiberMapbox.map.getSource(layerName) && newfiberMapbox.map.addSource(layerName, { type: 'geojson', data: geojson });
  !!!newfiberMapbox.map.getLayer(layerName) &&
    newfiberMapbox.map.addLayer({
      id: layerName,
      type: 'circle',
      source: layerName,
      paint: {
        'circle-color': ['get', 'color'],
        'circle-radius': 7,
      },
    });
  newfiberMapbox.map.on('click', layerName, e => {
    let clickfeature = newfiberMapbox.map
      .queryRenderedFeatures([
        [e.point.x - 10 / 2, e.point.y - 10 / 2],
        [e.point.x + 10 / 2, e.point.y + 10 / 2],
      ])
      .filter(i => i.layer.id == 'waterLoging');
    if (clickfeature[0].properties.isFlood == '0') return;
    console.log('clickfeature', '点击事件', clickfeature[0].properties.isFlood);
    if (clickfeature[0].properties.isFlood == '1') {
      yearMaxStartTime.value = clickfeature[0].properties.yearMaxStartTime;
      yearMaxEndTime.value = clickfeature[0].properties.yearMaxEndTime;
      stCodes.value = clickfeature[0].properties.stCodes;

      getSuperViseData();
    }
  });
};
//获取监测数据
const getSuperViseData = async () => {
  let params = {
    startTime: yearMaxStartTime.value,
    endTime: yearMaxEndTime.value,
    stCode: stCodes.value,
  };

  let res = await graphicReport(params);
  if (res && res.code == 200) {
    let datas = res.data;

    pipePopupShow.value = true;
    if (datas.propertyMonitorXList.length == 0) {
      pipePopupdata.value = true;
      return;
    }
    if (Boolean(datas.propertyMonitorXList.length)) {
      propertyMonitorXList.value = [];
      datas.propertyMonitorXList.forEach(i => {
        propertyMonitorXList.value.push(i.substr(0, 16));
      });
    }
    unitName.value = datas.propertyMonitorList[0].propertyUnit;
    selectData.value = datas.propertyMonitorList[0].ylist;

    //降雨过程线
    setTimeout(() => {
      initEchartsPopup();
    }, 1000);
  }
};
// 获取建成区面积
function getAreaData() {
  getConfigKey('jcq_area').then(res => {
    areaData.value = res.data || '58.1';
  });
}
const closePopup = () => {
  pipePopupShow.value = false;
};
// 降雨趋势折线图
let chartPopupRain = null;
const initEchartsPopup = () => {
  if (!!chartPopupRain) chartPopupRain.dispose();
  chartPopupRain = echarts.init(document.getElementById('chartPopupRain'));
  chartOption.popupRainTrend.legend.data = [seleceName.value];
  chartOption.popupRainTrend.yAxis.name = unitName.value;
  chartOption.popupRainTrend.xAxis.data = propertyMonitorXList.value;
  chartOption.popupRainTrend.series.name = seleceName.value;
  chartOption.popupRainTrend.series.data = selectData.value;
  // 设置鼠标滚轮放大缩小展示数据区间
  chartOption.popupRainTrend.dataZoom = [{ type: 'inside', startValue: propertyMonitorXList.value[propertyMonitorXList.value.length / 2] }];
  if (propertyMonitorXList.value.length > 0) {
    chartOption.popupRainTrend.graphic.invisible = true; //暂无数据
  } else {
    chartOption.popupRainTrend.graphic.invisible = false; //暂无数据
  }
  chartPopupRain.clear();
  chartPopupRain.setOption(chartOption.popupRainTrend);
};
onMounted(() => {
  getAreaData();
  getModalData();
});
onBeforeUnmount(() => {
  if (!!!newfiberMapbox) return;
  !!newfiberMapbox.map.getLayer('waterLoging') && newfiberMapbox.map.removeLayer('waterLoging');
  !!newfiberMapbox.map.getSource('waterLoging') && newfiberMapbox.map.removeSource('waterLoging');
  newfiberMapbox.popupService.popups.forEach(popup => {
    nextTick(() => {
      newfiberMapbox.removePopup(popup);
    });
  });
  if (timer.value) {
    clearInterval(timer.value);
  }
});
</script>
<style lang="scss">
@import '@/assets/styles/variables.module.scss';
.assessmentPage {
  width: 100%;
  height: 95%;
  .content {
    width: 500px;
    background: $mainBg;
    border-radius: 8px;
    position: absolute;
    top: 20px;
    right: 20px;
    z-index: 90;
    padding: 15px;
    overflow: auto;
    .chartHeight {
      width: 100%;
      height: 240px !important;
    }
  }
  .tabsContent {
    position: absolute;
    z-index: 99;
    left: 30px;
    top: 20px;
  }
  .imgTL {
    position: absolute;
    z-index: 99;
    left: 30px;
    bottom: 20px;
  }
  .tuli {
    left: 20px;
    bottom: 40px;
    z-index: 111;
    position: absolute;
    padding: 10px;
    background: #00314e;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    color: #fff;
    div {
      flex: 1;
    }
    .tuli_img {
      display: flex;
      width: 120px;
      align-items: center;
      margin-top: 5px;
      img {
        margin-right: 10px;
        width: 25px;
      }
    }
  }
}
.l7-popup-tip {
  display: none;
}
.l7-popup .l7-popup-content {
  padding: 0px;
  background: none;
}
.l7-popup .l7-popup-content .l7-popup-close-button {
  display: none;
}

.contentInfo {
  display: flex;
  align-items: center;
  .contentName {
    margin: 3px;
    height: 20px;
    width: 70px;
    font-size: 14px;
    font-weight: 400;
    line-height: 20px;
    color: #00d1ff;
  }
  .contentValue {
    height: 20px;
    width: 100px;
    font-size: 14px;
    font-weight: 400;
    line-height: 20px;
    color: #00d1ff;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
}
.el-popper {
  .typeMap {
    color: #ffffff;
  }
}
#PopupWaterlogging {
  position: fixed;
  left: 52%;
  top: 30%;
  transform: translate(-50%, -50%);
  width: 500px;
  height: 310px;
  background: #021534;
  border: 1px solid #114f89;
  z-index: 2000;
  display: flex;
  .allContent {
    width: 425px;
    height: 300px;
    display: flex;
    flex-direction: column;
  }
  #chartPopupRain {
    width: 425px;
    height: 200px;
  }
  .titleTop {
    width: 95%;
    display: flex;
    padding-top: 8px;
    margin-left: 20px;
  }
  .closePopup {
    width: 5%;
    margin: 15px;

    cursor: pointer;
  }
  .PopupWaterloggingtabs {
    width: 100%;
  }
}
.errorPopup {
  border-radius: 8px;
  background-color: rgba(247, 189, 15, 0.5);
  border: 2px solid #f7bd0f;
  padding: 5px;
  // color: #000;
}
.successPopup {
  border-radius: 8px;
  background-color: rgba(129, 211, 248, 0.5);
  border: 2px solid #81d3f8;
  padding: 5px;
}
.modelmapLegend {
}
</style>
<style lang="scss" scoped>
.modelmapLegend {
  position: absolute;
  right: 20px !important;
}
</style>