方式一: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>
注意事项:踩坑
- 引用百度地图,在页面访问时缩放比例需设置位100%,放大或者缩小会导致地图字体重叠,图形加载不完整等错误,且无法解决;
- 代码中秘钥省略,需要根据自己申请的秘钥加上