vue中使用百度地图

方式一:vue-baidu-map

<template>
  <div class="map-content map-area">
    <div id="map" class="map" style="width:100%;height:100%">
      <baidu-map class="bm-view" :center="center" :zoom="zoom" :scroll-wheel-zoom="true" style="width: 100%; height: 100%"
        @ready="handler" ak="buF4pdBmwIDt1nB7buqAw6xoY5y1SCRd">
        <bm-marker v-for="(marker, index) in markers" :key="index" :dragging="false" :position="{ lng: marker.lng, lat: marker.lat }"
          @click="infoWindowOpen(marker)" :icon="{ url: marker.icon, size: { width: 32, height: 32 } }">
          <bm-info-window :show="marker.show" @close="infoWindowClose(marker)" style="font-size: 13px" @open="infoWindowOpen(marker)">
            <div class="info-window">
              设备名称:{{ marker.deviceName }} <br /><br />
              设备地址:{{ marker.deviceAddr }} <br /><br />
              设备状态:{{ marker.deviceStatus }} <br /><br />
              经度: {{ marker.lng }} <br /><br />
              纬度: {{ marker.lat }}
            </div>
          </bm-info-window>
        </bm-marker>
      </baidu-map>
    </div>
  </div>
</template>
<script>
// import map from "@/views/mixin/map";
import online from "../assets/images/online.svg"
import offline from "../assets/images/offline.svg"
import {
  getRealtimeDataByGroupId
} from "@/api/device"
// 个性化地图样式文件引入
const custom_map_config = require('../assets/mapJson/custom_map_config.json')
export default {
  // mixins: [map],
  // components: {
  //   BaiduMap,
  //   BmMarker,
  //   BmInfoWindow
  // },
  data() {
    return {
      // 地址信息
      address: null,
      center: { lng: 0, lat: 0 },
      //地图展示级别
      zoom: 11,
      // 标注信息
      markers: [],
      normal: online,
      offline: offline,
      mapInterval: '',
      map: {}
    };
  },
  methods: {
    handler({ BMap, map }) {
      this.map = map;
      this.center.lng = 108.943777;
      this.center.lat = 34.521614;
      this.zoom = this.zoom;
      function changeMapStyle() {
        try {
          map.setMapStyleV2({
            styleJson: custom_map_config
          });
        } catch (e) {
          setTimeout(function () {
            changeMapStyle()
          }, 50)
        }
      }
      this.$nextTick(() => {
        changeMapStyle();
        this.getDeviceRealtime();
        this.mapInterval = setInterval(()=> {
            this.getDeviceRealtime();
        },60000)
      })
    },
    // 信息窗口关闭
    infoWindowClose(marker) {
      marker.show = false;
    },
    // 信息窗口打开
    infoWindowOpen(marker) {
      marker.show = true;
    },
    getDeviceRealtime(){
      this.markers.forEach(item=>{
        if(item.show === true){
          this.infoWindowClose(item);
        }
      })
      getRealtimeDataByGroupId({groupId: ''}).then(res=>{
        this.markers = [];
        const resData = res.data.map(item=> {
          let newItem = {}
          newItem['show'] = false;
          newItem['icon'] = this[item.deviceStatus];
          newItem.deviceStatus = item.deviceStatus === 'normal' ? '在线' : '离线';
          newItem.deviceName = item.deviceName;
          newItem.deviceAddr = item.deviceAddr;
          newItem.lng = item.lng;
          newItem.lat = item.lat;
          return newItem;
        })
        this.markers = resData;
      })
    }
  },
  beforeDestroy() {
    if (this.mapInterval) {
        clearInterval(this.mapInterval);
        this.mapInterval = '';
    }
  },
  destroyed() {
  },
};
</script>
<style lang="scss" scoped>
.map-area {
  width: 100%;
  height: 100%;
  border: 1px solid #0a4887;
  padding: 2px;
  // csss实现四角边框
  background: linear-gradient(#5ff1f3, #5ff1f3) left top,
    linear-gradient(#5ff1f3, #5ff1f3) left top,
    linear-gradient(#5ff1f3, #5ff1f3) right top,
    linear-gradient(#5ff1f3, #5ff1f3) right top,
    linear-gradient(#5ff1f3, #5ff1f3) left bottom,
    linear-gradient(#5ff1f3, #5ff1f3) left bottom,
    linear-gradient(#5ff1f3, #5ff1f3) right bottom,
    linear-gradient(#5ff1f3, #5ff1f3) right bottom;
  background-repeat: no-repeat;
  background-size: 2px 25px, 25px 2px, 2px 25px, 25px 2px;
}

.alarm-list-dialog {
  ::v-deep .el-dialog__body {
    padding: 0;
  }
}

::v-deep .map .anchorBL {
  display: none;
}

.bm-view {
        width: 100%;
        height: 100%; //BaiduMap 组件容器本身是一个空的块级元素,如果容器不定义高度,百度地图将渲染在一个高度为 0 不可见的容器内。
    }
</style>

方式二:引入https://api.map.baidu.com/getscript?v=3.0

(建议采用这种方式,可扩展性强,第一种方式vue版本插件已不再维护)

<template>
  <div class="map-content map-area">
    <div id="myMap" class="map" >
    </div>
  </div>
</template>
</template>

<script>
var BMap = {};
var map = {};
import online from "../assets/images/online.svg"
import offline from "../assets/images/offline.svg"
import alarm from "../assets/images/alarm.svg"
import online64 from "../assets/images/online-64.svg"
import offline64 from "../assets/images/offline-64.svg"
import alarm64 from "../assets/images/alarm-64.svg"
// import { getRealtimeDataByGroupId } from "@/api/device"
// 个性化地图样式文件引入
const custom_map_config = require('../assets/mapJson/custom_map_config.json')
export default {
  data() {
    return {
      markers: [],
      normal: online,
      offline: offline,
      alarm: alarm,
      normal64: online64,
      offline64: offline64,
      alarm64: alarm64,
      mapInterval: '',
      TEMP: '', // 温度
      HUMI: '', // 湿度
      resData: ''
    }
  },
  mounted() {
    this.$root.$on('deviceStatusData',(res)=>{
      this.resData = res;
    })
    // 加载百度地图
    this.loadMapScript();
    // setTimeout(() => {
    //   // 获取地图标注信息
    //   this.getMarkers();
    //   this.mapInterval = setInterval(() => {
    //     this.getMarkers();
    //   }, 60000)
    // }, 500);
    this.TEMP = window.localStorage.getItem('temperature');
    this.HUMI = window.localStorage.getItem('humidity');
    this.$root.$on('threshold', (threshold) => {
      const {temperature,humidity} = JSON.parse(threshold);
      this.TEMP = temperature;
      this.HUMI = humidity;
    })
  },
  methods: {
    loadMapScript() {
      let script = document.createElement("script");
      script.type = "text/javascript";
      script.src = "https://api.map.baidu.com/getscript?v=3.0";
      script.onload = () => {
        this.init();
      };
      document.body.appendChild(script);
    },
    init() {
      BMap = window.BMap;
      map = new BMap.Map("myMap");
      map.centerAndZoom(new BMap.Point(108.977074, 34.415616), 14); //初始化地图,设置中心点坐标和地图
      // map.setCurrentCity("西安"); //设置地图显示的城市(api要求必填,实际上可不填)
      map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
      map.setMapStyleV2({
        // styleId: '36397652f1f0168039859fe3aeeac05f'
        styleJson: custom_map_config
      })
      if(!this.resData){
        this.$root.$on('deviceStatusData',(res)=>{
          this.getMarkers(res);
        })
      }else{
        this.getMarkers(this.resData);
      }
    },
    // 地图上添加标注并增加信息框
    addMarker(markers) {
      map.clearOverlays();
      markers.forEach(item => {
        const { lng, lat, deviceName, deviceStatus, deviceAddr, icon } = item;
        let clientWidth = document.body.clientWidth||document.documentElement.clientWidth||window.innerWidth;
        let myIcon = (clientWidth && clientWidth > 1920) ? new BMap.Icon(icon, new BMap.Size(64, 64)) : new BMap.Icon(icon, new BMap.Size(32, 32))
        const marker = new BMap.Marker(new BMap.Point(lng, lat), { icon: myIcon });
        map.addOverlay(marker);
        var opts = {
          width: this.fontSize(2),     // 信息窗口宽度
          height: this.fontSize(2.4),     // 信息窗口高度
          title: deviceName, // 信息窗口标题
          enableMessage: true,//设置允许信息窗发送短息
          message: ""
        }
        var infoWindow = new BMap.InfoWindow(`
        <span>设备名称:</span> ${deviceName}<br/><br/>
        <span>设备地址:</span> ${deviceAddr}<br/><br/>
        <span>设备状态:</span> ${deviceStatus}<br/><br/>
        <span>经度: </span> ${lng}<br/><br/>
        <span>纬度: </span>${lat}`, opts);  // 创建信息窗口对象 
        // marker.addEventListener("click", function () {
        //   map.openInfoWindow(infoWindow, new BMap.Point(lng, lat)); //开启信息窗口
        // });
        // 修改标注提示为悬浮显示的方式
        marker.addEventListener("mouseover", function () {
          map.openInfoWindow(infoWindow, new BMap.Point(lng, lat)); //开启信息窗口
        });
        marker.addEventListener("mouseout", function () {
          map.closeInfoWindow(infoWindow, new BMap.Point(lng, lat)); //开启信息窗口
        });
      })
    },
    getMarkers(res) {
      this.markers = this.getDeviceRealtime(res);
      this.addMarker(this.markers);
    },
    getDeviceRealtime(res1) {
      const res = JSON.parse(res1);
      const resData = res.data.map(item => {
        let attrList = item.dataItem ?? [];
        let temp = 0;
        let humi = 0;
        if (attrList.length && attrList[0]?.registerItem) {
          attrList[0].registerItem.forEach(attr=>{
            if (attr.registerName == '温度') {
              if (attr?.data) {
                temp = temp + Number(attr?.data);
              }
            }
            if (attr.registerName == '湿度') {
              if (attr?.data) {
                humi = humi + Number(attr?.data);
              }
            }
            if (Number(temp) < Number(this.TEMP) && Number(humi) > Number(this.HUMI)) {
              item.deviceStatus = 'alarm';
            }
          })
        }
        let clientWidth = document.body.clientWidth||document.documentElement.clientWidth||window.innerWidth;
        let newItem = {}
        newItem['icon'] = (clientWidth && clientWidth > 1920) ? (this[item.deviceStatus+ '64'] ) : this[item.deviceStatus];
        newItem.deviceStatus = item.deviceStatus === 'normal' ? '在线' : item.deviceStatus === 'offline' ? '离线' : '结冰告警';
        newItem.deviceName = item.deviceName;
        newItem.deviceAddr = item.deviceAddr;
        newItem.lng = item.lng;
        newItem.lat = item.lat;
        return newItem;
      })
      return resData;
    }
  },
  beforeDestroy() {
    if (this.mapInterval) {
      clearInterval(this.mapInterval);
      this.mapInterval = '';
    }
  },
}
</script>

<style lang="scss" scoped>
#myMap {
  width: 100%;
  height: 100%;
}

.map-area {
  width: 100%;
  height: 100%;
  padding: 2px;
  // csss实现四角边框
  /* border: 1px solid #002586;
  background: linear-gradient(#5ff1f3, #5ff1f3) left top,
    linear-gradient(#5ff1f3, #5ff1f3) left top,
    linear-gradient(#5ff1f3, #5ff1f3) right top,
    linear-gradient(#5ff1f3, #5ff1f3) right top,
    linear-gradient(#5ff1f3, #5ff1f3) left bottom,
    linear-gradient(#5ff1f3, #5ff1f3) left bottom,
    linear-gradient(#5ff1f3, #5ff1f3) right bottom,
    linear-gradient(#5ff1f3, #5ff1f3) right bottom;
  background-repeat: no-repeat;
  background-size: 2px 25px, 25px 2px, 2px 25px, 25px 2px; */
  /* border: 1px solid #002586; */
  /* border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px; */
    /* background: linear-gradient(to bottom,#041e73,#010362 50%,#041e73); */
    border: 1px solid #467178;
    background: rgba(94, 215, 255, 0.1);
}

/*隐藏百度logo标识*/
::v-deep .map .anchorBL {
  display: none;
}

/*修改信息框样式*/
::v-deep .map .BMap_pop .BMap_top {
  background: rgba(41, 91, 128, 0.8) !important;
  border: 0 !important;
}

::v-deep .map .BMap_pop .BMap_center {
  border: 0 !important;
  background: rgba(41, 91, 128, 0.8) !important;
}

::v-deep .map .BMap_pop .BMap_bottom {
  border: 0 !important;
  background: rgba(41, 91, 128, 0.8) !important;
}

::v-deep .map .BMap_pop div:nth-child(3) {
  background: transparent !important;
}

::v-deep .map .BMap_pop div:nth-child(3) div {
  border-radius: 3px;
  background: rgba(41, 91, 128, 0.8) !important;
  border: 0 !important;
}

::v-deep .map .BMap_pop div:nth-child(1) {
  border-radius: 3px 0 0 0;
  background: transparent !important;
  border: 0 !important;
}

::v-deep .map .BMap_pop div:nth-child(1) div {
  background: rgba(41, 91, 128, 0.8) !important;
}

::v-deep .map .BMap_pop div:nth-child(5) {
  border-radius: 0 0 0 3px;
  background: transparent !important;
  border: 0 !important;
}

::v-deep .map .BMap_pop div:nth-child(5) div {
  border-radius: 3px;
  background: rgba(41, 91, 128, 0.8) !important;
}

::v-deep .map .BMap_pop div:nth-child(7) {
  background: transparent !important;
  // left: 226px;
}

::v-deep .map .BMap_pop div:nth-child(7) div {
  border-radius: 3px;
  background: rgba(41, 91, 128, 0.8) !important;
}

/*信息框内容*/
::v-deep .map .BMap_pop .BMap_bubble_title {
  font-size:20px;
  color: #48e3eb;
  margin-top: 5px;
  margin-bottom: 10px !important;
  line-height: 24px !important;
  font-weight: 600;
}
::v-deep .map .BMap_pop .BMap_bubble_content {
  font-size:16px;
  color: #48e3eb;
}

/*替换箭头*/
::v-deep .map  img[src="http://api.map.baidu.com/images/iw3.png"] {
    width:1px !important;
    height: 1px !important;
}

::v-deep .map img[src="https://api.map.baidu.com/images/iw3.png"] {
    opacity: 0.7;
    filter: alpha(opacity=70);
    width:1px !important;
    height: 1px !important;
}


</style>

注意事项:踩坑

  1. 引用百度地图,在页面访问时缩放比例需设置位100%,放大或者缩小会导致地图字体重叠,图形加载不完整等错误,且无法解决;
  2. 代码中秘钥省略,需要根据自己申请的秘钥加上
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值