Newer
Older
BigScreenDatav / src / views / screen / mainComponents / pipeLayer.vue
StephanieGitHub on 13 Jun 2022 10 KB MOD: 页面更新
<!--
 * @Description: 监控图层
 * @Author: 王晓颖
 * @Date: 2021-09-15 10:04:45
 -->
<template>
  <div>
    <!--<div v-if="layerShow" :class="{'video-dialog': !maxWindow, 'max-window': maxWindow}">-->
    <!--<div style="height:30px;color:white;margin-top:20px;width:100%;text-align:center;font-size: 18px;">实时监控</div>-->
    <!--<img :src="require('@/assets/img/map/maximum.png')" width="20" height="20" class="max-btn" @click="maxWindow = !maxWindow">-->
    <!--<img :src="require('@/assets/img/map/close.png')" width="20" height="20" class="close-btn" @click="closeVideo">-->
    <!--<div class="video-div">-->
    <!--<video :src="videoSrc" autoPlay="" width="100%"></video>-->
    <!--</div>-->
    <!--</div>-->
  </div>
</template>

<script>
  import Leaflet from 'leaflet'
  import commonMixin from '@/components/leafletMap/base/mixins/common.js'
  import { getDeviceList, getDeviceInfo } from '@/api/overview'
  import { getPathBounds, getCenterByBounds, getZoomByBounds } from '@/utils/maputils'

  export default {
    name: 'PipeLayer',
    mixins: [commonMixin('layer')],
    props: {
      show: {
        type: Boolean,
        default: true
      }, // 是否显示
      iconSize: {
        type: Array,
        default: () => {
          return [20, 20]
        }
      }, // 图标大小
      iconAnchor: {
        type: Array,
        default: () => {
          return [10, 20]
        }
      }, // 图标位移
      popupAnchor: {
        type: Array,
        default: () => {
          return [0, -20]
        }
      }, // 弹窗位移
      refreshTime: {
        type: Number,
        default: 60
      } // 定时刷新时间
    },
    data () {
      return {
        maxWindow:false, // 窗口最大化
        layerShow: false,
        dataList: [], // 数据列表
        wellCoverLayer: null, // 井盖图层
        liquidLayer: null, // 液位图层
        noiseLayer: null, // 噪声图层
        harmfulLayer: null, // 有害气体监测仪图层
        layerGroup: [], // 图层组
        wellIcon: require('@/assets/img/map/wellCover.png'),
        liquidIcon: require('@/assets/img/map/liquid.png'),
        noiseIcon: require('@/assets/img/map/noise.png'),
        poisonIcon: require('@/assets/img/map/poison.png'),
        timer: null // 定时器
      }
    },
    watch: {
      show (val) {
        if (val) {
          this.initLayer()
        } else {
          this.clearLayer()
        }
      }
    },
    methods: {
      load () {
        if (this.show) {
          this.initLayer()
        }
      },
      // 初始化图层
      initLayer () {
        const {map} = this
        this.layerGroup = [] // 先清空LayerGroup
        // 初始化图层组
        /* eslint-disable new-cap */
        this.noiseLayer = new Leaflet.layerGroup().addTo(map)
        this.wellCoverLayer = new Leaflet.layerGroup().addTo(map)
        this.liquidLayer = new Leaflet.layerGroup().addTo(map)
        this.harmfulLayer = new Leaflet.layerGroup().addTo(map)
        this.layerGroup.push(this.noiseLayer)
        this.layerGroup.push(this.wellCoverLayer)
        this.layerGroup.push(this.liquidLayer)
        this.layerGroup.push(this.harmfulLayer)
        console.log('initLayer')
        this.loadData()
      },
      // 清除图层
      clearLayer () {
        console.log('clearLayer')
        const {map, layerGroup} = this
        layerGroup.forEach(item => map.removeLayer(item))
      },
      // 加载全部数据
      loadData () {
        const {wellCoverLayer, noiseLayer, liquidLayer, harmfulLayer, wellIcon, liquidIcon, noiseIcon, poisonIcon} = this
        // 获取全部井列表
          getDeviceList().then(response => {
            if (response.code === 200) {
              const wells = response.data
              if (wells.length > 0) {
                const centerxs = [] // 存储所有坐标,用于计算中点
                const centerys = []
                for (const well of wells) {
                  centerxs.push(parseFloat(well.coordinateX))
                  centerys.push(parseFloat(well.coordinateY))
                }
                // 坐标排序取最中间的为中心
                centerxs.sort()
                centerys.sort()
                const index = Math.floor(centerxs.length / 2)
                this.center = [centerxs[index], centerys[index]]
                console.log('总数据数:'+this.dataList.length)
                // 按照设备类型分层
                const wellCoverList = wells.filter(item=>item.deviceType=='1')
                const liquidList =  wells.filter(item=>item.deviceType=='2')
                const harmfulList =  wells.filter(item=>item.deviceType=='3')
                const noiseList =  wells.filter(item=>item.deviceType=='8')
                this.addPointOnMap(wellCoverList, wellCoverLayer, wellIcon )
                this.addPointOnMap(liquidList, liquidLayer, liquidIcon )
                this.addPointOnMap(harmfulList, harmfulLayer, poisonIcon )
                this.addPointOnMap(noiseList, noiseLayer, noiseIcon )
                this.setZoom(wells)
              }
            }
          })
      },
      // 将点加到地图上
      addPointOnMap(dataList, layer, iconType) {
        const {iconSize, iconAnchor, popupAnchor} = this
        layer.clearLayers()
        // 图标
        const icon = Leaflet.icon({
          iconUrl: iconType,
          iconSize: iconSize,
          iconAnchor: iconAnchor,
          popupAnchor: popupAnchor
        })
        dataList.forEach(item => {
          // let popupStr = '<div class="popup-div">' +
          //   '<div class="popup-title">'+item.wellCode+'</div>' +
          //   '<div class="dashed-line"></div>' +
          //   '<div class="popup-item"><label>井名称</label>'+item.wellName+'</div>' +
          //   // '<div class="popup-item"><label>井类型</label>'+item.wellTypeName+'</div>' +
          //   '<div class="popup-item"><label>位置:</label>'+item.position+'</div>'
          //   // '<div class="popup-item"><label>时间</label>'+item.alarmTime+'</div>'
          // // '<div class="popup-button" id="real-video">查看实时监控</div>'
          // popupStr += '</div>'
          // const popup = Leaflet.popup().setContent(popupStr)
          const coordinateX = parseFloat(item.coordinateX)
          const coordinateY = parseFloat(item.coordinateY)
          if (coordinateX > 0 && coordinateY > 0) {
            // 添加marker
            const marker = Leaflet.marker([coordinateY, coordinateX], { icon: icon, id: item.id }).addTo(layer)
            // 点击获取详情并弹窗
            marker.on('click', (e) => {
              if (e.target.dragging._marker._popup) {
                e.target.dragging._marker.unbindPopup()
              }
              getDeviceInfo(e.target.options.id).then(res => {
                const data = res.data
                let popupStr = '<div class="popup-div">' +
                  '<div class="popup-title">' + data.deviceName + '</div>' +
                  '<div class="dashed-line"></div>' +
                  '<div class="popup-item"><label>设备编号</label>'+data.devcode+'</div>' +
                  '<div class="popup-item"><label>设备类型</label>'+data.deviceTypeName+'</div>' +
                  '<div class="popup-item"><label>位置</label>'+data.position+'</div>'  +
                  '<div class="popup-item"><label>权属单位</label>'+data.deptName+'</div>'
                if (data.realtimeData) {
                  for(const item of data.realtimeData){
                    popupStr += '<div class="popup-item"><label>'+item.typeName+'</label>' + item.value + '</div>'
                    popupStr += '<div class="popup-item"><label>更新时间</label>' + item.logtime+ '</div>'
                  }
                }else{
                  popupStr += '<div class="popup-item"><label>实时数据</label> -- </div>'
                }
                popupStr += '</div>'
                const popup = Leaflet.popup().setContent(popupStr)
                e.target.dragging._marker.bindPopup(popup).openPopup()
              })
            })
          }
        })
      },
      setZoom (points) {
        if (points.length > 0) {
          // 计算边界
          const { maxLng, minLng, maxLat, minLat } = getPathBounds(points,'coordinateX','coordinateY')
          // 计算中心点
          const { cenLat, cenLng } = getCenterByBounds({ maxLng, minLng, maxLat, minLat })
          // 计算缩放
          const zoom = getZoomByBounds({ maxLng, minLng, maxLat, minLat })
          console.log({ lat: cenLat, lng: cenLng }, zoom)
          this.map.setView({ lat: cenLat, lng: cenLng }, zoom)
        }
      }
    }
  }
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  .video-dialog{
    position: absolute;
    top: 50%;
    left:50%;
    transform: translate(-50%,-50%);
    z-index:1000;
    width: 600px;
    height: 400px;
    background-color: rgba(7,10,23,0.8);
    border-radius: 10px;
    .max-btn{
      position: absolute;
      top:20px;
      right:60px;
    }
    .close-btn{
      position: absolute;
      top:20px;
      right:20px;
    }
    .close-btn:hover{
      animation:turn 1s linear infinite;
    }
    .video-div{
      width: 100%;
      padding: 0px 20px;
    }
  }
  .max-window{
    position: fixed;
    top: 0;
    left:0;
    z-index:1000;
    width: 100%;
    height: 100%;
    background-color: rgba(7,10,23,0.8);
    border-radius: 10px;
    .max-btn{
      position: absolute;
      top:20px;
      right:60px;
    }
    .close-btn{
      position: absolute;
      top:20px;
      right:20px;
    }
    .close-btn:hover{
      animation:turn 1s linear infinite;
    }
    .video-div{
      width: 100%;
      padding: 0px 20px;
    }
  }
  @keyframes turn{
    0%{-webkit-transform:rotate(0deg);}
    25%{-webkit-transform:rotate(90deg);}
    50%{-webkit-transform:rotate(180deg);}
    75%{-webkit-transform:rotate(270deg);}
    100%{-webkit-transform:rotate(360deg);}
  }
</style>
<style rel="stylesheet/scss" lang="scss" >
  .leaflet-popup-content-wrapper, .leaflet-popup-tip{
    color: white;
    background-color: rgba(10,26,123,0.8);
  }
  .leaflet-popup-content {
    .popup-div {
      font-size: 14px;
      padding: 5px;

    }
    .popup-title {
      font-weight: bold;
    }
    .dashed-line {
      border-bottom: 1px dashed #dddddd;
      margin: 10px -10px;
    }
    .popup-item {
      padding-bottom: 6px;
      label {
        font-weight: bold;
        padding-right: 15px;
      }
    }
    .popup-subitem {
      padding-bottom: 6px;
      font-size: 12px;
    }
    .popup-button{
      color:#67E0E3;
      text-align: center;
      margin-top: 5px;
      text-decoration: underline;
    }
    .popup-button:hover{
      color: #36b7ff;
      cursor: pointer;
    }
  }
</style>