<template>
  <div>
    <div id="map" class="map-main"></div>
    <div class="btn-list">
      <button @click="initDrawCtrl">初始化绘制控件</button><br />
      <button @click="destoryDrawCtr">销毁绘制控件</button><br />
      <button @click="startDraw(0)">点</button>
      <button @click="startDraw(1)">圆</button>
      <button @click="startDraw(2)">线</button>
      <button @click="startDraw(3)">矩形</button>
      <button @click="startDraw(4)">多边形</button>
      <button @click="stopDraw">清除</button>
    </div>
  </div>
</template>
 
<script>
import 'leaflet'
import 'leaflet-draw'

export default {
  data() {
    return {
      // L.map 对象
      map: null,
      // L.Control.Draw 控件对象
      drawControl: null,
      // 绘制对象
      drawObj: null,
      // 图形图层组
      drawLayerGrounp: null
    }
  },
  methods: {
    // 启动绘制
    startDraw(idx) {
      // 先取消
      if (this.drawObj) {
        this.drawObj.disable()
      }
      switch (idx) {
        case 0: {
          // 点
          this.drawObj = new L.Draw.Marker(this.map, this.drawControl.options.draw.marker)
          break
        }
        case 1: {
          // 圆
          this.drawObj = new L.Draw.Circle(this.map, this.drawControl.options.draw.circle)
          break
        }
        case 2: {
          // 线
          this.drawObj = new L.Draw.Polyline(this.map, this.drawControl.options.draw.polyline)
          break
        }
        case 3: {
          // 矩形
          this.drawObj = new L.Draw.Rectangle(this.map, this.drawControl.options.draw.rectangle)
          break
        }
        case 4: {
          // 多边形
          this.drawObj = new L.Draw.Polygon(this.map, this.drawControl.options.draw.polygon)
          break
        }
      }
      // 启动
      this.drawObj.enable()
    },
    //清除绘制
    stopDraw() {
      // 删除全部绘制的图层
      if (this.drawLayerGrounp) {
        this.drawLayerGrounp.clearLayers()
      }
      // 取消绘制操作
      this.drawObj.disable()
    },
    // 初始化地图
    ininMap() {
      // 初始化地图容器并显天地图
      this.map = L.map('map', {
        //参考坐标系
        crs: L.CRS.EPSG4326,
        //不添加属性说明控件
        attributionControl: false,
        //限制显示地理范围
        maxBounds: L.latLngBounds(L.latLng(-180, -180), L.latLng(180, 180))
      })

      // 设置范围(这里是武汉)
      this.map.setView([30.59, 114.32], 10)
      // 矢量图+注记
      // let mapTypes = ['vec_c', 'cva_c'];
      // 影像图+注记
      let mapTypes = ['img_c', 'cia_c']
      // 天地图 token
      let tdtToken = 'xxxxxxxxxxxxxxxx'
      let layers = []
      for (let i = 0, len = mapTypes.length; i < len; i++) {
        let tdtUrl = `http://t0.tianditu.gov.cn/DataServer?T=${mapTypes[i]}&x={x}&y={y}&l={z}&tk=${tdtToken}`
        let layer = L.tileLayer(tdtUrl, {
          zoomOffset: 1,
          noWrap: true,
          bounds: [
            [-90, -180],
            [90, 180]
          ]
        })
        layers.push(layer)
      }
      L.layerGroup(layers).addTo(this.map)
    },
    // 交互绘制回调
    drawCreatedBack(e) {
      console.log('绘制完成', e)
      // 绘制的图形图层对象
      let drawLayer = e.layer
      // 判断当前没有图层组，需先添加
      if (!this.drawLayerGrounp) {
        //图层组
        this.drawLayerGrounp = new L.FeatureGroup()
        // 添加
        this.map.addLayer(this.drawLayerGrounp)
      }
      // 添加到图层组
      this.drawLayerGrounp.addLayer(drawLayer)
    },
    // 初始化绘制控件
    initDrawCtrl() {
      //初始化绘制控件
      this.drawControl = new L.Control.Draw({
        position: 'topright', //控件位置 'topleft'(默认), 'topright', 'bottomleft' or 'bottomright'
        draw: {
          polyline: true,
          polygon: true,
          rectangle: true,
          circle: true,
          marker: true
        }
      }).addTo(this.map) // 要添加到 L.map 对象中
      // 添加绘制完监听事件
      this.map.on(L.Draw.Event.CREATED, this.drawCreatedBack)
    },
    // 销毁绘制控件
    destoryDrawCtr() {
      // L.Control.Draw 控件对象
      this.drawControl = null
      // 绘制对象
      this.drawObj = null
      // 删除全部绘制的图层
      if (this.drawLayerGrounp) {
        this.drawLayerGrounp.clearLayers()
      }
      // 取消绘制完监听事件，避免在真正开发中，其它地方也监听了 CREATED 事件
      this.container.map.off(L.Draw.Event.CREATED, this.drawCreatedBack)
    }
  },
  mounted() {
    // 初始化地图
    this.ininMap()
    // 初始化绘制控件
    this.initDrawCtrl()
  }
}
</script>
 
<style lang="stylus" scoped>
@import '~leaflet/dist/leaflet.css';
@import '~leaflet-draw/dist/leaflet.draw.css';

.map-main {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #CCC;
}

.btn-list {
  z-index: 2000;
  position: absolute;
  top: 2px;
  left: 80px;
}
</style>