直接来案例,再分析;
<template> <div ref="map" style="height: 100vh;"></div> </template><script> export default { data() { return { points: [ { lng: 116.404, lat: 39.915, name: '北京天安门' }, { lng: 121.47, lat: 31.23, name: '上海东方明珠' }, { lng: 120.16, lat: 30.25, name: '杭州西湖' }, ], labels: [], // 记录已添加的所有 label 对象 }; }, mounted() { const map = new BMap.Map(this.$refs.map);
// 循环遍历每一个坐标点,并创建标注对象和文字标注对象 const polylinePoints = this.points.map((p) => new BMap.Point(p.lng, p.lat)); // 创建用于绘制连线的 BMap.Point 数组 const polyline = new BMap.Polyline(polylinePoints, { strokeWeight: 3, strokeColor: '#F00', strokeOpacity: 0.7, strokeStyle: 'dashed', enableClicking: false, arrowStyle: 'classic', // 设置箭头标志符号样式 arrowSize: 12, // 设置箭头标志符号大小 }); map.addOverlay(polyline);
// 循环遍历每一个坐标点,并创建标注对象和文字标注对象 for (let i = 0; i < this.points.length; i++) { const point = new BMap.Point(this.points[i].lng, this.points[i].lat); const icon = new BMap.Icon('https://lbsyun.baidu.com/jsdemo/img/fox.gif', new BMap.Size(300, 157)); const marker = new BMap.Marker(point, { icon }); map.addOverlay(marker);
// 创建 label 对象 const label = new BMap.Label(this.points[i].name, { offset: new BMap.Size(-20, -30), }); marker.addEventListener('mouseover', () => { label.setPosition(point); // 设置 label 的地理位置 map.addOverlay(label); // 将 label 添加到地图上 this.labels.push(label); // 记录已添加的 label 对象 }); marker.addEventListener('mouseout', () => { map.removeOverlay(label); // 将 label 从地图上移除 this.labels = this.labels.filter((item) => item !== label); // 从记录中删掉该 label 对象 }); }
// 初始化地图控件 const bounds = new BMap.Bounds(polylinePoints[0], polylinePoints[polylinePoints.length - 1]); map.centerAndZoom(bounds.getCenter(), map.getViewport([bounds]).zoom); map.enableScrollWheelZoom(true); }, beforeDestroy() { const map = this.$refs.map.BMapInstance; // 页面销毁时,将所有 label 对象从地图上移除,并清空记录数组 this.labels.forEach((label) => { map.removeOverlay(label); }); this.labels = []; }, }; </script>
这个示例代码中创建了一个包含多个坐标点的数组 points
,并在循环遍历每个点时创建了一个 BMap.Marker
标注对象和对应的文字标注 BMap.Label
对象。使用 marker.addEventListener()
方法分别绑定鼠标进入和移出事件,在进入事件回调函数中添加 label 对象到地图中,并记录到数组 labels
中;在移出事件回调函数中从地图上移除 label 对象,并从 labels
数组中删除。
创建连线用于连接多个坐标点,并设置箭头标志样式和大小。
在页面销毁时,通过 beforeDestroy()
钩子函数将所有 label 对象从地图上移除,并清空 labels
数组,以防止内存泄漏。
ps:注意在 Vue 项目中使用 Baidu Map,需要将地图容器 div
挂载到组件 ref
上,并在地图初始化时使用 this.$refs.map.BMapInstance
获取 BMap.Map
对象。
但是最后写在项目中的实例。
以下是实例:
<template> <div class="mapTrajectories"> <div class="queryBox"> <el-row> <div class="lableText">姓名:</div> <el-col :span="6"> <el-select size="mini" v-model="formDatas.user" style="width: 100%" placeholder="请选择" filterable clearable @change="querySearch" :filter-method="dataFilter" > <el-option v-for="item in userInfoListFilter" :key="item.id" :label="item.realname" :value="item.id" > </el-option> </el-select> </el-col> <div class="lableText">日期:</div> <el-col :span="8"> <el-date-picker size="mini" v-model="formDatas.time" type="daterange" range-separator="至" style="width: 100%" start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" > </el-date-picker> </el-col> <el-col :span="3"> <el-button size="mini" type="primary" style="margin-left: 20px" @click="queryMap(false)" >查询打卡记录</el-button > </el-col> <el-col :span="3"> <el-button size="mini" plain type="primary" style="margin-left: 20px" :disabled="!formDatas.user" @click="queryMap(true)" >查询打卡轨迹</el-button > </el-col> </el-row> </div> <div id="allmap" ref="map" v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.5)" ></div> </div> </template><script> import { mapGetters } from "vuex"; import { getLocation_clockin } from "@/api/business/basicBusiness"; import { queryIsLeader } from "@/api/business/myApprove"; import { queryAllUsers } from "@/api/business/index"; import icons from "@/assets/images/location2.png"; export default { name: "basicBusiness-mapTrajectories", components: {}, data() { return { map: null, isLeader: false, points: [ { lng: 118.80542, lat: 32.039748, name: "南京1" }, { lng: 118.79542, lat: 32.019748, name: "南京2" }, { lng: 118.77542, lat: 32.029748, name: "南京3" }, { lng: 118.60942, lat: 32.049748, name: "南京4" }, { lng: 118.80942, lat: 32.049748, name: "南京5" }, ], polyline: null, labels: [], // 记录已添加的所有 label 对象 userInfoList: [], //查询条件--数据状态 userInfoFilterVal: "", // 筛选字段 formDatas: { user: "", time: [], }, loading: false, isAddOverlay: false, // 是否显示轨迹 }; }, computed: { ...mapGetters(["userInfo"]), userInfoListFilter() { if (!this.userInfoFilterVal) return this.userInfoList; return this.userInfoList.filter((v) => { if (v.realname && v.realname.includes(this.userInfoFilterVal)) return true; if ( v.department && v.department.namePath.includes(this.userInfoFilterVal) ) return true; return false; }); }, }, mounted() { this.initParams(); // this.initMap();
// this.setPointMarkers() // this.queryisLeader() const myDate = new Date(); let M = myDate.getMonth() + 1; if (M < 10) { M = "0" + M; } console.log(M, "MMMM"); // this.formDatas.time = [ // myDate.getFullYear() +'-'+ M +"-01", myDate.toLocaleDateString().replaceAll("/", "-"), myDate.toLocaleDateString().replaceAll("/", "-"), ]; this.queryMap(false); }, methods: { initParams() { let temp = [ // { // id: "all", // realname: "全部", // }, ]; //填报人 queryAllUsers().then((res) => { this.$nextTick(() => { this.userInfoList = res; // this.userInfoList = temp.concat(this.userInfoList); //option--add全部 }); }); }, queryMap(isAddOverlay) { this.isAddOverlay = isAddOverlay; this.loading = true; let data = { userid: this.userInfo.user.id, //当前登录用户id start: this.formDatas.time && this.formDatas.time.length > 0 ? this.formDatas.time[0] : null, //默认当前月 end: this.formDatas.time && this.formDatas.time.length > 0 ? this.formDatas.time[1] : null, //默认当前月
user: this.formDatas.user, //打卡人员id }; getLocation_clockin(data).then((res) => { if (res.code == "200") { this.loading = false; new Promise((resolve, reject) => { this.points = res.data; resolve(); }).then((res) => { this.initMap(); }); } }); }, dataFilter(val) { this.userInfoFilterVal = val; }, querySearch() { this.userInfoFilterVal = ""; }, openDrawer() { this.$refs.detailsDrawer.drawer = true; }, beforeDestroy() { this.map = this.map.BMapInstance; // 页面销毁时,将所有 label 对象从地图上移除,并清空记录数组 this.labels.forEach((label) => { this.map.removeOverlay(label); }); this.labels = []; }, initMap() { this.map = new BMap.Map("allmap"); this.map.centerAndZoom( new BMap.Point(106.34067861392542, 34.129025520059834), 6 ); // 初始化地图控件 this.map.enableScrollWheelZoom(); this.map.setMaxZoom(15); // 循环遍历每一个坐标点,并创建标注对象和文字标注对象 for (let i = 0; i < this.points.length; i++) { const point = new BMap.Point(this.points[i].lng, this.points[i].lat); const icon = new BMap.Icon(icons, new BMap.Size(16, 25)); const marker = new BMap.Marker(point, { icon }); this.map.addOverlay(marker);
// 创建 label 对象 const label = new BMap.Label(this.points[i].name, { offset: new BMap.Size(-20, -30), }); marker.addEventListener("mouseover", () => { label.setPosition(point); // 设置 label 的地理位置 this.map.addOverlay(label); // 将 label 添加到地图上 this.labels.push(label); // 记录已添加的 label 对象 }); marker.addEventListener("mouseout", () => { this.map.removeOverlay(label); // 将 label 从地图上移除 this.labels = this.labels.filter((item) => item !== label); // 从记录中删掉该 label 对象 }); }
// 循环遍历每一个坐标点,并创建标注对象和文字标注对象 const polylinePoints = this.points.map((p) => { // console.log(p,'ppppppppp'); return new BMap.Point(p.lng, p.lat); }); // 创建用于绘制连线的 BMap.Point 数组 console.log(polylinePoints, "polylinePoints====", this.points); let sy = new BMap.Symbol(BMap_Symbol_SHAPE_BACKWARD_OPEN_ARROW, { scale: 0.5, //图标缩放大小 strokeColor: "#f00", //设置矢量图标的线填充颜色 strokeWeight: "1", //设置线宽 }); let iconsarrow = new BMap.IconSequence(sy, "0", "20");
setTimeout(() => { let iconDatas = [iconsarrow]; // 创建箭头标志符号 const polyline = new BMap.Polyline(polylinePoints, { strokeWeight: 0.1, //折线的宽度,以像素为单位 strokeColor: "#F00", strokeOpacity: 0.1, //折线的透明度,取值范围0 - 1 strokeStyle: "dashed", icons: iconDatas, enableClicking: false, arrowStyle: "classic", // 设置箭头标志符号样式 arrowSize: 2, // 设置箭头标志符号大小 // strokeOffset: new BMap.Size(-10, 10) // 改变线的位置 enableEditing: false, //是否启用线编辑,默认为false enableClicking: true, //是否响应点击事件,默认为true });
console.log(polyline, "polylineeeeeeeeeee"); if (this.isAddOverlay) { this.map.addOverlay(polyline); } }, 100); // 自动缩放地图,使轨迹全部可视化 let viewport = this.map.getViewport(this.points); this.map.centerAndZoom(viewport.center, viewport.zoom); }, }, }; </script>
<style scoped lang="scss"> .mapTrajectories { position: relative; top: 0px; bottom: 0; width: 100%; }
#allmap { width: 100%; height: 100%; -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Chrome/Safari/Opera */ -khtml-user-select: none; /* Konqueror */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently not supported by any browser */ } .queryBox { width: 900px; position: absolute; top: 20px; left: 20px; z-index: 99; background: #fff; height: 40px; line-height: 38px; padding: 0px 10px; border-radius: 6px; .lableText { width: 60px; padding-left: 20px; float: left; } } </style> 最后说一下开发中遇到的坑,在绘制点的时候没啥问题,就是大概5000条数据大概8秒钟,1000条还是很快,但是有个问题,坐标点都太近,那就会报错,只要有一个点比较远就能正常,也是很奇怪,排查了问题,最终解决了,此代码就是解决之后的。 文中注释很多,顺便提一下,我这个部门搜索,可根据下拉框中显示的姓名搜索外,还可以根据里面参数搜索。 标签:文字,map,const,label,points,BMap,移除,new,标注 From: https://www.cnblogs.com/zyz-s/p/17356088.html