vue3使用在线百度,标记点、序号label、信息弹窗、最佳可视区域

在index.html文件中引入百度地图src

<script type="text/javascript" src="http://api.map.baidu.com/api?type=webgl&v=1.0&ak=你的ak"></script>

然后封装地图组件

<template>
  <div class="contain">
    <div id="allmap">
    </div>
    <div class="legendBox" v-show="props.showLegend">
      <template v-for="item in addressMap" :key="item.value">
        <div class="legendBox-item" v-if="!item.hidden">
          <img :src="item.icon" :alt="item.label" />
          <span class="legendBox-item-word">{{ item.label }}</span>
        </div>
      </template>
    </div>
  </div>
</template>

<script setup>
import bluePeople from "@/assets/blue-robot.png";
import houseIcon from "@/assets/map/house.png";
import peperIcon from "@/assets/map/peper.png";
import projectIcon from "@/assets/map/project.png";
import connectIcon from "@/assets/map/connect.png";
import shadowIcon from "@/assets/map/shadow.png";
import gasIcon from "@/assets/map/gas.png";
import chooseIcon from "@/assets/map/isChoose.png";
// import "leaflet-rotatedmarker";
const addressMap = [];//右下角图例
const props = defineProps({
  heat: {
    type: Array,
    default: () => [],
  },
  maker: {
    type: Array,
    default: () => [],
  },
  seMarker: {
    type: Number,
    default: 0,
  },
  showLegend: {
    type: Boolean,
    default: true,
  },
  zoom: {
    type: Number,
    default: 0,
  }
});

let BMapGL = null;
let map = null;
// 初始化地图
const initMap = () => {
  nextTick(() => {
    BMapGL = window.BMapGL;
    map = new BMapGL.Map("allmap",{ // allmap必须和dom上的id一直
      minZoom: 3,
      maxZoom: 20
    });
    // map.centerAndZoom(
    //   new BMapGL.Point(116.404, 39.925),
    //   props.zoom,
    // ); // 初始化地图,设置中心点坐标和地图级别
    map.enableScrollWheelZoom(true);
    var scaleCtrl = new BMapGL.ScaleControl();  // 添加比例尺控件
    map.addControl(scaleCtrl);
    var zoomCtrl = new BMapGL.ZoomControl({
	    anchor: BMAP_ANCHOR_TOP_LEFT,
	    offset: new BMapGL.Size(20, 20),
    });
    map.addControl(zoomCtrl);
  })
};


onMounted(initMap);

const makerList = ref([]);
const infoWindowList = ref([]);
const createIcon = (type) => {
  return new BMapGL.Icon(
    addressMap.find((c) => c.value === type)?.icon || peperIcon,
    new BMapGL.Size(30, 30),
  )
};
const createMaker = (val) => {
  if (makerList.value.length) {
    map.clearOverlays();
    makerList.value = [];
    infoWindowList.value = [];
  }
  val.forEach((item) => {
    const label = item.condition.split("_").join("<br />");
    var pt = new BMapGL.Point(item.position[0], item.position[1]);
    var infoWindow = new BMapGL.InfoWindow(label,{
      offset: new BMapGL.Size(0, -16) //解决mouseover - mouseout事件 信息窗口闪动问题
    });
    infoWindowList.value.push(infoWindow)
    // 图标序号标记
    if (item.num) {
      const numLabel = new BMapGL.Label(item.num, {
      //调整数字跟点标记的位置关系
        offset: new BMapGL.Size(-8.5, -11),
      });
      numLabel.setStyle({
        background: "#fff",
        color: "#999",
        border: "none", 
        width: "15px",
        height: "15px",
        lineHeight: "15px",
        textAlign: "center",
        borderRadius: "50%",
      });
      //对label的样式进行设置
      const wordTip = new BMapGL.Icon(peperIcon, new BMapGL.Size(30, 30))
      const wordMarker = new BMapGL.Marker(pt, { icon: wordTip })
      wordMarker.setLabel(numLabel);
      makerList.value.push(wordMarker);
      map.addOverlay(wordMarker);
      wordMarker.addEventListener("mouseover", function(){
        map.openInfoWindow(infoWindow, pt);
      });
      wordMarker.addEventListener("mouseout", function(){
        map.closeInfoWindow(infoWindow, pt);
      });
    } else {
      // 图标标记
      const icon = createIcon(item.type);
      const marker = new BMapGL.Marker(pt, { icon });
      makerList.value.push(marker);
      map.addOverlay(marker);
      marker.addEventListener("mouseover", function(){
          map.openInfoWindow(infoWindow, pt);
      });
      marker.addEventListener("mouseout", function(){
        map.closeInfoWindow(infoWindow, pt);
      });
    }
  });
  setViewport(makerList.value)
};
watch(() => props.maker, createMaker);
/**
 * 使用BMap.Viewport来获取这些点的最佳显示视图
 * @param {*} markers 标点集合
 */
const setViewport = (markers) => {
  var points = markers.map(function(marker) {
    return marker.getPosition(); // 此处获取每个标记的地理位置点
  });

  var view = map.getViewport(points); // 计算这些点的最佳视图
  var mapZoom = view.zoom;
  if(props.zoom != 0) {//单点标记时候展示地标
    mapZoom = props.zoom
  }
  var centerPoint = view.center;
  map.centerAndZoom(centerPoint,mapZoom); // 动态更新地图的中心点和Zoom级别
}
/**
 * @param {*} seq 序号
 */
const dispatchMarker = (seq) => {
  if (makerList.value.length) {
    // 关闭所有信息窗口
    makerList.value.forEach((marker,idx) => map.closeInfoWindow(infoWindowList.value[idx]));
    // 打开选定的信息窗口
    if(seq > 0) {
      const selectedMarker = makerList.value[seq - 1];
      map.openInfoWindow(infoWindowList.value[seq - 1],selectedMarker.getPosition());
    }
  }
};
watch(() => props.seMarker, dispatchMarker);
</script>

<style lang="scss" scoped>
.contain {
  width: 100%;
  height: 100%;
  position: relative;
  #allmap {
    width: 100%;
    height: 100%;
    position: relative;
    /* 去除水印 */
    :deep(.BMap_cpyCtrl) {
      display: none;
    }
    :deep(.anchorBL) {
      display: none !important;
    }
    :deep(.BMap_bubble_content) {
      padding-bottom: 20px;
      box-sizing: border-box;
    }
  }
  .legendBox {
      width: 150px;
      padding: 10px;
      font-size: 14px;
      background: rgba(255, 255, 255, 0.8);
      position: absolute;
      right: 10px;
      bottom: 10px;
      z-index: 1002;
      border-radius: 11px;
      &-item {
        height: 30px;
        display: flex;
        align-items: center;
        margin-bottom: 10px;
        img {
          height: 100%;
        }
      }
    }
}
</style>

在子组件中引入b-map,就能使用了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值