vue3项目中使用百度地图自定义覆盖物

306 阅读2分钟

这里只讲ak 使用方式

image.png

所有的有坑的地方已经在代码注释中写出

<template>
  <div style="width: 100%;height: 100%;">
    <div class="map" ref="baiduRef"></div>
  </div>
</template>
<script setup>
import { ref, onMounted, onBeforeMount } from 'vue'
const baiduRef = ref()
let map = {}
const pointCustom = ref()

// 地图初始化
function initMap() {
  let myCity = new BMap.LocalCity();
  myCity.get(
    result => {
      let geoc = new BMap.Geocoder();
      geoc.getLocation(result.center, res => {
        // 经纬度
        // console.log(result.center);
        // 位置信息
        // console.log(res.addressComponents);
        // city = res.addressComponents.province + '' + res.addressComponents.city
        // map.centerAndZoom(this.city, 15);

        map = new BMap.Map(baiduRef.value, { enableMapClick: false });
        pointCustom.value = result.center
        map.centerAndZoom(result.center, 15);
        map.enableScrollWheelZoom(true); //滚轮缩放
        // 使用此方法必须在 地图centerAndZoom 方法后 且改方法的第一个参数不能为汉字只能是坐标点
        map.setMapStyleV2({
          styleId: "d5a49e0ca596b9264c00b6fae7faab69",
        });

        // 自定义点,覆盖物
        let myIcon = new BMap.Icon("https://file.hblg.vip/biz_school/2022/08/03/8f5a74b3365440189e28d9a49e776e33.png", new BMap.Size(50, 50));
        let nowMarker = new BMap.Marker(result.center, { icon: myIcon });
        nowMarker.setZIndex(9999999)
        map.addOverlay(nowMarker);

        // 地图自定义覆盖物
        initializeMap(pointCustom.value)
      });
    },
    { enableHighAccuracy: true }
  );
}
// 地图自定义覆盖物
const initializeMap = (point) => {
  let CustomDiv = null
  const CustomOverlay = class extends BMap.Overlay {
    initialize(map) {
      const div = document.createElement('div');
      div.style.position = 'absolute'; // 必要勿删
      // div 可以使用内联样式 , class,但是必须是全局样式 scoped 内会无效
      div.innerHTML = ` <div style="font-size: 16px;">
                            <div>标题:${'自定义覆盖物'}</div>
                            <div>简介:${'可以自定义容器'}</div>
                        </div>`;
      div.setAttribute("class", "CustomOverlay") // 新增容器css 类 ,可以执行多次,但是重名的会被覆盖
      map.getPanes().labelPane.appendChild(div);
      CustomDiv = div
      return div;
    }
    draw() {  // 计算-根据中心点覆盖物的位置,默认数据(不进行加减乘除),是div左上角对应中心点
      const position = map.pointToOverlayPixel(point);
      CustomDiv.style.left =
        position.x -
        parseInt(getStyle(CustomDiv, 'width')) / 2 -
        (parseInt(getStyle(CustomDiv, 'padding-left')) +
          parseInt(getStyle(CustomDiv, 'padding-right'))) /
        2 +
        'px';
      CustomDiv.style.top = position.y - parseInt(getStyle(CustomDiv, 'height')) / 2 + 'px';
    }
  };

  const overlay = new CustomOverlay();
  map.addOverlay(overlay);

  // 监听地图移动事件,更新自定义覆盖物位置
  map.addEventListener('moveend', () => {
    const position = map.getCenter();
    overlay._point = position;
    overlay.draw();
  });

  //获取容器样式属性
  function getStyle(node, attr) {
    if (typeof getComputedStyle != 'undefined') {
      var value = getComputedStyle(node, null).getPropertyValue(attr)
      return attr == 'opacity' ? value * 100 : value //兼容不透明度,如果是不透明度,则返回整数方便计算
    } else if (typeof node.currentStyle != 'undefined') {
      //如果是IE
      if (attr == 'opacity') {
        //兼容不透明度
        return Number(
          node.currentStyle
            .getAttribute('filter')
            .match(/(?:opacity[=:])(\d+)/)[1]
        )
      } else {
        return node.currentStyle.getAttribute(attr)
      }
    }
  }
}

onMounted(() => {
  initMap()
})
</script>
<style>
.CustomOverlay {
  width: 200px;
  height: 100px;
  padding: 15px;
  background-color: rgba(255, 166, 0, 0.5);
  color: red;
  border: 1px red solid;
}
</style>

<style lang="scss" scoped>
.map {
  width: 100%;
  height: 100%
}
</style>