Newer
Older
cockpit_hxrq_front / src / views / maps / waterThreat2.vue
StephanieGitHub on 25 Apr 2021 14 KB MOD:优化显示
<!--
 * @Description: 水保隐患专题
 * @Author: 王晓颖
 * @Date: 2021-04-07
 -->
<template>
  <layout-map>
    <!--选择区-->
    <!--<select-all-construction @change="selectChange" />-->
    <!--&lt;!&ndash;统计结果显示&ndash;&gt;-->
    <!--<div class="label-div">-->
    <!--<div class="label">-->
    <!--{{ boardData.name | boardNameFilter }}-->
    <!--</div>-->
    <!--<div class="value">-->
    <!--{{ boardData.value }}-->
    <!--</div>-->
    <!--</div>-->

    <!--地图-->
    <Map :url="configUrl" @onload="onMapload" />
    <div class="map-btn-group">
      <!--<select-button :select="heatShow" name="热力图" icon="icon-heat" @click="showHeat(heatShow)"/>-->
      <select-button :select="positionShow" name="点位分布" icon="icon-position" @click="showPosition(positionShow)"/>
      <select-button :select="stationShow" name="管理处" icon="icon-station" @click="showStation(stationShow)"/>
    </div>
  </layout-map>
</template>

<script>
import Map from '@/components/Map/MarsMap.vue'
import 'mars3d-heatmap'
import axios from 'axios'
import SelectAllConstruction from './components/selectAllConstruction'
import SelectButton from '@/components/SelectTool/components/selectButton'
import { getTimes } from '@/utils/dateutils'
import LayoutMap from '@/layout/layoutMap'
import { getWaterThreat } from '@/api/threat'
export default {
  name: 'WaterThreat',
  components: {
    LayoutMap,
    SelectAllConstruction,
    Map,
    SelectButton
  },
  filters: {
    boardNameFilter(val) {
      if (val === '全部' || val === '') {
        return '全省水保隐患'
      } else {
        return val + '区域水保隐患'
      }
    }
  },
  data() {
    return {
      map: null, // 地图
      configUrl: 'static/config/config.json',
      alpha: 100, // 透明度
      underground: null, // ?
      heatShow: false, // 显示热力图
      stationShow: true, // 显示管理处
      positionShow: true, // 显示位置
      boardData: {
        name: '全部',
        value: 196
      }, // 统计版展示数据
      threatLevel: {
        '1': 'A级',
        '2': 'B级',
        '3': 'C级',
        '4': '问题'
      }, // 隐患等级
      manageStations: [
        { 'x': 112.73874, 'y': 37.693689, 'z': 0, 'name': '晋中管理处' },
        { 'x': 111.121552, 'y': 37.5245, 'z': 0, 'name': '吕梁管理处' },
        { 'x': 112.929902, 'y': 39.622888, 'z': 0, 'name': '同朔管理处' },
        { 'x': 112.72496, 'y': 38.415485, 'z': 0, 'name': '忻州管理处' },
        { 'x': 113.58249, 'y': 37.851892, 'z': 0, 'name': '阳泉管理处' },
        { 'x': 110.980927, 'y': 35.010828, 'z': 0, 'name': '运城管理处' },
        { 'x': 113.038394, 'y': 35.850111, 'z': 0, 'name': '长晋管理处' },
        { 'x': 111.491467, 'y': 36.064572, 'z': 0, 'name': '临汾管理处' }
      ],
      threatAreaStation: [
        { x: 112.73874, y: 37.693689, id: 0, name: '晋中管理处', count: 158 },
        { x: 111.121552, y: 37.5245, id: 0, name: '吕梁管理处', count: 10 },
        { x: 112.929902, y: 39.622888, id: 0, name: '同朔管理处', count: 44 },
        { x: 112.72496, y: 38.415485, id: 0, name: '忻州管理处', count: 9 },
        { x: 113.58249, y: 37.851892, id: 0, name: '阳泉管理处', count: 21 },
        { x: 110.980927, y: 35.010828, id: 0, name: '运城管理处', count: 21 },
        { x: 113.038394, y: 35.850111, id: 0, name: '长晋管理处', count: 11 },
        { x: 111.491467, y: 36.064572, id: 0, name: '临汾管理处', count: 30 }
      ],
      threatArea: [], // 第三方隐患列表
      stationLayer: null, // 管理站图层
      heatLayer: null, // 水保隐患热力图
      threatLayer: null, // 水保隐患分布图层
      pointColorArr: ['#f33349', '#f79a2c', '#f2fa19', '#95e40c', '#1ffee6'],
      graphicLayer: null // 管理站标签图层
    }
  },
  methods: {
    // 地图构造完成回调
    onMapload(map) {
      // 以下为演示代码
      this.map = map
      // 背景透明
      this.map._viewer.scene.backgroundColor = new this.Cesium.Color(0.0, 0.0, 0.0, 0.0)
      this.map._viewer.scene.globe.baseColor.alpha = 0
      // this.addWaterHeat()
      // 添加管理处
      this.addStation()
      this.addStationDiv()
      // 添加水保隐患隐患点
      this.addThreatPosition()
    },
    // 高后果区热力图
    addWaterHeat() {
      const { mars3d } = this
      getWaterThreat().then((res) => {
        let data = res.data.filter(item => item['DES02'] !== '无')
        data = data.map(item => {
          return {
            '经度': parseFloat(item['DES08']),
            '纬度': parseFloat(item['DES09']),
            '位置描述': item['DES02'],
            '村庄地址': item['DES03'],
            '发现人': item['DES04'],
            '隐患描述': item['DES05'],
            '业主单位': item['DES06'],
            '隐患类型': item['DES01'],
            '隐患发现时间': item['WD01_03'],
            '创建时间': item['DES07'],
            '隐患级别': item['WD54_03'],
            '所属管理处': item['DES10'],
            '状态': item['WD56_03']
          }
        })
        // 过滤掉经度为null的
        this.threatArea = data.filter(item => item['经度'] !== null)
        this.boardData.value = this.threatArea.length
        const heatLayer = new mars3d.layer.HeatLayer({
          positions: this.threatArea.map(item => {
            return { lng: item['经度'], lat: item['纬度'], value: 1 }
          }),
          heatStyle: {
            radius: 30, // 半径
            blur: 1 // 模糊因子
          },
          // 以下为矩形矢量对象的样式参数
          style: {
            opacity: 0.8,
            clampToGround: false,
            height: 10000
          },
          redrawZoom: true,
          flyTo: false
        })
        this.heatLayer = heatLayer
        this.map.addLayer(heatLayer)
      })
    },
    // 水保隐患位置
    addThreatPosition() {
      getWaterThreat().then((res) => {
        let data = res.data
        data = data.map(item => {
          return {
            '经度': parseFloat(item['DES08']),
            '纬度': parseFloat(item['DES09']),
            '位置描述': item['DES02'],
            '村庄地址': item['DES03'],
            '发现人': item['DES04'],
            '隐患描述': item['DES05'],
            '业主单位': item['DES06'],
            '隐患类型': item['DES01'],
            '隐患发现时间': item['WD01_03'],
            '创建时间': item['DES07'],
            '隐患级别': item['WD54_03'],
            '所属管理处': item['DES10'],
            '状态': item['WD56_03']
          }
        })
        debugger
        this.threatArea = data.filter(item => item['经度'] !== null)
        this.boardData.value = this.threatArea.length
        this.addFeatures(this.threatArea)
      })
    },
    // 添加隐患点
    addFeatures(arr) {
      const { mars3d, Cesium, threatLevel } = this
      // 创建DIV数据图层
      var graphicLayer = new mars3d.layer.DivLayer()
      this.threatLayer = graphicLayer
      this.map.addLayer(graphicLayer)
      // 在layer上绑定监听事件
      graphicLayer.on(mars3d.EventType.click, function(event) {
        console.log('监听layer,单击了矢量对象', event)
      })
      graphicLayer.bindPopup(function(event) {
        const item = event.graphic.attr
        var html =
          '位置描述:' +
          item['位置描述'] +
          '<br />村庄地址:' +
          item['村庄地址'] +
          '<br />发现人:' +
          item['发现人'] +
          '<br />隐患描述:' +
          item['隐患描述'] +
          '<br />创建时间:' +
          item['创建时间'] +
          '<br />隐患等级:' +
          threatLevel[item['隐患等级']]
        return html
      })

      for (var i = 0, len = arr.length; i < len; i++) {
        const item = arr[i]
        var jd = item['经度']
        var wd = item['纬度']
        const level = parseInt(item['隐患等级']) - 1
        var clr = this.pointColorArr[level]
        var graphic = new mars3d.graphic.DivGraphic({
          position: Cesium.Cartesian3.fromDegrees(jd, wd, 0),
          style: {
            html: '<div class="mars3d-animation-point" style="color:' + clr + ';"><p></p></div>',
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 2000000) // 按视距距离显示
          },
          attr: item
        })
        graphicLayer.addGraphic(graphic)
      }
    },
    // 管理处
    addStation() {
      const { mars3d } = this
      const stationLayer = new mars3d.layer.ModelLayer({
        name: '管理处',
        url: './static/gltf/output/guanlizhan.gltf',
        // url: './static/gltf/house02.gltf',
        style: {
          scale: 10,
          heading: 0,
          minimumPixelSize: 30,
          clampToGround: true
        },
        positions: this.manageStations.map(item => {
          return { lng: item.x, lat: item.y, alt: 0 }
        })
      })
      this.stationLayer = stationLayer
      this.map.addLayer(stationLayer)
    },
    // 选框发生变化
    selectChange({ area, state, time, level }) {
      area = area === '全部' ? '' : area
      time = time === '全部' ? '' : time
      level = level === '全部' ? '' : level
      // 解析时间
      let beginTime = ''
      let endTime = ''
      if (time) {
        const result = getTimes(time)
        beginTime = result.beginDate
        endTime = result.endDate
      }
      this.boardData.name = area
      // 查询数据
      let count = 0
      debugger
      for (const hca of this.threatArea) {
        let flag = true // 标记是否合格
        // 比较区域
        if (area && hca['所属管理处'] && hca['所属管理处'].indexOf(area) === -1) {
          flag = false
        }
        // 比较时间
        if (time) {
          const real_date = new Date(hca['识别时间'])
          if (real_date && (real_date < beginTime || real_date > endTime)) {
            flag = false
          }
        }
        // 比较级别
        if (level && hca['隐患等级'] && hca['隐患等级'] === level) {
          flag = false
        }
        if (flag) {
          count++
        }
      }
      this.boardData.value = count
    },
    // 自定义的弹窗
    addStationDiv() {
      const { Cesium, mars3d } = this
      const graphicLayer = new mars3d.layer.GraphicLayer()
      this.graphicLayer = graphicLayer
      this.map.addLayer(graphicLayer)
      for (const station of this.threatAreaStation) {
        var graphic = new mars3d.graphic.DivGraphic({
          position: Cesium.Cartesian3.fromDegrees(station.x, station.y, 10100),
          style: {
            html: `<div class="divpoint divpoint-theme-29baf1">
                    <div class="divpoint-wrap">
                        <div class="area">
                            <div class="arrow-lt"></div>
                            <div class="b-t"></div>
                            <div class="b-r"></div>
                            <div class="b-b"></div>
                            <div class="b-l"></div>
                            <div class="arrow-rb"></div>
                            <div class="label-wrap">
                                <div class="title">${station.name}</div>
                                <div class="label-content">
                                    <div class="data-li">
                                        <div class="data-label">水保隐患数量:</div>
                                        <div class="data-value"><span class="label-num">${station.count}</span><span class="label-unit">个</span>
                                        </div>
                                    </div>
                                    <div class="data-li">
                                        <div class="data-label">经度:</div>
                                        <div class="data-value"><span class="label-num">${station.x}</span>
                                        </div>
                                    </div>
                                    <div class="data-li">
                                        <div class="data-label">纬度:</div>
                                        <div class="data-value"><span class="label-num">${station.y}</span>
                                        </div>
                                    </div>
                                    `,
            // anchor: [0, 0],
            horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10000, 500000), // 按视距距离显示
            scaleByDistance: new Cesium.NearFarScalar(10000, 1.0, 500000, 0.1),
            clampToGround: true,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
          },
          pointerEvents: false // false时不允许拾取和触发任意鼠标事件,但可以穿透div缩放地球
        })
        graphicLayer.addGraphic(graphic)
        graphic.testPoint = false // 打开测试点,与DIV点进行对比位置调整css
      }
    },
    // 是否显示热力图
    showHeat(show) {
      // 现在正在显示
      if (show) { // 移除
        this.heatShow = false
        this.map.removeLayer(this.heatLayer, true)
      } else {
        this.heatShow = true
        this.addWaterHeat()
      }
    },
    // 显示管理处
    showStation(show) {
      // 现在正在显示
      if (show) { // 移除
        this.stationShow = false
        this.map.removeLayer(this.stationLayer, true)
        this.map.removeLayer(this.graphicLayer, true)
      } else {
        this.stationShow = true
        this.addStation()
        this.addStationDiv()
      }
    },
    // 显示隐患分布
    showPosition(show) {
      if (show) { // 移除
        this.positionShow = false
        this.map.removeLayer(this.threatLayer, true)
      } else {
        this.positionShow = true
        this.addThreatPosition()
      }
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  .label-div{
    position: absolute;
    top: 140px;
    left:31rem;
    z-index:100;
    color: white;
    padding:2rem 3rem 1.5rem 3rem;
    background-image: url("../../assets/button_images/board-box1.png");
    background-size: 100% 100%;
    .label{
      margin-bottom: 1rem;
      font-size:1.2rem;
    }
    .value{
      font-family: DS-DigitalBold;
      font-size:2.5rem;
    }
  }
  .map-btn-group{
    position: absolute;
    bottom:3rem;
    left:50%;
    transform: translateX(-50%);
    display: flex;
    justify-content: center;
  }
</style>