Newer
Older
casic-smartcity-well-front / src / components / mapWindow / leafletMap.vue
<template>
  <div id="map" ref="mapDiv" class="baseMap">
    <slot/>
  </div>
</template>

<script>
import L, { map } from 'leaflet'
import "leaflet.markercluster"
import 'leaflet/dist/leaflet.css'
import "leaflet.markercluster/dist/MarkerCluster.css"
import "leaflet.markercluster/dist/MarkerCluster.Default.css"

var esri = require('esri-leaflet')
export default {
  name: 'LeafletMap',
  props: {
    satellite: {
      type: Boolean,
      default: true
    },
    showAllWell: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      map: null,
      baseLayer: [],
      satelliteLayer: null,
      alarmMarkers: [], // 选点
      icon: null,
      alarmIcon: null,
      group: null,
      // layerGroups: [], // 图层组,用于控制一组内容显示或者隐藏
      gxLayers: [],
      allWellLayers: [], // 所有的井图层 聚合点
      alarmWellLayers: [], // 报警井的图层
    }
  },
  mounted () {
    this.initMap()
  },
  watch: {
    satellite (val, oldVal) {
      if (val&&!oldVal) {
        this.satelliteLayer = L.tileLayer(this.baseConfig.satelliteUrl, {
          maxZoom: 22
        })
        this.satelliteLayer.addTo(this.map)
      } else {
        this.map.removeLayer(this.satelliteLayer)
      }
    }
  },
  methods: {
    initMap () {
      this.icon = L.icon({
        iconUrl: require(`@/assets/map/marker.png`),
        iconSize: [20, 30],
        iconAnchor: [10, 30],
        popupAnchor: [0, -30]
      })

      this.alarmIcon = L.icon({
        iconUrl: require(`@/assets/map/markerAlarm.png`),
        iconSize: [20, 30],
        iconAnchor: [10, 30],
        popupAnchor: [0, -30]
      })

      this.group = L.layerGroup()

      const map = L.map(this.$refs.mapDiv, {
        minZoom: 14,
        maxZoom: 25,
        center: this.baseConfig.center,
        zoom: this.baseConfig.zoom,
        zoomControl: false,
        attributionControl: false,
        crs: L.CRS.EPSG3857
      })
      map.doubleClickZoom.disable()
      this.map = map // data上需要挂载
      window.map = map
      this.$emit('onload', map)

      this.map.addLayer(this.group)

      // 加载图层
      this.addLayers()
    },
    addLayers () {
      // 加载天地图底图和标注
      const tdtMap = L.tileLayer(this.baseConfig.mapUrl, { maxZoom: 22 })
      const tdtLabel = L.tileLayer(this.baseConfig.labelUrl, { maxZoom: 22 })
      this.satelliteLayer = L.tileLayer(this.baseConfig.satelliteUrl, { maxZoom: 22 })
      this.baseLayer.push(tdtMap.addTo(this.map))
      if (this.satellite) {
        this.baseLayer.push(this.satelliteLayer.addTo(this.map))
      }
      this.baseLayer.push(tdtLabel.addTo(this.map))

      // this.addPartsLayer()

      // this.addPartsLayer(2) // 雨水管线附属物
      // this.addPartsLayer(3) // 污水管线附属物
      this.addPartsLayer(4) // 雨水管线
      this.addPartsLayer(5) // 污水管线
    },
    addPartsLayer: function(index) {
      const item = {
        url: `${this.baseConfig.baseGisUrl}${this.baseConfig.gxServerUrl}/${index}`,
        minZoom: this.baseConfig.zoom
      }
      const layer = esri.featureLayer(item).addTo(this.group)

      this.gxLayers.push(layer)
      // this.layerGroups.push(layer)
    },
    addWellLayer: function(wellList) {
      // 清除之前的图层
      this.allWellLayers.forEach(layer => {
        this.group.removeLayer(layer)
      })
      this.allWellLayers = []

      const clusterLayer = L.markerClusterGroup({
	      showCoverageOnHover: false,
        disableClusteringAtZoom: 18
      })// 全部井的海量点图层

      for (let i = 0; i < wellList.length; i++) {
        const well = wellList[i]
        if (well.coordinateX !== "" && well.coordinateY !== "") {
          const latlng = L.latLng([well.coordinateY, well.coordinateX])
          const marker = L.marker(latlng, {icon: this.icon})

          // 弹窗样式
          const popupStr = '<div class="popup-div">' +
            '<div class="popup-title">井信息</div>' +
            '<div class="dashed-line"></div>' +
            '<div class="popup-item"><label>井编号</label>' + well.wellCode + '</div>' +
            '<div class="popup-item"><label>井名称</label>' + well.wellName + '</div>' +
            '<div class="popup-item"><label>位置</label>' + well.position + '</div>' +
            '</div>'
          const popup = marker.bindPopup(popupStr)

          clusterLayer.addLayer(marker)
        }
      }
      this.allWellLayers.push(clusterLayer)
      // this.layerGroups.push(clusterLayer)
      this.group.addLayer(clusterLayer)

      this.showOrHideAllWell(this.showAllWell)
    },
    addAlarmWellLayer: function(alarmList) {
      const alarmLayer = L.layerGroup()
      this.alarmMarkers = []
      for (let i = 0; i < alarmList.length; i++) {
        const alarm = alarmList[i]
        if (alarm.coordinateX !== "" && alarm.coordinateY !== "") {
          const latlng = L.latLng([alarm.coordinateY, alarm.coordinateX])
          const marker = L.marker(latlng, {icon: this.alarmIcon, code: alarm.wellCode})

          // 弹窗样式
          const popupStr = '<div class="popup-div">' +
            '<div class="popup-title">报警信息</div>' +
            '<div class="dashed-line"></div>' +
            '<div class="popup-item"><label>报警内容</label>' + alarm.alarmContent + '</div>' +
            '<div class="popup-item"><label>报警时间</label>' + alarm.alarmTime + '</div>' +
            '<div class="popup-item"><label>井编号</label>' + alarm.wellCode + '</div>' +
            '<div class="popup-item"><label>设备编号</label>' + alarm.devcode + '</div>' +
            '<div class="popup-item"><label>井类型</label>' + alarm.wellTypeName + '</div>' +
            '<div class="popup-item"><label>位置</label>' + alarm.position + '</div>' +
            '</div>'
          const popup = marker.bindPopup(popupStr)

          alarmLayer.addLayer(marker)

          // 加到marker列表中
          this.alarmMarkers.push(marker)
        }
      }
      this.alarmWellLayers.push(alarmLayer)
      // this.layerGroups.push(alarmLayer)
      this.group.addLayer(alarmLayer)
    },
    locateWell: function(wellCode) {
      const wellFilted = this.alarmMarkers.filter(well => well.options.code === wellCode)
      if (wellFilted.length > 0) {
        const well = wellFilted[0]
        this.map.setView([well.getLatLng().lat, well.getLatLng().lng], 20)
        well.openPopup();
      }
    },
    showOrHideAllWell(show) {
      if (show) {
        this.allWellLayers.forEach(layer => {
          this.group.addLayer(layer)
        })
      } else {
        this.allWellLayers.forEach(layer => {
          this.group.removeLayer(layer)
        })
      }
    },
    showOrHideAlarmWell(show) {
      if (show) {
        this.alarmWellLayers.forEach(layer => {
          this.group.addLayer(layer)
        })
      } else {
        this.alarmWellLayers.forEach(layer => {
          this.group.removeLayer(layer)
        })
      }
    },
    resetMapView() {
      this.map.setView(this.baseConfig.center, this.baseConfig.zoom)
    }
  }
}
</script>

<style scoped>
  .baseMap {
    height: 100vh;
    width: 100%;
    /*border: 1px solid #DCDCDC;*/
    /*border-radius: 4px;*/
  }
</style>

<style>
  .leaflet-container a.leaflet-popup-close-button {
    top: 5px; /* 修改弹窗关闭按钮样式 */
    right: 10px; /* 修改弹窗关闭按钮样式 */
  }

  .leaflet-popup-content .popup-div {
    font-size: 15px;
    padding: 6px;
  }

  .leaflet-popup-content .popup-title {
    font-weight: bold;
  }

  .leaflet-popup-content .dashed-line {
    border-bottom: 1px dashed #dddddd;
    margin: 10px -10px;
  }

  .leaflet-popup-content .popup-item {
    padding-bottom: 6px;
  }

  .leaflet-popup-content .popup-item label {
    font-weight: bold;
    padding-right: 15px;
  }

  .leaflet-popup-content .popup-subitem {
    padding-bottom: 6px;
    font-size: 12px;
  }
</style>