Newer
Older
smartwell_front / src / views / overview / overview3d.vue
wangxitong on 28 Jul 2022 40 KB Changes 设备图层
<!--suppress ALL -->
<template>
  <div class="overview-map-container">
    <div id="mars3dContainer" class="mars3d-container" :style="{height:(bodyHeight-20)+'px'}" />
    <div class="cover">
      <div v-for="(item,index) in layerName" :key="item" class="cover-item">
        <span v-if="index<=7"><img :src="'/../../../static/images/'+layerName[index]+'.png'" style="width: 15px;height:15px"></span>
        <span v-else :style="{color: colors[index-8],fontWeight: 600}">——</span>
        {{ item }}
      </div>
    </div>
    <!--搜索框-->
    <map-search-comp :list="resultList" placeholder="点位编号/名称/位置" style="background: #00000000" @search="search" @change-page="searchPageChange" @click-item="searchItemClick" @clear="clearSearch" />

    <el-slider v-model="alpha" style="width: 220px; position: absolute;top:0px; right: 20px" />
    <!--报警列表-->
    <alarm-list :show="showAlarm" :data="alarmList" @row-click="alarmRowClick" />
    <!--工具箱-->
    <tool-box
      style="position: absolute; width:300px;top:25px;right: 0px"
      :show="!loading"
      :layers="layers"
      :layer-checked="checkedLayer"
      :tool-menu="menus.menuList"
      @change-base-map="changeBaseMap"
      @layer-change="filterLayer"
      @click-menu="clickMenu"
      @close-menu-pop="closeAllPopup"
    />
    <!--数据筛选窗口-->
    <popup-data-filter :show="menus.dataFilterWindowShow" :well-type-list="wellTypeList" @filter="dataFilter" @close="closePopupDataFilter" />
    <!--坐标定位窗口-->
    <popup-location ref="popupLocation" :show="menus.locationWindowShow" @search="setCenter" @picker="pickerPosition" @close="closePopupLocation" />
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import { getWellType } from '@/api/well/well'
import { getWellList, getWellInfo, getAlarmsNow, getWellAlarms } from '@/api/overview/wellOverview'
import { getDeviceAllList, getDeviceType } from '@/api/device/device'
import { toPixel, toLngLat, toSize } from '@/components/Amap/utils/convert-helper'
import DeptSelect from '../../components/DeptSelect/index'
import AMapContainer from '@/components/Amap/AMapContainer'
import AlarmInfoWindow from './components/infoWindowAlarm'
import WellInfoWindow from './components/infoWindowWell'
import AMapMarker from '@/components/Amap/AMapMarker'
import AlarmList from './components/alarmList'
import Vue from 'vue'
import ToolBox from '@/views/overview/components/toolBox'
import PopupDataFilter from '@/views/overview/components/popupDataFilter'
import PopupLocation from '@/views/overview/components/popupLocation'
import MapSearchComp from '@/views/overview/components/mapSearchComp'

import axios from 'axios'
// import 'cesium/Source/Widgets/widgets.css'// 导入必须的样式表
// import 'cesium/Source/Cesium'// 导入必须的样式表
// var Cesium = require('../../../node_modules/cesium/Source/Cesium')
var Cesium = require('../../../node_modules/mars3d-cesium/Build/Cesium/Cesium')
import 'mars3d/dist/mars3d.css'
import 'mars3d/dist/mars3d.js'
import * as mars3d from 'mars3d'
import store from '@/store'
import { breadcrumb } from '@/settings'

var underground = null
var line_layer = []
var line_layer_3D = []
var point_layer = []
var point_layer_3D = []
var dev_layer = []
var dev_layer_3D = []
var wellLoc = {}
export default {
  name: 'Overview3D',
  components: { MapSearchComp, PopupLocation, PopupDataFilter, ToolBox, AlarmList, AMapMarker, AMapContainer, DeptSelect },
  data() {
    return {
      initWell: false, // 是否初始化井信息
      showLine: true,
      showModel: false,
      colors: ['#7f0000', '#804000', '#00ff00', '#ff7fe9', '#ff7fe9', '#ff0000', '#00bfff', '#00ff00', '#ff0000'],
      layerName:
        ['雨水附属物', '污水附属物', '天然气附属物', '燃气附属物', '给水附属物', '电信附属物', '电力附属物', '标识器',
          '雨水管线', '污水管线', '通信管线', '天然气管线', '燃气管线', '路灯管线', '给水管线', '电信管线', '电力管线'],
      baseLayer: 'gaode_vec', // 底图图层
      layers: [{ id: 'well', name: '井图层', children: [] }, { id: 'line', name: '管线图层', children: [] }, { id: 'dev', name: '设备图层', children: [] }, { id: 'alarm', name: '报警图层' }], // 图层列表
      checkedLayer: [], // 选中的图层
      center: ['114.88', '25.68'], // 地图中心
      // center: [this.$store.getters.lng, this.$store.getters.lat], // 地图中心
      zoom: 12, // 地图缩放比例
      type: this.baseConfig.showPointType, // 加载数据方式:massMarkers海量点或cluster聚合点
      refreshType: this.baseConfig.refreshType, // 刷新数据方式:clock定时器或websocket推送
      alarmIcon: require('@/assets/icons/icon-alarm1.png'), // 报警图标
      alarmIconSize: [30, 30], // 报警图标大小
      alarmOffset: [-15, -30], // 报警图标偏移量
      wellIcon: require('@/assets/overview/icon-location-small.png'), // 井图标
      wellIconSize: [16, 16], // 井图标大小
      wellOffset: [-8, -16], // 井偏移量
      massMarkerUrl: './static/overview/icon-location-small.png',
      massMarkerSize: [15, 15],
      massMarkerOffset: [0, 8],
      searchResultSize: [24, 30],
      searchResultOffset: [-12, -30],
      searchResultIcon: require('@/assets/overview/pure-position-icon.png'), // 报警图标
      showAlarm: true, // 是否显示报警
      alpha: 100,
      toolShow: false, // 工具栏是否显示
      menus: {
        menuList: [
          { icon: 'search', menu: 'dataFilter', name: '数据筛选' },
          { icon: 'coordinate', menu: 'location', name: '坐标定位' }
        ],
        dataFilterWindowShow: false, // 数据筛选窗口是否显示
        locationWindowShow: false // 坐标定位窗口是否显示
      }, // 工具栏菜单
      listQuery: {
        keywords: '', // 关键字
        wellType: '', // 点位类型
        deptid: '' // 组织机构
      }, // 筛选条件
      count: 30, // 倒计时显示时间
      clock: null, // 计时器
      showWellType: false, // 是否显示点位类型下拉,默认边上
      wellTypeList: [], // 点位类型列表
      deviceTypeList: [], // 设备类型列表
      commonIcon: 'well-common-green', // 通用图标 绿
      commonIconAlarm: 'well-common-red', // 通用图标 红
      alarmListOri: [], // 原始报警列表
      alarmList: [], // 显示报警列表
      alarmWells: [], // 报警井列表
      resultList: [], // 搜索结果列表
      searchMarkers: [], // 当前搜索页展示marker集合
      latestAlarmTime: '', // 列表中最新报警事件
      alarmFirstAmount: true, // 是否初次加载报警
      firstAmount: true, // 是否第一次加载井数据
      loading: true, // 加载图标是否显示
      markers: [], // 所有井的点原始数据
      massMarks: null, // 海量点对象
      mapMarkers: [], // 查询结果列表
      clusters: [], // 聚合
      tempMarker: null,
      showClearBtn: false, // 是否显示清除查询按钮
      bloomEffect: null,
      layerProvider: '',
      options: {}
    }
  },
  computed: {
    ...mapGetters([
      'needRefresh',
      'bodyHeight'
    ])
  },
  watch: {
    alpha(val) {
      window.map.basemap.opacity = val / 100
      underground.alpha = val / 100
      // if (val <= 90 && window.map.level >= 19) {
      //   line_layer.forEach(layer => {
      //     layer.show = false
      //   })
      // } else {
      //   line_layer.forEach(layer => {
      //     layer.show = true
      //   })
      // }
    },
    needRefresh(val) { // 需要刷新报警
      if (val) this.refreshAlarm()
    },
    'menus.locationWindowShow'(val) { // 打开弹窗设置默认中心,关闭弹窗清空屏幕
      if (val) {
        this.$refs.popupLocation.setQuery(this.center)
      } else {
        // window.map.remove(this.tempMarker)
      }
    }
  },
  beforeCreate() {
    this.$store.dispatch('settings/changeSetting', {
      key: 'breadcrumb',
      value: false
    })
    this.$store.dispatch('settings/changeSetting', {
      key: 'tagsView',
      value: false
    })
  },
  created() {
    this.fetchWellType()
  },
  mounted() {
    this.$nextTick(() => {
      this.windowResize(window.innerHeight, window.innerWidth)
      this.initmars3d()
      this.resultList = []
    })
  },
  beforeDestroy() {
    this.$store.dispatch('settings/changeSetting', {
      key: 'breadcrumb',
      value: true
    })
    this.$store.dispatch('settings/changeSetting', {
      key: 'tagsView',
      value: true
    })
    if (this.clock) {
      clearInterval(this.clock)
      this.clock = null
    }
  },
  methods: {
    windowResize(height, width) {
      // 查找header高度
      const el_header = document.getElementById('app-header')
      let bodyHeight = height - (el_header ? el_header.clientHeight : 56)
      if (store.getters.tagsView) {
        const el_tagsView = document.getElementById('tags-view-container')
        bodyHeight -= el_tagsView ? el_tagsView.clientHeight : 34
      }
      if (breadcrumb) {
        const el_navbar = document.getElementsByClassName('navbar')
        bodyHeight -= el_navbar ? el_navbar[0].clientHeight : 48
      }
      // 减去2个padding
      bodyHeight -= 5
      store.dispatch('settings/ChangeHeight', bodyHeight)
    },
    // 初始化放这里
    async initmars3d() {
      const mapOptions = {
        scene: {
          // 默认视角参数
          center: { lat: this.center[1], lng: this.center[0], alt: 10000, heading: 360, pitch: -45 },
          showSun: true,
          // showMoon: true,
          // showSkyBox: true,
          showSkyAtmosphere: false, // 关闭球周边的白色轮廓 map.scene.skyAtmosphere = false
          fog: true,
          fxaa: true,
          // 以下是Cesium.Globe对象相关参数
          globe: {
            depthTestAgainstTerrain: true, // 是否启用深度监测
            baseColor: '#1A2126', // 地球默认背景色
            showGroundAtmosphere: false, // 是否在地球上绘制的地面大气
            enableLighting: false // 是否显示昼夜区域
          },
          control: {
            infoBox: false
          },
          // 以下是Cesium.ScreenSpaceCameraController对象相关参数
          cameraController: {
            zoomFactor: 3.0, // 鼠标滚轮放大的步长参数
            minimumZoomDistance: 1, // 地球放大的最小值(以米为单位)
            maximumZoomDistance: 5000, // 地球缩小的最大值(以米为单位)
            enableRotate: true, // 2D和3D视图下,是否允许用户旋转相机
            enableTranslate: true, // 2D和哥伦布视图下,是否允许用户平移地图
            enableTilt: true, // 3D和哥伦布视图下,是否允许用户倾斜相机
            enableZoom: true, // 是否允许 用户放大和缩小视图
            enableCollisionDetection: true // 是否允许 地形相机的碰撞检测
          }
        },
        basemaps: [
          {
            pid: 10,
            id: 1111,
            name: '天地图',
            type: 'group',
            layers: [
              { name: '注记', type: 'tdt', layer: 'ter_z', key: ['216ee92889e17ab1b083fae665d522b8'] },
              { name: '注记', type: 'tdt', layer: 'img_z', key: ['216ee92889e17ab1b083fae665d522b8'] }
            ]
          },
          {
            'id': 1112,
            'pid': 10,
            'name': '天地图电子',
            'icon': 'http://mars3d.cn/example/img/basemaps/tdt_vec.png',
            'type': 'group',
            'layers': [
              { 'name': '底图', 'type': 'tdt', 'layer': 'vec_d', 'key': ['216ee92889e17ab1b083fae665d522b8'] },
              { 'name': '注记', 'type': 'tdt', 'layer': 'vec_z', 'key': ['216ee92889e17ab1b083fae665d522b8'] }
            ]
          },
          {
            'id': 1113,
            'pid': 10,
            'name': '天地图影像',
            'icon': 'http://mars3d.cn/example/img/basemaps/tdt_img.png',
            'type': 'tdt',
            'layer': 'img_d',
            'key': ['216ee92889e17ab1b083fae665d522b8'],
            'show': true
          }
        ]
      }
      const map = new mars3d.Map('mars3dContainer', mapOptions)
      map.basemap = 1113
      map.scene.screenSpaceCameraController.enableCollisionDetection = false
      // 设置鼠标
      map.scene.screenSpaceCameraController.tiltEventTypes = [Cesium.CameraEventType.RIGHT_DRAG]
      // 缩放设置 重新设置缩放成员
      map.scene.screenSpaceCameraController.zoomEventTypes = [Cesium.CameraEventType.MIDDLE_DRAG, Cesium.CameraEventType.WHEEL, Cesium.CameraEventType.PINCH]
      // 鼠标左键平移
      map.scene.screenSpaceCameraController.rotateEventTypes = [Cesium.CameraEventType.LEFT_DRAG]
      window.map = map
      underground = new mars3d.thing.Underground({ alpha: this.alpha / 100 })
      map.addThing(underground)
      this.bloomEffect = new mars3d.effect.BloomEffect({
        enabled: true
      })
      map.addEffect(this.bloomEffect)
      window.map.basemap.opacity = this.alpha / 100
      // 崩溃后刷新
      // map.on(mars3d.EventType.renderError, function(event) {
      //   window.location.reload()
      // })
      const that = this
      map.on(mars3d.EventType.load, function(event) {
        window.map.on(mars3d.EventType.cameraChanged, that.cameraChange, that)
        that.initLine()
        that.initPoint()
      })
    },
    initLine() {
      for (let i = 8; i <= 16; i++) {
        // 三维地下管线 (19)
        const wfsLayer = new mars3d.layer.ArcGisWfsLayer({
          name: this.layerName[i],
          popup: 'all',
          url: 'http://111.198.10.15:13002/arcgis/rest/services/gztest/MapServer/' + i,
          minimumLevel: 19,
          symbol: {
            type: 'polylineVolumeP',
            styleOptions: {
              color: this.colors[i - 8],
              shape: 'pipeline',
              radius: 0.1
            },
            callback: function(attr, styleOpt) {
              return { setHeight: -2 }
            }
            // callback: function(attr, styleOpt) {
            //   var val = { attr }.attr
            //   return { addHeight: [-2, -2] }
            // }
          }
        })
        line_layer_3D.push(wfsLayer)
        window.map.addLayer(wfsLayer)
        // 二维管线
        const queryLineserver = new mars3d.query.QueryArcServer({
          url: 'http://111.198.10.15:13002/arcgis/rest/services/gztest/MapServer/' + i,
          popup: 'all',
          pageSize: 3000
        })
        const layer = new mars3d.layer.GeoJsonLayer({
          name: this.layerName[i],
          // enablePickFeatures: false,
          symbol: {
            type: 'polylineC',
            styleOptions: {
              color: this.colors[i - 8],
              width: 3,
              hasShadows: true,
              shadows: Cesium.ShadowMode.ENABLED
            }
          },
          popup: 'all'
          // flyTo: true
        })
        line_layer.push(layer)
        window.map.addLayer(layer)
        queryLineserver.query({
          success: (result) => {
            layer.load({ data: result.geojson })
          },
          error: (error, msg) => {
            console.log('服务访问错误', error)
          }
        })
      }
    },
    initPoint(condition = '') {
      point_layer = []
      point_layer_3D = []
      let comp_layer = 0
      const that = this
      for (let i = 0; i <= 7; i++) {
        const queryPointserver = new mars3d.query.QueryArcServer({
          url: 'http://111.198.10.15:13002/arcgis/rest/services/gztest/MapServer/' + i,
          popup: 'all',
          pageSize: 3000
        })
        const point = new mars3d.layer.GeoJsonLayer({
          name: this.layerName[i],
          symbol: {
            type: 'billboard',
            styleOptions: {
              image: '../static/images/' + this.layerName[i] + '.png',
              scale: 0.6,
              pixelOffsetY: -10,
              scaleByDistance: true,
              scaleByDistance_far: 30000,
              scaleByDistance_farValue: 0.6,
              scaleByDistance_near: 0,
              scaleByDistance_nearValue: 2,
              clampToGround: true,
              highlight: { type: 'click', image: '../static/images/gz-high.png' }
            }
          },
          popup: 'all'
        })
        point_layer.push(point)
        window.map.addLayer(point)
        const point3D = new mars3d.layer.GeoJsonLayer({
          name: this.layerName[i],
          enablePickFeatures: false,
          onCreateGraphic: function(options) {
            // 在里面就可以处理geojson内部的数据
            const points = options.position // 坐标
            const attr = options.attr // 属性信息
            const primitive = new mars3d.graphic.ModelPrimitive({
              allowDrillPick: true,
              // attr: attr,
              id: attr.编号,
              position: points,
              style: {
                url: '../static/model/ys.gltf',
                scale: 1.5,
                setHeight: -2
              }
            })
            point3D.addGraphic(primitive)
          },
          show: false
        })
        // point3D.on(mars3d.EventType.load, function(e) {
        // console.log('绘制矢量对象完成', e)
        // console.log(point3D)
        // })
        if (i !== 7) {
          window.map.addLayer(point3D)
          point_layer_3D.push(point3D)
        }
        if (condition === '') {
          queryPointserver.query({
            success: (result) => {
              if (result.count === 0) {
                this.$message.warning('未查询到相关记录!')
                point.load({ data: { features: null }})
                point3D.load({ data: { features: null }})
                return
              }
              point.load({ data: result.geojson })
              point3D.load({ data: result.geojson })
              if (!this.initWell && comp_layer < 7) {
                comp_layer++
              }
              if (!this.initWell && comp_layer === 7) {
                this.initWell = true
                point_layer_3D.forEach(layer => {
                  layer.options.data.features.forEach(item => {
                    that.$set(wellLoc, item.properties.编号, item.geometry.coordinates)
                  })
                })
                that.mapReady()
              }
            },
            error: (error, msg) => {
              this.$message.error('服务访问错误,' + error)
            }
          })
        } else {
          // 按列查询
          queryPointserver.query({
            column: 'LineWt',
            text: condition,
            success: (result) => {
              if (result.count === 0) {
                this.$message.warning('未查询到相关记录!')
                point.load({ data: { features: null }})
                point3D.load({ data: { features: null }})
                return
              }
              point.load({ data: result.geojson })
              point3D.load({ data: result.geojson })
            },
            error: (error, msg) => {
              this.$message.error('服务访问错误,' + error)
            }
          })
        }
      }
    },
    // 控制二维线的显隐
    cameraChange() {
      console.log('map-level:' + window.map.level)
      console.log('alpha:' + this.alpha)
      if (window.map.level <= 19) { // 远
        // 线
        if (!this.showLine) {
          const lineTypes = this.checkedLayer.filter(item => item.indexOf('line-') > -1).map(item => item.substring(5))
          line_layer.forEach(layer => { layer.show = lineTypes.indexOf(layer.options.name) > -1 })
          this.showLine = true
        }
        if (this.showModel) {
          point_layer_3D.forEach(layer => { layer.show = false })
          this.showModel = false
        }
      } else if (this.alpha < 80) { // 近,透
        if (this.showLine) {
          line_layer.forEach(layer => { layer.show = false })
          this.showLine = false
        }
        if (!this.showModel) {
          const wellTypes = this.checkedLayer.filter(item => item.indexOf('well-') > -1).map(item => item.substring(5))
          point_layer_3D.forEach(layer => { layer.show = wellTypes.indexOf(layer.options.name) > -1 })
          this.showModel = true
        }
      } else { // 近,不透
        if (this.showLine) {
          line_layer.forEach(layer => { layer.show = false })
          this.showLine = false
        }
        if (this.showModel) {
          point_layer_3D.forEach(layer => { layer.show = false })
          this.showModel = false
        }
      }
    },
    // 初始化放这里
    mapReady() {
      this.fetchDeviceList()
      this.firstAmount = true
      this.toolShow = true
      this.refreshAlarm()
      if (this.refreshType === 'clock') { // 如果需要倒计时刷新的
        setTimeout(() => { this.countDown() }, 1000)
      }
    },
    // 过滤图层
    filterLayer(checkedLayer) {
      this.checkedLayer = checkedLayer
      // 1.过滤井图层
      const wellTypes = checkedLayer.filter(item => item.indexOf('well-') > -1).map(item => item.substring(5))
      const lineTypes = checkedLayer.filter(item => item.indexOf('line-') > -1).map(item => item.substring(5))
      // 点
      point_layer.forEach(layer => { layer.show = wellTypes.indexOf(layer.options.name) > -1 })
      point_layer_3D.forEach(layer => { layer.show = wellTypes.indexOf(layer.options.name) > -1 })
      // 线
      line_layer.forEach(layer => { layer.show = lineTypes.indexOf(layer.options.name) > -1 })
      line_layer_3D.forEach(layer => { layer.show = lineTypes.indexOf(layer.options.name) > -1 })

      // 2.选中or没选中报警图层
      if (checkedLayer.indexOf('alarm') !== -1) {
        this.showAlarm = true
      } else {
        this.showAlarm = false
      }
    },
    // 切换底图
    changeBaseMap(type) {
      this.baseLayer = type
      if (type === 'gaode_vec') {
        window.map.basemap = 1112
        if (this.bloomEffect !== null) {
          this.bloomEffect.enabled = false
        }
      } else {
        window.map.basemap = 1113
        if (this.bloomEffect !== null) {
          this.bloomEffect.enabled = true
        }
      }
    },
    // 倒计时函数
    countDown() {
      this.clock = setInterval(() => {
        this.count--
        if (this.count < 0) { // 当倒计时小于0时清除定时器
          this.refreshAlarm()
          this.count = this.baseConfig.refreshTime
        }
      }, 1000)
    },
    // 获取点位类型,显示点位类型下拉
    fetchWellType() {
      // getWellType().then(response => {
      //  this.wellTypeList = []
      //  // 如果该用户支持的点位类型只有一个,则不显示该筛选框
      //  const supportWellTypes = this.$store.getters.wellTypes
      //  this.wellTypeList = response.data.filter(wellType => {
      //    return supportWellTypes.findIndex(item => item == wellType.value) > -1
      //  })
      // })
      this.wellTypeList = this.layerName.map((item, index) => {
        return {
          value: item,
          name: item
        }
      })
      this.wellTypeList.length = 8
      const wellLayer = {
        id: 'well',
        name: '井图层',
        children: this.wellTypeList.map(item => {
          return {
            id: 'well-' + item.value,
            name: item.name
          }
        })
      }
      const lineLayer = {
        id: 'line',
        name: '管线图层',
        children: this.layerName.map(item => {
          return {
            id: 'line-' + item,
            name: item
          }
        }).splice(8, 9)
      }
      const deviceTypes = this.$store.getters.deviceTypes
      this.layers.splice(0, 1, wellLayer)
      this.layers.splice(1, 1, lineLayer)

      if (this.baseConfig.showAllWells) {
        // this.checkedLayer = [...this.checkedLayer, 'well', this.wellTypeList.map(item => 'well-' + item.value), 'line', lineLayer.children.map(item => item.id)]
        this.checkedLayer = ['well', 'line']
        this.wellTypeList.forEach(item => this.checkedLayer.push('well-' + item.value))
        lineLayer.children.forEach(item => this.checkedLayer.push('line-' + item.value))
      } else {
        this.checkedLayer = [...this.checkedLayer]
      }
      if (this.wellTypeList.length <= 1) {
        this.showWellType = false
      }
      getDeviceType(this.listQuery).then(response => {
        this.deviceTypeList = []
        // 过滤掉该单位不支持的设备类型
        const deviceTypes = this.$store.getters.deviceTypes
        for (const deviceType of response.data) {
          if (deviceTypes.indexOf(deviceType.value) !== -1) {
            this.deviceTypeList.push(deviceType)
          }
        }
        const devLayer = {
          id: 'dev',
          name: '设备图层',
          children: this.deviceTypeList.map(item => {
            return {
              id: 'dev-' + item.value,
              name: item.name
            }
          })
        }
        this.layers.splice(2, 1, devLayer)
      })
    },
    /**
     * 数据筛选
     * @param listQuery 筛选条件
     * @param showMessage 是否告知筛选结果
     */
    dataFilter(listQuery, showMessage = true) {
      if (this.type === 'massMarkers') { // 过滤海量点
        this.filterMassMarker(listQuery, showMessage)
        this.filterAlarm(listQuery, showMessage)
      } else if (this.type === 'cluster') { // 过滤聚合点
        // this.filterClusters(listQuery, showMessage)
        this.filterAlarm(listQuery, showMessage)
      }
    },
    // 清空查询
    clearSearch() {
      this.searchMarkers = []
      this.resultList = []
    },
    // 数据查询
    search(keywords) {
      if (keywords === '') {
        this.$message.warning('搜索条件不能为空')
      } else {
        this.resultList = this.markers.filter(item => {
          if (item.wellCode.includes(keywords) || item.wellName.includes(keywords) || item.position.includes(keywords)) {
            return true
          } else {
            return false
          }
        })
        this.initPoint(keywords)
      }
    },
    // 搜索结果页面变化,触发地图展示列表中所有
    searchPageChange(currentMarkers) {
      // 增加查询展示图层
      this.searchMarkers = currentMarkers
    },
    // 点击搜索结果项居中,弹窗
    searchItemClick(marker) {
      // this.center = marker.lnglat
      // this.openInfoWindow(marker.wellId, marker.lnglat, this.searchResultOffset[1])
    },
    // 过滤海量点,给markers赋visible值
    filterMassMarker(listQuery, showMessage = false) {
      const hideWellIds = []// 要隐藏的点位编号
      let center = [] // 待移动到的地图中心
      // 2. 整理查询条件
      const keywords = listQuery.keywords // 关键字
      const wellTypes = listQuery.wellTypes ? listQuery.wellTypes : listQuery.wellType ? [listQuery.wellType] : [] // 点位类型
      let deptids = [] // 所有权属
      if (listQuery.deptid) {
        deptids = this.fetchDeptList(listQuery.deptid) // 获取所有下级
      }
      // 3.查询全部井,是否匹配,只要有一项不匹配则show为false
      for (const marker of this.markers) {
        let show = true
        // 关键字不为空,且没有匹配成功,不显示, 关键字匹配点位编号和位置
        if (keywords && keywords !== '' && !(marker.wellCode.indexOf(keywords) !== -1 || marker.position.indexOf(keywords) !== -1)) {
          show = false
        }
        // 部门不为空, 且没有匹配成功,多部门匹配
        if (deptids.length > 0 && deptids.indexOf(marker.deptid) === -1) {
          show = false
        }
        // 点位类型不为空,且没有匹配成功
        if (wellTypes && wellTypes.length > 0 && wellTypes.indexOf(marker.wellType) === -1) {
          show = false
        }
        // 如果show为false,放入需要隐藏的井id列表
        if (show === false) {
          hideWellIds.push(marker.wellId)
        } else {
          center = marker.lnglat
        }
        marker.visible = show
      }
      this.resetMassMarker()
    },
    // 过滤报警
    filterAlarm(listQuery, showMessage = false) {
      const hideWellIds = []// 要隐藏的点位编号
      // 整理筛选条件
      const keywords = listQuery.keywords
      const wellTypes = listQuery.wellTypes ? listQuery.wellTypes : listQuery.wellType ? [listQuery.wellType] : [] // 点位类型
      let deptids = [] // 所有权属
      if (listQuery.deptid) {
        deptids = this.fetchDeptList(listQuery.deptid) // 获取所有下级
      }
      // 查询报警的井
      for (const marker of this.alarmWells) {
        let show = true
        // 关键字不为空,且没有匹配成功,不显示, 关键字匹配点位编号和位置
        if (keywords && keywords !== '' && !(marker.wellCode.indexOf(keywords) !== -1 || marker.position.indexOf(keywords) !== -1)) {
          show = false
        }
        // 部门不为空, 且没有匹配成功,多部门匹配
        if (deptids.length > 0 && deptids.indexOf(marker.deptid) === -1) {
          show = false
        }
        // 点位类型不为空,且没有匹配成功
        if (wellTypes && wellTypes.length > 0 && wellTypes.indexOf(marker.wellType) === -1) {
          show = false
        }
        // 如果show为false,放入需要隐藏的井id列表
        if (show === false) {
          hideWellIds.push(marker.wellId)
        }
        marker.visible = show
      }
      // 4.过滤报警marker:alarmWells  如果没有找到符合要求的井,直接将全部查询结果隐藏,并将所有报警隐藏,否则按照查询结果筛选需要隐藏的报警
      if (hideWellIds.length === this.alarmWells.length) {
        for (const alarmWell of this.alarmWells) {
          alarmWell.visible = false
        }
      } else {
        // 将报警隐藏
        for (const alarmWell of this.alarmWells) {
          if (hideWellIds.indexOf(alarmWell.wellId) > -1) {
            alarmWell.visible = false
          } else {
            alarmWell.visible = true
          }
        }
      }
      // 5.过滤显示列表:alarmList
      this.alarmList = []
      if (hideWellIds.length > 0) { // 如果有要隐藏的井,过滤
        for (const alarm of this.alarmListOri) {
          const findFlag = hideWellIds.findIndex(code => code === alarm.wellId)
          if (findFlag === -1) {
            this.alarmList.push(alarm)
          }
        }
      } else { // 如果没有直接等于alarmListOri
        this.alarmList = this.alarmListOri
      }
    },
    // 获取全部井列表
    fetchDeviceList() {
      this.loading = false
      this.deviceTypeList.forEach(item => {
        const param = {
          deviceType: item.value
        }
        // getDeviceAllList(param).then(response => {
        //   if (response.code === 200) {
        //     if (response.data.length === 0) return
        //     const graphicLayer = new mars3d.layer.GraphicLayer({ name: item.name })
        //     window.map.addLayer(graphicLayer)
        //     dev_layer.push(graphicLayer)
        //     const name = item.name.substr(0, 1)
        //     response.data.forEach(data => {
        //       if (wellLoc[data.wellCode] !== undefined && wellLoc[data.wellCode].length === 2) {
        //         const primitive = new mars3d.graphic.ModelPrimitive({
        //           position: [wellLoc[data.wellCode][0], wellLoc[data.wellCode][1], -3],
        //           style: {
        //             url: '../static/model/' + 1 + '.glb',
        //             scale: 1,
        //             label: {
        //               // 面中心点,显示文字的配置
        //               text: name, // 对应的属性名称
        //               opacity: 1,
        //               font_size: 14,
        //               color: '#ffffff',
        //               font_weight: 'bold',
        //               font_style: 'normal',
        //               addHeight: 3,
        //               // scaleByDistance: true,
        //               //
        //               // pixelOffsetY: -40,
        //               //
        //               // scaleByDistance_far: 300000,
        //               // scaleByDistance_farValue: 0.4,
        //               // scaleByDistance_near: 1,
        //               // scaleByDistance_nearValue: 1.4,
        //               visibleDepth: false
        //             }
        //           }
        //         })
        //         graphicLayer.addGraphic(primitive)
        //       }
        //     })
        //   }
        // })
      })
    },
    // 刷新报警列表
    refreshAlarm() {
      console.log('refreshAlarm')
      this.count = this.baseConfig.refreshTime
      this.loading = true
      // 如果showAlarm为ture, 确保选中图层报警
      if (this.showAlarm && this.checkedLayer.indexOf('alarm') == -1) {
        this.checkedLayer.push('alarm')
      }
      getAlarmsNow().then(response => {
        if (response.code === 200) {
          this.loading = false
          // 判断最新报警时间,若和旧的最新时间不一样,则判断是否需要产生声音
          if (response.data.length > 0) {
            const latestTime = response.data[0].alarmTime
            console.log(latestTime, 'vs', this.latestAlarmTime)
            if (this.latestAlarmTime < latestTime) {
              // 如果不是初次加载并且声音开关开启状态
              if ((!this.alarmFirstAmount) && this.baseConfig.alarmSound) {
                console.log('playAudio')
                this.playAudio()
              }
              this.latestAlarmTime = latestTime
            }
          }
          this.alarmFirstAmount = false // 初次加载完毕
          // 获取当前报警列表
          this.alarmListOri = response.data // 列表原始
          this.alarmList = response.data // 要显示的报警列表
          this.alarmWells = [] // 报警的井列表
          for (const alarm of response.data) {
            if (this.alarmWells.findIndex(item => item.wellCode === alarm.wellCode) == -1) {
              this.alarmWells.push({
                wellCode: alarm.wellCode,
                wellId: alarm.wellId,
                wellType: alarm.wellType,
                lngGaode: alarm.lngGaode,
                latGaode: alarm.latGaode,
                coordinates: [alarm.lngGaode, alarm.latGaode],
                position: alarm.position,
                visible: true
              })
            }
          }
          console.log('alarmWells Length', this.alarmWells.length)
        }
      })
    },
    /**
     * 打开报警弹窗
     * @param wellId 井id
     * @param coordinates 弹窗位置: [经度,纬度]
     * @param needCenter 是否需要将点居中
     */
    openAlarmWindow(wellId, coordinates, needCenter = false) {
      console.log('openAlarmWindow:' + wellId)
      // if (this.needCenter) { // 如果需要居中
      //   this.center = coordinates
      // }
      // 获取报警详情
      getWellAlarms(wellId).then(response => {
        if (response.code === 200) {
          const wellInfo = response.data
          const alarmInfo = {
            wellCode: response.data.wellCode,
            position: response.data.position,
            deptName: response.data.deptName,
            wellTypeName: response.data.wellTypeName,
            alarms: response.data.alarmList,
            deep: response.data.deep
          }
          const AlarmWindow = Vue.extend({
            render: h => h(AlarmInfoWindow, { props: { alarmInfo: alarmInfo }})
          })
          const alarmWindow = new AlarmWindow().$mount()
          const infoWindow = new window.AMap.InfoWindow({
            content: alarmWindow.$el, // 显示内容
            offset: [0, this.alarmOffset[1]], // 偏移
            autoMove: true // 是否自动调整窗体到视野内
          })
          infoWindow.open(window.map, new toLngLat(coordinates))
        }
      })
    },
    // 关闭所有弹窗
    clearInfoWindow() {
      const { map } = this
      map.clearInfoWindow()
    },
    // 点击报警列表
    alarmRowClick(row) {
      console.log('alarmRowClick')
      const wellId = row.wellId
      for (const alarmWell of this.alarmWells) {
        if (alarmWell.wellId === wellId) {
          // this.center = alarmWell.coordinates
          if (this.zoom < 16) {
            this.zoom = 16
          }
          this.openAlarmWindow(alarmWell.wellId, alarmWell.coordinates, true)
        }
      }
    },
    // 点击工具箱菜单, menu:{menu:'xxx', name:''}, 建议菜单menu属性的命名与自定义弹窗的show属性名称保持同一规则
    clickMenu(menu) {
      this.closeAllPopup()
      const key = menu.menu + 'WindowShow'
      const obj = {}
      obj[key] = true // 将该值置为false, 需要借助obj中转
      Object.assign(this.menus, obj)
    },
    // 关闭所有菜单点出的弹窗
    closeAllPopup() {
      for (const key in this.menus) {
        if (key.indexOf('WindowShow') > -1) {
          // 将该值置为false, 需要借助obj中转
          const obj = {}
          obj[key] = false
          Object.assign(this.menus, obj)
        }
      }
    },
    // 关闭数据筛选弹窗
    closePopupDataFilter() {
      Object.assign(this.menus, { dataFilterWindowShow: false })
    },
    // 坐标定位,居中,绘点
    setCenter(position) {
      this.center = position
      var center = { lat: this.center[1], lng: this.center[0], alt: 10000, heading: 360, pitch: -45 }
      window.map.setCameraView(center)
    },
    // 坐标拾取, 在地图上绘点
    pickerPosition() {
      const { searchResultOffset, searchResultIcon, searchResultSize, center } = this
      const icon = new window.AMap.Icon({
        size: toSize(searchResultSize), // 图标尺寸
        image: searchResultIcon, // Icon的图像
        imageSize: toSize(searchResultSize) // 根据所设置的大小拉伸或压缩图片
      })
      const marker = new window.AMap.Marker({
        icon: icon,
        position: center,
        offset: toPixel(searchResultOffset),
        draggable: true
      })
      marker.on('dragend', e => {
        const position = [e.lnglat.lng, e.lnglat.lat]
        this.$refs.popupLocation.setQuery(position)
      })
      marker.setMap(window.map)
      this.tempMarker = marker
    },
    // TODO: 关闭坐标定位窗口, 清除地图上的标注
    closePopupLocation() {
      Object.assign(this.menus, { locationWindowShow: false })
    },
    // 获取当前deptid的所有下级id,仅最多支持3级
    fetchDeptList(deptid) {
      console.log('fetchDeptList')
      const deptids = [deptid] // 储存了该pid和其子集
      const deptlist = this.$refs.deptSelect.fetchDeptTree()
      for (const dept of deptlist) {
        if (dept.pid === deptid) {
          deptids.push(dept.id)
        }
      }
      const result = []
      // 查找所有列表中有没有deptids里面的本人或子集
      if (deptlist.length > 0) {
        for (const dept of deptlist) {
          if (deptids.indexOf(dept.id) !== -1) {
            result.push(dept.id)
          } else if (deptids.indexOf(dept.pid) !== -1) {
            result.push(dept.id)
          }
        }
      }
      console.log(result)
      return result
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss">
// 查询框
.map-search-div{
  position: absolute;
  z-index: 100;
  padding: 5px 20px;
  background-color: rgba(244, 244, 244, 0.9);
  /*left: 90px;*/
  .el-form-item{
    margin-bottom: 0px;
  }
}
// 刷新框
.function-div{
  position: absolute;
  right: 10px;
  top: 7px;
  z-index: 1100;
  padding: 10px;
  color: #ce8b74;
  font-size: 14px;
  /*background-color: rgba(244, 233, 230, 1.0);*/
  .font-red{
    color: red;
    font-weight: bold;
  }
  .el-icon-refresh:hover{
    color: #ff7fe9;
    font-weight: bold;
    cursor: pointer;
  }
}
// 刷新框
.refresh-div{
  position: absolute;
  right: 10px;
  top: 7px;
  z-index: 100;
  padding: 10px;
  color: #ce8b74;
  font-size: 14px;
  background-color: rgba(244, 233, 230, 1.0);
  .font-red{
    color: red;
    font-weight: bold;
  }
  .el-icon-refresh:hover{
    color: red;
    font-weight: bold;
    cursor: pointer;
  }
}
// 地图
.overview-map-container{
  width: 100%;
  overflow-y: hidden;
  padding: 0px;
  .map-demo{
    width: 100%;
    .svg-icon{
      width: 20px;
      height: 20px;
    }
    .alarm-icon{
      width: 29px;
      height: 30px;
    }
    .nomal-info-window{
      background-color: pink;
    }
  }
}

.search-marker{
  position: relative;
  .search-marker-image{
    width: 100%;
    height: 100%;
  }
  .search-marker-label{
    position:absolute;
    font-size: 14px;
    font-weight: 600;
    color:#FFF;
    z-index:50;
    top: 4px;
    left: 50%;
    transform: translateX(-50%)
  }
}
.cover{
  position: absolute;
  bottom: 0px;
  left: 0px;
  display: flex;
  flex-wrap: wrap;
  background-color: #fcfbe8;
  width: 210px;
  height: 180px;
  padding: 6px;
  .cover-item{
    width: 50%;
    padding: 1px;
    font-size: 13px;
  }
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
.no-head-scrollbar .el-scrollbar__wrap, has-head-scrollbar .el-scrollbar__wrap {
  padding: 0px 10px;
}
</style>