Vue引入原生JS 高德地图实现Maker点击创建带下标聚合效果

环境:vue 2.9.6

本来看着vue集成了相关的高德地图,本以为就可以很方便的调用,结果发现功能很不齐全,本次涉及到的基本maker操作都没有,无奈只好引入原生js,遇到了很多坑记录下:

代码现行:

<script src="http://webapi.amap.com/maps?v=1.3&key=xxx"></script>
<script src="http://webapi.amap.com/ui/1.0/main.js"></script>

二话不说先在index.html中直接引入高德相关

写成组件化():

<!--
  描述:拖放地图组件,默认尺寸是 500 * 300

  接收属性参数:
    lat: 纬度
    lng: 经度

  自定义事件:
    drag: 拖放完成事件

  示例:
    <mapDrag @drag="dragMap" lat="22.574405" lng="114.095388"></mapDrag>
-->
<template>
  <div class="m-map">
    <div id="js-container" class="map" >正在加载数据 ...</div>
    <img style=" position:relative;top: -55px;left: 5px;width: 45px;" src="../../assets/images/jw_logo.png" >
  </div>
</template>

<script>
import { MapKey, BuildingPng} from '../config/config'
export default {
  props: ['lat', 'lng'],
  data () {
    return {
      cluster:null,
      dragStatus: false,
      AMapUI: null,
      AMap: null,
      marker:null,
      map:null,
      map_lng:null,
      map_lat:null,
      geocoder:null,
      strLen:0,
      buildingList:[],
      switchBoo:true,
      switchWatch:true,
      markers:[]
    }
  },
  mounted(){
  },
  watch: {
    markers(){
      if (this.switchWatch){
        this.addCluster(1);
        this.switchWatch = false;
      }
    }
  },
  methods: {
    initMapMaker(){
      this.buildingList = [];
      let that = this;
      $.ajax({
        type: "get",
        url: 获取请求所有需要创建的makers,
        dataType: "json",
        success: function(data) {
          if (data.code === 200){
            that.buildingList = data.buildings;
            that.buildingList.forEach((obj)=>{
              that.addMarker(obj.longitude, obj.latitude, obj.name, obj.email, 1, obj.uniqueKey);
            })
          }
        },
      });
    },
    clear(){
      this.placeSearch.clear();
    },
    async initInfo(){
      this.initMap();
    },
    //获取并展示当前城市信息
    logMapinfo(){
        this.map.getCity( function(info){
           return info.city;
        });
    },
    //计算字符串长度
    strLength(str){
      let realLength = 0, len = str.length, charCode = -1;
      for (let i = 0; i < len; i++) {
        charCode = str.charCodeAt(i);
        if (charCode >= 0 && charCode <= 128)
          realLength += 1;
        else
          realLength += 2;
      }
      return realLength;
    },
    //设置视角
    setView(lng, lat){
      this.map.setZoomAndCenter(16,[lng, lat]);
    },
    // 创建标记
    addMarker(lng, lat, mapName, email, type, uniqueKey) {

      if (email !== '' && email !== null ){
        let shifting = 0;
        let span = '<span  class="map-email" style="margin-top: 6px">'+email+'</span>';
        //若名称大于邮箱展示,则重新设置偏移
        if (this.strLength(mapName) > this.strLength(email)){
          shifting =-5 * (this.strLength(mapName) - 16)  + 5;
        }else {
          if (this.strLength(email) < 16){
            shifting = -this.strLength(email) * 10 + 140;
          }
        }
        if (lng !== null && lat !== null){
          if (type === 1){
            this.marker = new AMap.Marker({
              icon: BuildingPng,
              position: [lng,lat],
              offset: new AMap.Pixel(-13, -30),
              label:{
                content: '<div class="map-name"><span>'+mapName+'</span>'+span+'</div>',
                offset: new AMap.Pixel(-55 + shifting, 55)
              },
              extData:uniqueKey
            });
          }else {
            this.marker = new AMap.Marker({
              icon: BuildingPng,
              position: [lng,lat],
              offset: new AMap.Pixel(-13, -30),
              extData:uniqueKey
            });
          }
          this.markers.push(this.marker);
          // this.marker.setMap(this.map);
          let that = this;
          new AMap.event.addListener(this.marker, 'click', function(e) {
            //得到的数据
            that.$store.commit('setMapShow_uniqueKey', JSON.parse(JSON.stringify(e.target.getExtData())));
            const { href } = that.$router.resolve({ name:'MapShow'});
            window.open(href, '_blank', )
          });
        }
      }
    },
    // 清除 marker
    clearMarker() {
        if (this.marker) {
            this.marker.setMap(null);
            this.marker = null;
        }
    },
    //鼠标单击事件获取坐标
    showInfoClick(e){
        this.map_lng = e.lnglat.getLng();
        this.map_lat = e.lnglat.getLat();
    },
    // 搜索
    handleSearch () {
      this.setView(104.071078, 30.545154);
    },
    //设置建筑
    setBuildingList(val){
      if (val === ''){
        this.map.setZoomAndCenter(16,[104.065861, 30.657401]);
      }else {
        this.buildingList = val;
      }
    },
    //聚合makers
    addCluster(tag) {
      if (this.cluster) {
        this.cluster.setMap(null);
      } else if (tag === 1) {//自定义图标
        var sts = [{
          url: require('../images/TogetherPng.png'),
          size: new AMap.Size(43, 50),
          offset: new AMap.Pixel(-13, -30),
          imageOffset:new AMap.Pixel(0, 0),
          textColor:'#ffffff',
          textSize: 20
        },
          {
            url: require('../images/TogetherPng.png'),
            size: new AMap.Size(43, 50),
            offset: new AMap.Pixel(-13, -30),
            imageOffset:new AMap.Pixel(0, 0),
            textColor:'#ffffff',
            textSize: 20
          },
          {
            url: require('../images/TogetherPng.png'),
            size: new AMap.Size(43, 50),
            offset: new AMap.Pixel(-13, -30),
            imageOffset:new AMap.Pixel(0, 0),
            textColor:'#ffffff',
            textSize: 20
          },
          {
            url: require('../images/TogetherPng.png'),
            size: new AMap.Size(43, 50),
            offset: new AMap.Pixel(-13, -30),
            imageOffset:new AMap.Pixel(0, 0),
            textColor:'#ffffff',
            textSize: 20
          }];
        let Amap = this.map;
        let markers = this.markers;
        let cluster = this.cluster;
        Amap.plugin(["AMap.MarkerClusterer"],function() {
          cluster = new AMap.MarkerClusterer(Amap, markers, {
            styles: sts,
            gridSize: 80
          });
        });
      } else {//默认样式
        let Amap = this.map;
        let markers = this.markers;
        Amap.plugin(["AMap.MarkerClusterer"],function() {
          cluster = new AMap.MarkerClusterer(Amap, markers, {gridSize: 80});
        });
      }
    },
    mapSetZoom(){

    },
    //缩放比例回调
    mapZoomend(){
      let zoom = this.map.getZoom();
      console.debug(zoom + "缩放比例")
    },
    clearMap(){
      this.map.clearMap();
    },
    // 实例化地图
    async initMap () {
        // 加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分
        this.AMapUI = window.AMapUI;
        let AMapUI =window.AMapUI;
        let AMap = this.AMap = window.AMap;
        if (typeof (AMapUI) == "undefined"){
        }
        AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
          let mapConfig = {
            zoom: 14,//初始化地图层级
            // cityName: MapCityName,
            resizeEnable: true //是否监控地图容器尺寸变化
          };
          if (this.lat && this.lng) {
            mapConfig.center = [this.lng, this.lat]
          }
          let marker, map = new AMap.Map('js-container', mapConfig);
          this.map = map;
          this.marker = marker;
          this.initMapMaker();
          map.on('zoomend', this.mapZoomend);
          map.on('click', this.showInfoClick);
            let city = this.logMapinfo();
          // 启用工具条
          AMap.plugin(['AMap.ToolBar'], function () {
            map.addControl(new AMap.ToolBar({
              position: 'RB'
            }))
          });
          // 创建地图拖拽
          let positionPicker = new PositionPicker({
            mode: 'dragMap', // 设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'
            map: map // 依赖地图对象
          });
          // 拖拽完成发送自定义 drag 事件
          positionPicker.on('success', () => {
            // 过滤掉初始化地图后的第一次默认拖放
            if (!this.dragStatus) {
              this.dragStatus = true
            }
          });
          // 启动拖放
          positionPicker.start();
          //绑定地图移动事件
          map.setCity(city);
        });
      }
  },
  async created () {
    this.initInfo();
  },
}
</script>
<style>
  /**
    局部覆盖原生样式
   */
  .my_input .el-input__inner{
    background:rgba(28,29,29,1);
    border:1px solid rgba(0,0,0,1);
    border-radius:20px;
  }
</style>
<style lang="css">
  .amap-logo {
    display: none;
  }
  .amap-copyright {
    opacity:0;
  }
.my_input{position: marker;width:400px;height:40px;}
.m-map{ width: 100%; height: 100%; position: relative; }
.m-map .map{ width: 100%; height: 100%; }
.m-map .search_gaode{ position: absolute; top: 30px; left: 10px; width: 285px; z-index: 1; }
.m-map .result{ max-height: 300px; overflow: auto; margin-top: 10px; }
.m-map .amap-marker-label{
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family:Source Han Sans CN;
    font-weight:400;
    width:auto;
    padding: 7px 15px 7px 15px;
    height:41px!important;
    background:rgba(19,19,24,1);
    box-shadow:0px 3px 7px 0px rgba(0, 0, 0, 0.35);
    border-radius:15px;
}
.m-map .amap-ui-misc-positionpicker{
  display: none;
}
.m-map .map-name{
  font-size:16px;
  color: white;
  display:flex;
  flex-direction:column;
  align-items:center
}
.m-map .map-email{
  font-size:12px;
  color: #A0A0A0;
}
</style>

引入的config.js

// 高德地图 key
export const MapKey = 'xxx';
//makers图标
export const BuildingPng = 'data:image/png;base64,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';

遇到的几大坑:

①在ajax返回值中this的指向会改变,只能在外部先定义才能指向到vue

②高德地图在嵌入页面的时候会出现加载地图不完整 让初始化方法async 方式

③maker的下标显示label 这里有个很麻烦的地方如果你的标签显示信息长度不相同动态的,它这里没有自动居中设置只能设置偏移量,我这里只是简单的数学计算让它居中,没有深入研究

④maker的监听事件也和①一样内部需要转this指向

label:{
                content: '<div class="map-name"><span>'+mapName+'</span>'+span+'</div>',
                offset: new AMap.Pixel(-55 + shifting, 55)
              },
 let that = this;
          new AMap.event.addListener(this.marker, 'click', function(e) {
            //得到的数据
            that.$store.commit('setMapShow_uniqueKey', JSON.parse(JSON.stringify(e.target.getExtData())));
            const { href } = that.$router.resolve({ name:'MapShow'});
            window.open(href, '_blank', )
          });

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值