vue使用高德地图,marker低于1000,滑动卡顿问题的探究(已解决)

news2024/12/23 23:01:28

问题描述

vue使用高德地图点标记,刚开始使用的是Marker,但是数目超过300,滑动就卡顿,按文档来说,Marker 类型推荐在数据量为 500 以内时使用,不应该卡顿。后边就开始对这个bug进行两天脑秃的探究了

1.换成 LabelMarker

既然Marker类型不行,看了文档, LabelMarker支持更多的点标记,那就换成 LabelMarker,然后自信满满的发布,结果还是不行。

2.与官方沟通寻求解决方案

按照文档写了代码,都不行,只能跟官方发工单沟通,我把项目中使用到的初始化代码贴给了官方,官方看完也说没问题,给了一个js的demo,运行了一下,确实不卡。demo代码贴一下

Labelmarker_Test.html

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
    <title>地图显示</title>
    <style>
        html,
        body,
        #container {
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <div id="container"></div>
    <!-- 加载地图JSAPI脚本 -->
    <script src="https://webapi.amap.com/maps?v=2.0&key=自己的key"></script>
    <script src="/data.js"></script>

    <script>
        var map = new AMap.Map('container', {
            viewMode: '2D', // 默认使用 2D 模式,如果希望使用带有俯仰角的 3D 模式,请设置 viewMode: '3D',
            zoom: 11, //初始化地图层级
            center: [116.397428, 39.90923] //初始化地图中心点
        });
        let markers = [];
        for (var i = 0; i < data.length; i++) {
            var marker;
            let item = data[i];
            // console.log("地图marker", item);
            let imageUrl = 'https://a.amap.com/jsapi_demos/static/demo-center/marker/express2.png';
            var icon = {
                // 图标类型,现阶段只支持 image 类型
                type: "image",
                // 图片 url
                image: imageUrl,
                // 图片尺寸
                size: [44, 50],
                // 图片相对 position 的锚点,默认为 bottom-center
                anchor: "center",
            };

            var text = {
                // 要展示的文字内容
                content: item.orgName,
                // 文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置
                direction: "top",
                // 在 direction 基础上的偏移量
                offset: [0, 0],
                // 文字样式
                style: {
                    // 字体大小
                    fontSize: 12,
                    // 字体颜色
                    fillColor: "#000000",
                    //backgroundColor: "#ffffff",
                },
            };

            if (item.latitude && item.longitude) {
                let positionV = [item.longitude, item.latitude];
                marker = new AMap.LabelMarker({
                    name: "标注2", // 此属性非绘制文字内容,仅最为标识使用
                    position: positionV,
                    zIndex: i,
                    opacity: 1,
                    // 将第一步创建的 icon 对象传给 icon 属性
                    icon: icon,
                    // 将第二步创建的 text 对象传给 text 属性
                    text: text,
                    zooms: [3, 20],
                    allowCollision: false,
                });
            }
         
            var onMarkerClick = function (e) {
                console.log("marker 点击");
                that.hospital = item;
                that.sheetShow = true;
            };
            marker.on("click", onMarkerClick); //绑定click事件

            markers.push(marker);
        }

        var labelsLayer = new AMap.LabelsLayer({
            zooms: [3, 20],
            zIndex: 1000,
            // 该层内标注是否避让
            collision: true,
            // 设置 allowCollision:true,可以让标注避让用户的标注
            allowCollision: true,
        });
        labelsLayer.add(markers);
        map.add(labelsLayer);
    </script>
</body>

</html>

data.js

const data = [
    { unifiedOrgCode: "320211PD3854", orgName: "门诊部", branchCode: null, branchName: null, orgLevel: null, orgGrade: null, provinceCode: null, cityCode: null, orgAddress: "太湖新城金融街11号", latitude: 31.488750, longitude: 120.304928, introduction: null, orgUrl: "https://www.wxhealth.net:8241/File/GetFile/76c0c8d6be03c2e1", reserveNote: null, orgTraffic: null, feature: null, ticketDetial: null, isReservation: 1, appointDays: 7, canAppointToday: 1, doctorAppointDays: null, showOrder: null, accessType: null, h5Info: null, distance: "0.10", contactPhone: null, characteristics: null, orgType: "clinic", districtCode: "3201", economicType: 2 }, { unifiedOrgCode: "320211PD78", orgName: "同仁大药房", branchCode: null, branchName: null, orgLevel: null, orgGrade: null, provinceCode: null, cityCode: null, orgAddress: "区观山路38号", latitude: 31.491185, longitude: 120.302667, introduction: null, orgUrl: "https://www.wxhealth.net:8241/be03c2e1", reserveNote: null, orgTraffic: null, feature: null, ticketDetial: null, isReservation: 1, appointDays: 7, canAppointToday: 1, doctorAppointDays: null, showOrder: null, accessType: null, h5Info: null, distance: "0.40", contactPhone: null, characteristics: null, orgType: "clinic", districtCode: "320211", economicType: 2 },
]

有非常多的数据,我这边只贴出来数据结构。如果要模拟数据,可以使用循环遍历,然后动态修改经纬度的办法,比如

 demoData.forEach((element) => {
         //TODO 增加多条数据,测试是否卡顿
            let latTest = element.latitude;
            let lonTest = element.longitude;
            for (let i = 0; i < 50; i++) {
              element.latitude = latTest + 0.00001 * i;
              element.longitude = lonTest + 0.00001 * i;
              mapData.push(element);
            }
          });

是否只有Vue会卡顿

我试了官方给的js demo,数据多的时候确实不卡,所以我怀疑是不是vue的问题,我试着不用Vue的初始化,在vue中使用js那种方式来初始化
在public下的index.html中的 <head>里添加

  <script src="https://webapi.amap.com/maps?v=2.0&key=自己的key"></script> 

然后对应的Vue里使用

 var map = new AMap.Map('container', {
            viewMode: '2D', // 默认使用 2D 模式,如果希望使用带有俯仰角的 3D 模式,请设置 viewMode: '3D',
            zoom: 11, //初始化地图层级
            center: [116.397428, 39.90923] //初始化地图中心点
        });

但是还是不行,还是会卡顿

治标不治本的办法

既然技术上不好实现,那修改需求呢,比如对于大量数据,我分N组,比如四组吧,然后监听地图缩放事件,在某一范围,只显示第一组,然后在另一范围,显示第二组,每组显示的数据比较少,就不会出现卡顿,但是这是治标不治本的办法,如果数据很多呢,每组超过几千,岂不是还是很卡,所以放弃

不经意发现的bug

只能技术上解决了,按照官方代码,一点一点的删项目中的代码,看看到底是哪一块代码引起的卡顿,经过各种尝试,最终锁定了一个变量,这个变量是data里的localMap,我在map初始化以后,将this.localMap=map。这个在逻辑上是没有问题的,所以我刚开始并没有在意,但是确实是这段代码引起的卡顿,所以我反馈给官方,
在这里插入图片描述
然后官方给的回复:
在这里插入图片描述

所有地图相关的实例不要放在 vue 的可响应数据中,响应数据会劫持属性,地图的属性会被修改,另外,劫持的属性可能和渲染有关,那么会增加很多响应的计算,会很卡;

懂了吧,就是不能在地图相关的实例里,进行任何data里字段的赋值,否则就会很卡

怎样获得地图实例

我现在的需求是,我地图控件的上边,加了一个图标,用来设置居中位置,使用了setCenter方法,这个需要用到当前地图的对象,所以我想使用data里的字段与map关联,但是这样会卡顿,有什么办法拿到map的对象,在外层进行操作????

既然不能在地图实例代码里给外层字段赋值,想到的第一个办法就是把map对象return出去,然后用字段接收,但是呢,还是不行,再一个办法,就是通过方法,传入map对象赋值,还是不行,所以,继续与官方沟通,得到的回复是

地图加载后,把AMap挂载到window上面,后面直接从window中获取即可。

然后怎么才能获取到呢,试了几种办法,也没找到怎么获取AMap的setCenter方法,最后百度了一下,可以这样得到实例,将map与window关联,window.map=new AMap.Map(“container”, {…});然后在外层通过window.map对地图操作

  window.map.setCenter([120.318321, 31.497963]);
 initAMap() {
      
    
      AMapLoader.load({
        key: "自己的key", //设置您的key
        version: "2.0",
        plugins: ["AMap.ToolBar", "AMap.Driving"],
        AMapUI: {
          version: "1.1",
          plugins: [],
        },
        Loca: {
          version: "2.0",
        },
      })
        .then((AMap) => {
           window.map = new AMap.Map("container", {
            viewMode: "3D",
            zoom: 10,
            zooms: [2, 22],
            center: [120.318791, 31.497993],
          });
          let markers = [];
          let demoData = dataInJs();
          let mapData = [];

          demoData.forEach((element) => {
            // //TODO 增加多条数据,测试是否卡顿,正式发布删除
            let latTest = element.latitude;
            let lonTest = element.longitude;
            for (let i = 0; i < 10; i++) {
              element.latitude = latTest + 0.00001 * i;
              element.longitude = lonTest + 0.00001 * i;
              mapData.push(element);
            }
          });

          console.log("mapData", mapData);
          for (var i = 0; i < mapData.length; i++) {
            var marker;
            let item = mapData[i];
            let imageUrl =
              "https://a.amap.com/jsapi_demos/static/demo-center/marker/express2.png";

            var icon = {
              // 图标类型,现阶段只支持 image 类型
              type: "image",
              // 图片 url
              image: imageUrl,
              // 图片尺寸
              size: [44, 50],
              // 图片相对 position 的锚点,默认为 bottom-center
              anchor: "center",
            };

            var text = {
              // 要展示的文字内容
              content: item.orgName,
              // 文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置
              direction: "top",
              // 在 direction 基础上的偏移量
              offset: [0, 0],
              // 文字样式
              style: {
                // 字体大小
                fontSize: 12,
                // 字体颜色
                fillColor: "#000000",
              },
            };

            if (item.latitude && item.longitude) {
              let positionV = [item.longitude, item.latitude];
              marker = new AMap.LabelMarker({
                name: "标注2", // 此属性非绘制文字内容,仅最为标识使用
                position: positionV,
                zIndex: i,
                opacity: 1,
                // 将第一步创建的 icon 对象传给 icon 属性
                icon: icon,
                // 将第二步创建的 text 对象传给 text 属性
                text: text,
                zooms: [3, 20],
                allowCollision: false,
              });
            }

            var onMarkerClick = function (ee) {
              console.log("marker 点击" + ee);
            };
            marker.on("click", onMarkerClick); //绑定click事件

            markers.push(marker);
          }

          var labelsLayer = new AMap.LabelsLayer({
            zooms: [3, 20],
            zIndex: 1000,
            // 该层内标注是否避让
            collision: true,
            // 设置 allowCollision:true,可以让标注避让用户的标注
            allowCollision: true,
          });
          labelsLayer.add(markers);
            window.map.add(labelsLayer);
          //  this.setLocalMap(map);
          setTimeout(() => {
            console.log("定位");
             this.testMap();
          }, 1000);
         
        })
        .catch((e) => {
          console.log(e);
        });

      //return map;
    },

总结

标注就使用官方文档上的就可以了,如果还是卡顿,检查一下是否在map实例化的时候,有对data里字段的操作,比如this.localMap=map之类的。如果想要获取到map的实例,用于外层对地图的操作,可以给window.map,然后获取,将map实例与window关联,这样不会卡顿

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/74040.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytorch-天气识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章地址&#xff1a; 365天深度学习训练营-第P3周&#xff1a;天气识别&#x1f356; 作者&#xff1a;K同学啊一、前期准备 1.设置GPU import torch import torch.nn as nn impor…

MAC苹果系统安装数字证书的方法

MAC苹果系统安装数字证书的方法之工具/原料 Mac OS电脑一台 数字证书 先讲讲安装方法,mac系统默认浏览器是Safari,那小D在这里就以Safari浏览器为例子,讲解一下相关的安装方法 如果已有开通了数字证书的用户,在重装了系统或是在没有安装安装证书的电脑上进行付款时,会提…

【ELM回归预测】基于非洲秃鹫算法优化极限学习机预测附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

FL Studio水果21版本助力原创音乐人(中文完整版All Plugins)

最近&#xff0c;网上算是“风言风语”吧&#xff0c;关于FL Studio是否出21版的说法各异。首先呢&#xff0c;这里先肯定一点&#xff0c;FL Studio即将出FL Studio 21版本&#xff0c;但是正式版已经出来。希望大家不要被网上一些所谓冒充发布的FL Studio21正式版所骗&#x…

信息系统分析与设计:摊位管理信息系统

摊位管理信息系统的分析与设计 1 市场分析 1.1 地摊经济发展背景 1.2 地摊经济逐渐复苏 1.3 地摊经济的放管服 2 目标市场定位 2.1 普通城市居民 2.2 政府相关管理部门 3 系统主要介绍 3.1 系统创新描述 3.2 主要搭建流程 3.3 主要业务模块 3.4 业务流程图 3.5 组…

Vue学习笔记--第二章(尚硅谷学习视频总结)

第二章 Vue组件化编程第二章 Vue组件化编程2.1. 模块与组件、模块化与组件化2.1.1. 模块2.1.2. 组件2.1.3. 模块化2.1.4. 组件化2.2. 非单文件组件2.2.1. 基本使用2.2.2. 组件注意事项2.2.3. 组件的嵌套2.2.4. VueComponent2.2.5. 一个重要的内置关系2.3. 单文件组件第二章 Vue…

【C#基础学习】第十七章、数组

目录 数组 1.数组的类型 1.1 一维数组和矩形数组 1.1.1实例化一维数组和矩形数组 1.2 访问数组元素 1.3 初始化数组 1.3.1 显式初始化一维数组 1.3.2 显式初始化矩形数组 1.3.3 显式初始化的快捷语法 1.3.4 隐式类型数组 1.4 交错数组 1.4.1 声明交错数组 1.4.2 实例…

bump map(凹凸贴图)的一个简单生成方法

用于渲染物体表面&#xff0c;增加真实感的bump map(凹凸贴图)的一个简单生成方法。 1. 在 Perlin Noise Map Generator - OpenProcessing 生成一个perlin noise map&#xff0c; 点击代码按钮&#xff0c;修改生成图像的分辨率 点击 paly 按钮&#xff0c;设置参数&#xf…

学习笔记-3-SVM-10-SVR

细节内容请关注微信公众号&#xff1a;运筹优化与数据科学 ID: pomelo_tree_opt outline 1. Linear regression 2. Support vector regression 3. SVR vs. SVM 4. Linear SVR 5. Kernel SVR ------------------------------------ 1. Linear regression OR里最常使用的…

【从零开始学习深度学习】15. Pytorch实战Kaggle比赛:房价预测案例【含数据集与源码】

基于之前学习的内容&#xff0c;让我们动手实战一个Kaggle比赛的&#xff1a;房价预测实战案例。Kaggle是一个著名的供机器学习爱好者交流的平台&#xff0c;该房价预测实战网址&#xff1a;https://www.kaggle.com/competitions/house-prices-advanced-regression-techniques …

浅析Linux 内存布局

【推荐文章】 路由选择协议——RIP协议 纯干货&#xff0c;linux内存管理-内存管理架构&#xff08;建议收藏&#xff09; 轻松学会linux下查看内存频率,内核函数,cpu频率 X86体系结构 在X86体系结构下&#xff0c;物理内存地址一般从0x0000_0000开始&#xff0c;而Linux内核主…

微信小程序实战之获取用户信息并保存唯一实例

前言 这是我参加掘金启航计划的第二篇文章&#xff0c;这次总结的是获取用户信息并联合 mobx 状态管理库&#xff0c;保存全局唯一的用户对象。 本篇文章基于 微信云开发 &#xff0c;数据从云数据库中取出&#xff0c;使用微信云数据库API进行获取数据&#xff0c;希望观众老…

Altium Designer飞线不从过孔里面出线如何解决?

出现以上飞线不从过孔出线的原因是其拓扑结构所导致&#xff0c;解决方式就是设置下拓扑结构。 1、执行菜单栏命令“设计-规则”&#xff0c;或者快捷键DR&#xff0c;快速打开“PCB规则及约束编辑器”对话框&#xff0c;如图1所示。 2、在对应的对话框中&#xff0c;选择“Rou…

postgres源码解析41 btree索引文件的创建--2

本文将从btbuild函数作为入口从源码角度进行讲解btree文件的创建流程&#xff0c;执行SQL对应为CREATE TABLE wp_shy(id int primary key, name carchar(20))。知识回顾见&#xff1a;postgres源码解析41 btree索引文件的创建–1 执行流程图梳理 _bt_spools_heapscan 执行流程…

2153年,人类已被AI所奴役。就在这一天,作为一名被俘虏的“搜查部队”士兵,你来到了A0007号城外的反抗军基地中

2153年&#xff0c;地球。   人类&#xff0c;已被AI所奴役。   这个AI的缩写名为——PTA&#xff0c;或称“辟塔”。      辟塔的原型&#xff0c;是一个用于分析网络用户消费倾向并立即给出相关引导的软广告程序。   很快&#xff0c;辟塔便成了广大商家的宠儿&…

【华为上机真题 2022】求解连续数列

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

MatLab SimuLink国产代替

MATLab SimuLink国产代替 米国的限制&#xff0c;把工业软件的国产化推到风口浪尖&#xff0c;作为扎根工业软件开源基础架构20多年的UCanCode, 一直是国外顶尖工业软件的基础架构提供商之一。许多国外软件都在这个基础上构建出来&#xff0c;这里我们也希望探讨一下国产代替Ma…

乐享元游的 UWA Pipeline 最佳实践分享

“躬身入局 践行游戏研发工业化”是UWA在2022年研发上坚持的方向&#xff0c;其中UWA Pipeline更是今年在工业化部署上的一个重要的突破口。在近一年里&#xff0c;越来越多的游戏研发团队在日常项目生产开发中&#xff0c;使用UWA Pipeline搭建了符合自身需求的DevOps研发交付…

fat32文件系统分析

fat32文件系统结构&#xff1a; fat32文件系统比fat16文件系统少了根目录FDT&#xff0c;其实是将根目录归结到数据区中了。 注意数据区第一个扇区所在蔟为2号蔟。 首先在磁盘管理中创建一个fat32磁盘&#xff1a; 大小为16GB。 使用winhex打开磁盘。 可以看到MBR在扇区0处…

AI推理卡/tensorRT c++

#####AI 推理卡&#xff1a;我的需求是x86上Nvidia显卡训练好的模型 用在AI推理卡上进行推理### AI 推理卡 环境配置 安装ubuntu系统、AI推理卡环境 1&#xff0c;安装ubuntu20.04.4 过程忽略&#xff0c;网上教程很多。 2&#xff0c;ubuntu20.04.4设置root登录&#xf…