Vue usa el mapa de Gaode, el marcador es inferior a 1000 y la exploración del problema del atasco deslizante (resuelto)

Descripción del problema

Vue usa marcadores de puntos de mapa Gaode. Al principio, se usaba Marker, pero cuando el número supera los 300, el deslizamiento se congela. Según el documento, se recomienda usar el tipo Marker cuando la cantidad de datos es inferior a 500, y no debe estar atascado. Más tarde, comencé a explorar este error durante dos días.

1. Cambiar a LabelMarker

Dado que el tipo de marcador no es bueno, después de leer el documento, LabelMarker admite más marcadores de puntos, luego reemplácelo con LabelMarker y luego suéltelo con confianza, pero el resultado aún no funciona.

2. Comunicarse con el funcionario para buscar una solución

Escribí el código de acuerdo con el documento, pero no funcionó. Solo pude comunicarme con la orden de trabajo oficial. Publiqué el código de inicialización utilizado en el proyecto al oficial. Después de leerlo, el oficial dijo que no había problema. Le di una demostración de js y la ejecuté, realmente no se atascó. Publicar el código de demostración

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>

datos.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 },
]

Hay muchos datos, solo publico la estructura de datos aquí. Si desea simular datos, puede usar el bucle transversal y luego modificar dinámicamente la latitud y la longitud, como

 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);
            }
          });

¿Es solo Vue que se congela?

Probé la demostración de js dada por el oficial, y no se atasca cuando hay muchos datos, así que me pregunto si es un problema con vue. Trato de no inicializar Vue y uso js en vue para inicializar el índice bajo public
.añadir <head>en

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

Luego úsalo en el Vue correspondiente

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

Pero todavía no funciona, todavía se congela

Un paliativo, no una solución permanente

Dado que es técnicamente difícil de implementar, ¿qué hay de modificar los requisitos? Por ejemplo, para una gran cantidad de datos, los divido en N grupos, como cuatro grupos, y luego controlo el evento de zoom del mapa. En un cierto rango, solo se muestra el primer grupo, y en otro rango, muestra el segundo grupo.Los datos que se muestran en cada grupo son relativamente pequeños, por lo que no habrá retraso.

error encontrado accidentalmente

Solo se puede resolver técnicamente. De acuerdo con el código oficial, elimine el código en el proyecto poco a poco para ver qué pieza de código causó el bloqueo. Después de varios intentos, finalmente bloqueé una variable. Esta variable está en los datos The localMap , configuro this.localMap=map después de inicializar el mapa. No hay ningún problema con esta lógica, por lo que no me importó al principio, pero de hecho fue causado por este código, así que se lo informé al oficial y la respuesta oficial
inserte la descripción de la imagen aquí
:
inserte la descripción de la imagen aquí

Todas las instancias relacionadas con el mapa no deben colocarse en los datos de respuesta de vue. Los datos de respuesta secuestrarán los atributos y los atributos del mapa se modificarán. Además, los atributos secuestrados pueden estar relacionados con la representación, lo que aumentará muchos cálculos de respuesta. , que estará muy atascado;

Entendido, es solo que no puede asignar ningún campo en los datos en la instancia relacionada con el mapa, de lo contrario, estará muy atascado

Cómo obtener una instancia de mapa

Mi requisito actual es agregar un ícono en la parte superior de mi control de mapa para establecer la posición central y usar el método setCenter. Esto necesita usar el objeto de mapa actual, por lo que quiero usar los campos en los datos para asociarlos con el mapa. , pero esto causará retraso. ¿Hay alguna forma de obtener el objeto del mapa y operarlo en la capa exterior? ? ? ?

Dado que no es posible asignar un valor al campo externo en el código de instancia del mapa, el primer método que se me ocurre es devolver el objeto del mapa y luego usar el campo para recibirlo, pero sigue sin funcionar. es pasar el objeto del mapa para asignar un valor a través del método, o no, así que continúe comunicándose con el oficial, la respuesta es

Después de cargar el mapa, monte el AMap en la ventana y luego obténgalo directamente desde la ventana.

Entonces, ¿cómo puedo obtenerlo? Probé varios métodos, pero no pude encontrar cómo obtener el método setCenter de AMap. Finalmente, busqué en Baidu, y puedo obtener una instancia como esta, asociar mapa con ventana, ventana. map=new AMap.Map(“container ", {...}); luego opere en el mapa a través de window.map en la capa externa

  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;
    },

Resumir

Solo use el documento oficial para la anotación.Si todavía está atascado, verifique si hay una operación en los campos en los datos cuando se instancia el mapa, como this.localMap=map y similares. Si desea obtener una instancia de mapa para que la capa externa opere en el mapa, puede proporcionar window.map y luego obtenerlo, y asociar la instancia de mapa con la ventana, para que no se congele.

Supongo que te gusta

Origin blog.csdn.net/jifashihan/article/details/128231939
Recomendado
Clasificación