Newer
Older
smartwell_front / src / components / CMap / components / cmapSmart.vue
StephanieGitHub on 6 Dec 2019 12 KB ADD:智能分析模块
<template>
  <div>
    <div id="map" ref="map" class="mapDiv"/>
    <slot/>
  </div>
</template>

<script>
import bindEvents from './../base/bindEvents'
import { createIcon } from '../base/factory.js'

export default {
  name: 'Cmap',
  props: {
    center: { // 地图中心
      type: Object,
      default: function() {
        return { lat: 39.9, lng: 116.4 }
      }
    },
    wellObj: { // 井对象
      type: Object,
      default: function() {
        return { wellCode: '', id: '', lat: 39.9, lng: 116.4, radius: 10 }
      }
    },
    valves: { // 阀门
      type: Array,
      default: () => []
    },
    zoom: { // 缩放层级
      type: Number,
      default: 12
    },
    minZoom: { // 最小缩放层级
      type: Number,
      default: 9
    },
    maxZoom: { // 最大缩放层级
      type: Number,
      default: 21
    },
    autoResize: { // 自动重绘
      type: Boolean,
      default: true
    },
    size: { // marker大小
      type: Array,
      default: function() {
        return [30, 30]
      }
    },
    anchor: { // 位移
      type: Array,
      default: function() {
        return [15, 30]
      }
    }, // 图标位移
    popupTemplate: { // 弹窗html内容
      type: String,
      default: '<div>hello</div>'
    },
    popupAnchor: { // 弹窗位移
      type: Array,
      default: function() {
        return [0, -15]
      }
    }
  },
  data() {
    return {
      // wellObj: null,
      affectCicle: null, // 影响区域
      affectPipes: null, // 影响管线
      closeCircle: null, // 关阀影响区域
      closePipes: null, // 影响管线
      mapLayers: null, // 地图图层
      wellOverlay: null, // 井overlay
      affectAreaOverlay: null, // 影响区域overlay
      affectLineOverlays: [], // 影响管线overlay
      valvesOverlays: [], // 阀门overlay列表
      closeAreaOverlay: null, // 关阀影响区域overlay
      closeLineOverlays: [] // 关阀影响区域overlay
    }
  },
  watch: {
    center(val, oldVal) {
      const { mapLayers, zoom } = this
      if (mapLayers != null && val !== oldVal) {
        mapLayers.setCenter(new CLatLng(val.lat, val.lng))
      }
    },
    'center.lng'(val, oldVal) {
      const { mapLayers, zoom, center } = this
      if (mapLayers != null && val !== oldVal) {
        mapLayers.setCenter(new CLatLng(center.lat, val))
      }
    },
    'center.lat'(val, oldVal) {
      const { mapLayers, zoom, center } = this
      if (mapLayers != null && val !== oldVal) {
        mapLayers.setCenter(new CLatLng(val, center.lng))
      }
    },
    zoom(val, oldVal) {
      const { mapLayers } = this
      mapLayers.setZoom(val)
    },
    minZoom(val, oldVal) {
      const { mapLayers } = this
      mapLayers.setMinZoom(val)
    },
    maxZoom(val, oldVal) {
      const { mapLayers } = this
      mapLayers.setMaxZoom(val)
    },
    alarmMarkers(val) {
      console.log('alarmMarkers')
      this.renderMarkers()
    }
  },
  mounted() {
    console.log('map mounted')
    this.reset()
  },
  activated() {
    console.log('map activated')
    this.init()
  },
  methods: {
    // 初始化地图
    init() {
      if (this.mapLayers) {
        return
      }
      const $el = this.$refs.map
      // 影像和矢量地图
      // const sateLayer = new CTileLayer(2, 18, 'sate', null, null)// 影像
      // const sateLabelLayer = new CTileLayer(2, 18, 'satelabel', null, null)// 影像注记
      // const mapLayer = new CTileLayer(2, 18, 'map', null, null)// 矢量
      // const mapLabelLayer = new CTileLayer(2, 18, 'maplabel', null, null)// 矢量注记

      var tianditusateLayer = new CTileLayer({
        zbound: [2, 18],
        tileName: 'sate',
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
        url: 'http://t{s}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=80310778300778a15b36e70a6da5af00'
      })

      var tianditusateLabelLayer = new CTileLayer({
        zbound: [2, 18],
        tileName: 'satelabel',
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
        url: 'http://t{s}.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=80310778300778a15b36e70a6da5af00'
      })

      var tianditumapLayer = new CTileLayer({
        zbound: [2, 18],
        tileName: 'map',
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
        url: 'http://t{s}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=80310778300778a15b36e70a6da5af00'
      })

      const tianditumapLabelLayer = new CTileLayer({
        zbound: [2, 18],
        tileName: 'maplabel',
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
        url: 'http://t{s}.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=80310778300778a15b36e70a6da5af00'
      })

      const TianDiTuBASEMAP = new CMapType([tianditumapLayer], '矢量')
      const TianDiTuVECTORMAP = new CMapType([tianditumapLayer, tianditumapLabelLayer], '矢量')
      const TianDiTuSATEMAP = new CMapType([tianditusateLayer, tianditusateLabelLayer], '影像')

      const VECTORMAP = new CMapType([tianditumapLayer, tianditumapLabelLayer], '矢量')
      const SATEMAP = new CMapType([tianditusateLayer, tianditusateLabelLayer], '影像')
      // const VECTORMAP = new CMapType([mapLayer, mapLabelLayer], '矢量')
      // const SATEMAP = new CMapType([sateLayer, sateLabelLayer], '影像')

      const { getCenterPoint, zoom } = this
      // 初始化配置
      const opts = {
        mapTypes: [VECTORMAP],
        center: getCenterPoint(),
        zoom: zoom
      }
      // 加载图层
      this.mapLayers = new CMapLayers($el, opts)
      this.mapLayers.addMapTypeControl()

      bindEvents.call(this, this.mapLayers)

      // 此处强行初始化一次地图 回避一个由于错误的 center 字符串导致初始化失败抛出的错误
      // this.mapLayers.reset()
      this.reset()
      this.mapLayers.setCenter(getCenterPoint(), zoom)
      this.$emit('ready', { mapLayers: this.mapLayers })
      // this.renderMarkers()
    },
    renderAffectAP(wellObj) {
      // this.wellObj = wellObj
      const { mapLayers } = this
      if (!mapLayers) {
        return
      }
      this.removeOverlays() // 清除所有overlay
      // 渲染井
      if (this.wellObj != null) {
        this.affectCircle = {
          lat: this.wellObj.lat,
          lng: this.wellObj.lng,
          radius: this.wellObj.radius
        }
        if (this.wellObj.affectPipes) {
          this.affectPipes = this.wellObj.affectPipes
        }
        this.renderWell()
      }
      // 当影响区域不为空的时候显示影响区域
      if (this.affectCircle != null) {
        this.renderAffectArea()
      }
      // 渲染管线
      if (this.affectPipes && this.affectPipes.length > 0) {
        this.renderAffectPipes()
      }
    },
    removeAffectAP() {
      // 移除井
      // if (this.wellObj != null) {
      //   this.removeWell()
      // }
      // 移除影响区域
      if (this.affectArea != null) {
        this.removeAffectArea()
      }
      // 移除管线
      if (this.affectPipes.length > 0) {
        this.removeAffectPipes()
      }
    },
    // 渲染影响区域
    renderAffectArea() {
      const { mapLayers, affectCircle } = this
      // 绘制影响区域
      const opts = { color: '#c45366', weight: 2, opacity: 0.9, fill: true, fillColor: '#009900', fillOpacity: 0.4 }
      this.affectAreaOverlay = mapLayers.drawCircle(new CLatLng(affectCircle.lat, affectCircle.lng), affectCircle.radius, opts)
    },
    // 移除影响区域
    removeAffectArea() {
      const { mapLayers } = this
      if (this.affectAreaOverlay) {
        mapLayers.removeOverlay(this.affectAreaOverlay)
        this.affectAreaOverlay = null
      }
    },
    // 渲染井
    renderWell() {
      const { mapLayers, size, anchor, wellObj } = this
      const options = {
        url: './static/images/map_images/alarm-well1.png',
        size: size,
        anchor: anchor
      }
      const cmapIcon = createIcon(options)
      const opts = {
        icon: cmapIcon,
        title: wellObj.wellCode,
        draggable: false
      }
      this.wellOverlay = new CMarker(new CLatLng(wellObj.lat, wellObj.lng), opts)
      mapLayers.addOverlay(this.wellOverlay)
      mapLayers.setZoom(17)
      mapLayers.setCenter(new CLatLng(wellObj.lat, wellObj.lng))
    },
    // 移除井
    removeWell() {
      const { mapLayers } = this
      if (!this.wellOverlay) {
        mapLayers.removeOverlay(this.wellOverlay)
        this.wellOverlay = null
      }
    },
    // 渲染问题影响管线
    renderAffectPipes() {
      // TODO: 渲染管线
    },
    // 移除影响管线
    removeAffectPipes() {
      const { mapLayers } = this
      for (const overlay of this.affectLineOverlays) {
        mapLayers.removeOverlay(overlay)
      }
      this.affectLineOverlays = []
    },
    // 渲染关阀影响区域
    renderCloseArea() {
      const { mapLayers, closeCircle } = this
      // 绘制影响区域
      const opts = { color: '#c45366', weight: 2, opacity: 0.9, fill: true, fillColor: '#009900', fillOpacity: 0.4 }
      this.closeAreaOverlay = mapLayers.drawCircle(new CLatLng(closeCircle.lat, closeCircle.lng), closeCircle.radius, opts)
    },
    // 移除关阀影响区域
    removeCloseArea() {
      const { mapLayers } = this
      if (this.closeAreaOverlay) {
        mapLayers.removeOverlay(this.closeAreaOverlay)
        this.closeAreaOverlay = null
      }
    },
    // 渲染关阀影响管线
    renderClosePipes() {
      // TODO: 渲染管线
    },
    // 移除关阀影响管线
    removeClosePipes() {
      const { mapLayers } = this
      for (const overlay of this.closeLineOverlays) {
        mapLayers.removeOverlay(overlay)
      }
      this.closeLineOverlays = []
    },
    // 清除所有overlay
    removeOverlays() {
      const { mapLayers } = this
      mapLayers.clearOverlays()
    },
    // 获取中点
    getCenterPoint() {
      const { center } = this
      console.log('getCenterPoint:' + center.lat + ',' + center.lng)
      return new CLatLng(center.lat, center.lng)
    },
    initMap(CMapLayers) {
      this.CMapLayers = CMapLayers
      this.init(CMapLayers)
    },
    getMapScript() {
      // 动态获取cmap的脚本
      // const TMapURL = 'http://satellite.casm.ac.cn:8020/geowinmap/api?version=tapi&map=map&utils=mapcase'
      const TMapURL = 'http://119.3.228.125:8080/geowinmap/api?version=tapi&map=map&utils=mapcase,mapv'
      return new Promise((resolve, reject) => {
        console.log(window.CMapLayers)
        // 如果已加载直接返回
        if (typeof window.CMapLayers !== 'undefined') {
          console.log('地图脚本初始化成功1111...')
          resolve(window.CMapLayers)
          // return true
        } else {
          // 插入script脚本
          const scriptNode = document.createElement('script')
          scriptNode.setAttribute('type', 'text/javascript')
          scriptNode.setAttribute('src', TMapURL)

          if (scriptNode.readyState) { // IE
            scriptNode.onreadystatechange = function() {
              if (scriptNode.readyState === 'loaded' || scriptNode.readyState === 'complete') {
                scriptNode.onreadystatechange = null
                console.log('地图脚本初始化成功2...')
                // eslint-disable-next-line
                resolve(window.CMapLayers)
              }
            }
          } else { // 其他浏览器
            scriptNode.onload = function() {
              console.log('地图脚本初始化成功3...')
              resolve(window.CMapLayers)
            }
          }
          document.body.appendChild(scriptNode)
          console.log(scriptNode)
        }
      })
    },
    reset() {
      console.log('map reset')
      const { initMap, getMapScript } = this
      getMapScript()
        .then(initMap)
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss">
  .mapDiv{
    width:100%;
    height: calc(100vh - 84px);
  }
  /*.alarm-window{*/
    /*max-width: 250px;*/
  /*!*background-color: #ffeaf1;*!*/
    /*.alarm-header {*/
      /*padding: 10px 10px 5px 10px;*/
      /*line-height: 30px;*/
      /*color: red;*/
      /*font-weight: bold;*/
      /*!*background-color: #ffecec;*!*/
    /*}*/
    /*.alarm-body{*/
      /*padding: 5px 10px 10px 10px;*/
      /*line-height: 23px;*/
      /*font-size: 14px;*/
    /*.alarm-red{*/
      /*color: #ff0000;*/
    /*}*/
  /*}*/
  /*}*/
</style>