1. 业务需求

现有数据:初始经纬度信息 this.point
打开抽屉层:

  1. 创建地图
  2. 将当前初始经纬度信息使用标点方式通过图标展示出来
  3. 当前经纬度为地图中心点

点击地图:将初始标点进行清除 → 点击位置添加新标点 → 询问用户是否确定该标点位置

  1. 确定:关闭当前抽屉层,将最新点击的标点数据 this.clickPoint 传给父组件
  2. 取消:清除最新标点,展示初始标点

2. 代码示例

<!-- 地图标注弹出框 -->
<template>
  <section id="MarkPoint">
    <el-drawer
      title="地图标注"
      size="65%"
      :append-to-body="true"
      :before-close="beforeCloseHandler"
      @close="closeHandler"
      :visible.sync="innerDrawerVisible"
    >
      <!-- <cdt-map @result="mapInit"></cdt-map> -->
      <div id="map"></div>
    </el-drawer>
  </section>
</template>
<script>
// import CdtMap from '@/components/cdt-map/index'
import { mapGetters } from 'vuex'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
import { tiledMapLayer } from '@supermap/iclient-leaflet'

export default {
  name: 'MapNew',
  components: {
    // CdtMap
  },
  data() {
    return {
      innerDrawerVisible: false,
      map: null,
      point: {}, // 经纬度初始值
      clickPoint: {}, // 点击地图 - 当前点击位置经纬度
      mapIcon: require('@/assets/mapIcon.png'), // 地图标点图标
      layer: null // 标点图层
    }
  },
  computed: {
    ...mapGetters(['sysConfigData'])
  },

  watch: {
    // 侦听点击地图时,当前标点经纬度发生变化
    clickPoint: {
      handler(val) {
        if (!!val.jd) {
          this.$confirm(
            `确定标注以下经纬度吗?<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;经度 ${val.jd}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;纬度 ${val.wd}`,
            '提示',
            {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning',
              dangerouslyUseHTMLString: true
            }
          )
            .then((_) => {
              /**** 确定当前标点 ****/
              this.$message.success('标点成功')
              this.innerDrawerVisible = false
              this.$emit('updatePoint', val)
            })
            .catch((_) => {
              /**** 取消当前标点 ****/
              this.clickPoint = {}
              // 清除点击处标点
              this.map.removeLayer(this.layer)
              // 将标点标回原位置
              this.setPoint([this.point.wd, this.point.jd])
              this.$message.info('取消经纬度标注')
            })
        }
      }
    }
  },

  methods: {
    // 打开抽屉层
    open(pointer) {
      this.innerDrawerVisible = true
      this.point = pointer
      this.$nextTick(() => {
        this.mapInit()
      })
    },
    // 初始化地图
    mapInit() {
      this.map = L.map('map', {
        center: JSON.parse(this.sysConfigData['gx.arcgis.center']),
        maxZoom: this.sysConfigData['gx.arcgis.maxZoom'] * 1,
        zoom: this.sysConfigData['gx.arcgis.zoom'] * 1
      }).on('click', (ev) => {
        /**** 点击地图,清除原有坐标,将图标标点在当前点击位置 ****/
        this.clickPoint = {
          jd: ev.latlng.lng, // 经度
          wd: ev.latlng.lat // 纬度
        }
        this.map.removeLayer(this.layer) // 移除原有图标图层
        this.setPoint([ev.latlng.lat, ev.latlng.lng]) // 添加当前点击位置为新标点位置
      })

      tiledMapLayer(this.sysConfigData['gx.arcgis.mapUrl']).addTo(this.map) // 生成地图

      /**** 判断有没有经纬度,有的话标点 start ****/
      if (this.point.jd && this.point.wd) {
        // 画点线
        // // this.layer = L.polygon([JSON.parse(this.sysConfigData['gx.arcgis.center'])], {
        // this.layer = L.polygon([JSON.parse(this.sysConfigData['gx.arcgis.center']), [22, 108]], {
        //   color: 'blue',
        //   fillColor: 'none',
        //   opacity: 0.2
        // })
        // 画圆
        // this.layer = L.circle([22, 108], {
        //   color: 'green',
        //   fillColor: '#f03',
        //   fillOpacity: 0.5,
        //   radius: 10000
        // // }).addTo(this.map)
        // })
        // this.map.addLayer(this.layer)

        this.setPoint([this.point.wd, this.point.jd]) // 初始位置标点
        this.map.panTo(new L.LatLng(this.point.wd, this.point.jd)) // 当前图标位置为地图中心点
      }
      /**** 判断有没有经纬度,有的话标点 end ****/
    },

    // 标点
    setPoint(latlngArr) {
      /**
       * latlngArr数组:[纬度, 经度]
       */
      this.layer = new L.marker(latlngArr, {
        title: 'iconTitle',
        clickable: false,
        draggable: false,
        icon: L.icon({
          iconUrl: this.mapIcon, // 标点图标
          iconSize: [30, 36]
        })
      })
      this.map.addLayer(this.layer)
    },

    beforeCloseHandler(done) {
      this.$confirm('还有未保存的工作,确定关闭吗?')
        .then((_) => {
          done()
        })
        .catch((_) => {})
    },
    closeHandler() {
      this.layer = null
      if (this.map) this.map.remove() // 移除原有地图
      // this.map = null
    }
  }
}
</script>

<style lang='scss' scoped>
#map {
  position: absolute;
  top: 47px;
  bottom: 0;
  height: calc(100% - 47px);
  width: 100%;

  margin: 0 -30px;
  border: 2px solid red;
}
</style>

注意的点

  • 清除现有地图
    if (this.map) this.map.remove()
    
  • 移除指定标点图层
    this.map.removeLayer(this.layer)
    

补充示例:L.polygon() 画点线、L.circle() 画圆(该文档中未涉及)

  • 示例1 - 画点

    this.layer = L.polygon([JSON.parse(this.sysConfigData['gx.arcgis.center'])], {
      color: 'blue',
      fillColor: 'none',
      opacity: 0.2
    })
    this.map.addLayer(this.layer)
    

    在这里插入图片描述

  • 示例2 - 画线

    this.layer = L.polygon([JSON.parse(this.sysConfigData['gx.arcgis.center']), [22, 108]], {
      color: 'blue',
      fillColor: 'none',
      opacity: 0.2
    })
    this.map.addLayer(this.layer)
    

    在这里插入图片描述

  • 示例3 - 画圆

    this.layer = L.circle([22, 108], {
      color: 'green',
      fillColor: '#f03',
      fillOpacity: 0.5,
      radius: 10000
    }).addTo(this.map)
    // this.map.addLayer(this.layer) 
    /* L.circle().addTo(this.map) 或者 this.map.addLayer(this.layer)都可以将图层添加到地图 */
    

    在这里插入图片描述

3. 页面展示

  • 打开抽屉层页面展示
    在这里插入图片描述
  • 用户点击地图后,页面展示
    在这里插入图片描述
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐