首页 > 其他分享 >如何实现vue项目中使用Baidu Map,有多个点,鼠标移入出现文字标注,移除消失文字标注,并且点的轨迹连线有箭头指向。

如何实现vue项目中使用Baidu Map,有多个点,鼠标移入出现文字标注,移除消失文字标注,并且点的轨迹连线有箭头指向。

时间:2023-04-26 15:00:39浏览次数:43  
标签:文字 map const label points BMap 移除 new 标注

直接来案例,再分析;

<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

相关文章

  • 关于在linux-centos7下部署 .net core程序绘图(PDF等)丢失中文字体的解决方案
    关于在linux-centos7下部署.netcore程序绘图(PDF等)丢失中文字体的解决方案说明:1:以下操作基于新系统,如果步骤一,二已经安装则不需要额外安装.需要注意的是,在使用(yuminstall包)的时候如果提示包不存在;需要运行步骤(一:5安装epel,企业版Linux额外包)2:以下()内代表......
  • 关于vcpkg中x-history命令移除后及git subtree的使用问答
    1、现在的版本中已经移除了x-history命令,我该使用什么方式来查看port的历史记录呢如果当前版本的vcpkg中已经移除了x-history命令,您可以使用以下方法查看port的历史记录:使用Git命令:首先,确保您已经安装了Git。然后,在命令行或终端中,导航到vcpkg的安装目录。接下来,使用以下命令......
  • 使用Vue实现点击事件变颜色并且显示选中文字
    首先需要引入Vue.js!!!!!   直接上代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><scriptsrc="../static/vue.js"></script><st......
  • 直播软件搭建,为文字/图片添加按压效果
    直播软件搭建,为文字/图片添加按压效果1、文字layout布局: <TextView   android:layout_width="@dimen/textview_button_width"    android:layout_height="match_parent"    android:text="@string/wifi_item_hulv"   android:textColor="@drawa......
  • 移除元素
    staticvoidRemoveDataFromList(int[]nums,intval){intj=nums.Length-1;inti=0;while(i<=j)//感觉总卡在边界上{if(nums[i]==val){i......
  • 文字框自适配
    图片作为父物体,添加如下两个组件: 文本作为子物体,添加如下组件: 图片的延长方向设置可以在Recttransform中设置Pivot. ......
  • jQuery 在图片和文字中插入内容(多种情况考虑)
    昨天接到一个新的需要,在后台文章编辑器中,每一个文章的正文前面,可以单独添加一个电头字段,但是如果在富文本编辑器中最上面就添加图片的话,图片就会把电头和正文中的文字给隔开。需要做的是获取到电头字段,然后在正文中的文字部分的最前面插入电头字段。具体看下图:原始的代码:<div......
  • ArchLinux系列中文字体及中文输入法
    中文字体(全)sudopacman-Sadobe-source-han-sans-cn-fontssudopacman-Sadobe-source-han-serif-cn-fontssudopacman-Swqy-microheisudopacman-Swqy-microhei-litesudopacman-Sttf-hannomsudopacman-Swqy-zenheisudopacman-Swqy-bitmapfontsudopacman......
  • Element 级联选择器(Cascader)点击文字(或者一行)选中样式回显
    预览图实现的效果1、选中最后一级,下拉框收缩2、下拉框的每一行点击都可以选中3、点击radio,也能实现选中最后一级,下拉框收缩组件代码<el-cascaderref="cascaderHandleRef"v-model="languageIds"class="width-260":options="languageList":props="{check......
  • echarts treemap当份额太小时文字显示不全,解决为垂直显示全部文字
    before:after:解决: ......