高德地图JS API 海量点标记LabelMarker

在这里插入图片描述

🤖 作者简介:水煮白菜王 ,一位资深前端劝退师 👻
👀 文章专栏: 高德AMap专栏 ,记录一下平时在博客写作中,总结出的一些开发技巧✍。
感谢支持💕💕💕

关联文章:
高德地图JS API 普通点标记Marker
高德地图JS API 海量点标记LabelMarker
高德地图JS API 区划浏览DistrictExplorer
高德地图JS API 加载行政区边界AMap.Polygon
高德地图JS API AMap.MouseTool绘制

高德地图JS API 海量点LabelMarker

官方示例

提示:阅读官方文档API注意下版本和自己使用的版本是否对应。
新版2.0官方文档
老版1.4官方文档

关于如何引入高德地图JS API方式 请移步前面文章

👉使用高德地图JS API 开发一些常见使用方法(急救包)

上一篇👉: 普通点标记Marker

对于地图打坐标点来说,用普通点还是海量点;这个要看项目需求,数据达到千级以上,建议使用海量点标注LabelMarker,性能好又灵活。

相比于Marker, LabelMarker支持避让功能,它不仅支持LabelMarker之间的避让,JS API 2.0 版本也支持地图底图标注避让,点标记更加明显。

展示效果👇
在这里插入图片描述

1.先创建 LabelsLayer 图层

👉官方API手册
LabelsLayer 图层是用于承载 LabelMarker 标记的图层,因此所有创建的 LabelMarker标记都需要添加到 LabelsLayer 图层上才能最终展示在地图上。

const labelsLayer = new AMap.LabelsLayer({
  zooms: [3, 20],
  zIndex: 1000,
  collision: true, //该层内标注是否避让
  allowCollision: true, //不同标注层之间是否避让  
});

2.创建 LabelMarker 标记

👉官方API手册

//设置一个图标对象
const icon = {
  type: "image", //图标类型,现阶段只支持 image 类型
  image: "https://a.amap.com/jsapi_demos/static/demo-center/marker/express2.png", //可访问的图片 URL
  size: [64, 30], //图片尺寸
  anchor: "center", //图片相对 position 的锚点,默认为 bottom-center
};
//设置文字对象
const text = {
  content: "中邮速递易", //要展示的文字内容
  direction: "right", //文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置
  offset: [-20, -5], //在 direction 基础上的偏移量
  //文字样式
  style: {
    fontSize: 12, //字体大小
    fillColor: "#22886f", //字体颜色
    strokeColor: "#fff", //描边颜色
    strokeWidth: 2, //描边宽度
  },
};
//创建 LabelMarker
const labelMarker = new AMap.LabelMarker({
  name: "标注", //此属性非绘制文字内容,仅为标识使用
  position: [116.466994, 39.984904],
  zIndex: 16,
  rank: 1, //避让优先级
  icon: icon, //标注图标,将 icon 对象传给 icon 属性
  text: text, //标注文本,将 text 对象传给 text 属性
});

当LabelsLayer图层开启避让(collision:true)时,若两个LabelMarker标记发生重叠,rank值较高的LabelMarker标记将显示,而值较低的会被隐藏。

3.给LabelMarker 添加事件

LabelMarker 自带的事件e里面的信息只有地理数据,拿不到当前整条数据的data[i]
最下面全部代码👇给LabelMarker 添加的点击事件 拿的是data[i]数据包 方便后面取值使用

labelMarker.on('click', function(e){
    console.log(e);
});

4.清除海量点LabelMarker

// 清除海量点 
LabelsLayer.clear(LabelMarker); 

全部代码👇

<!-- Vue 2 Code -->
<template>
  <div id="index" ref="appRef">
    <div id="container" ref="mapRef"></div>
  </div>
</template>
  <script>
var map; // 地图加载
var LabelsLayer; // LabelsLayer图层
var LabelMarker; // LabelMarker海量点标注
export default {
  name: "componentsMap",
  data() {
    return {
      data: [],
    };
  },
  created() {
    this.initData();
  },
  mounted() {
    this.$nextTick(() => this.initMap());
  },
  beforeDestroy() {
    map?.destroy();
    map = null;
  },
  methods: {
    // 模拟生成地图打点数据Array
    initData() {
      /*
       * @Author: Do not edit
       * @Date: 2024-04-27 14:19:53
       * @LastEditors: Do not edit
       * @LastEditTime: 2024-05-11 09:54:38
       * @FilePath: Do not edit
       * @Description: 模拟生成坐标点
       */
      // 限定范围
      const anhuibounds = {
        minlng: 104.032965,
        maxlng: 119.695845,
        minlat: 28.097015,
        maxlat: 36.897459,
      };
      // 生成条数
      const steps = 10000;
      const generaterandomcoordinate = () => {
        // 生成随机经度
        const lng =
          anhuibounds.minlng +
          Math.random() * (anhuibounds.maxlng - anhuibounds.minlng);
        // 生成随机纬度
        const lat =
          anhuibounds.minlat +
          Math.random() * (anhuibounds.maxlat - anhuibounds.minlat);
        // 生成随机名称
        const name = "地点" + Math.floor(Math.random() * steps);
        // 获取当前时间戳
        const timestamp = Date.now();
        return { name, lng, lat, timestamp};
      };
      let array = [];
      for (let i = 0; i < steps; i++) {
        array.push(generaterandomcoordinate());
      }
      // console.log(array)
      this.data = array;
    },
    // 初始化地图
    initMap() {
      map = new window.AMap.Map("container", {
        viewMode: "2D",
        zooms: [3, 20], // 缩放范围
        terrain: false, //关闭地形图 官方效果示例https://lbs.amap.com/demo/javascript-api-v2/example/3d/3d-terrain
        showBuildingBlock: false, // 不显示3D楼块 建议使用 节省性能 看需要
        showLabel: false, // 取消地图层标注
        scrollWheel: true, // 开启缩放
        dragEnable: true, // 开启鼠标拖动
        doubleClickZoom: false, // 禁止双击
      });
      if (this.data) this.setMarker();
    },
    setMarker() {
      // 创建并配置 AMap.LabelsLayer 图层
      LabelsLayer = new window.AMap.LabelsLayer({
        zooms: [3, 20],
        zIndex: 1000,
        collision: true, //该层内标注是否避让 效果示例 https://lbs.amap.com/demo/javascript-api-v2/example/mass-markers/labelmarker
        allowCollision: true, //不同标注层之间是否避让
      });
      map.add(LabelsLayer);

      // 定义图标样式
      const MARKER_ICON = {
        type: "image",
        image: "https://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
        anchor: "bottom-center", // 设置锚点
        size: new window.AMap.Size(25, 30), // 图标大小
      };
      // 定义文本样式
      const TEXT_STYLE = {
        fold: true,
        fontSize: 15,
        fontWeight: "normal",
        fillColor: "#0bc8de",//字体颜色        
        // strokeColor: "RGBA(23, 39, 53, 1)", //描边颜色
        // strokeWidth: "1px",//描边宽度
        borderColor: "#00a0e9",
        borderWidth: "5px",
        padding: "2, 5",
        backgroundColor: "RGBA(23, 39, 53, 0.6)",
      };
      
      // 筛选出有效数据 含有经纬度信息(lng和lat)的数据项
      LabelMarker = this.data
        .filter((item) => item.lng && item.lat)
        .map((item) => {
          const marker = new window.AMap.LabelMarker({
            position: [item.lng, item.lat],
            name: '',
            icon: MARKER_ICON,
            rank: 1, //避让优先级
            text: {
              content: item.name,
              direction: "top",
              style: TEXT_STYLE, // 文本样式
            },
          });
          // 绑定点击事件
          marker.on("click", () => this.markersClick(item));
          return marker;
        });
      // 批量添加到图层
      LabelsLayer.add(LabelMarker);
    },
    // 点击获取当前marker点数据data[i]
    markersClick(item) {
      console.log(item);
    },
  },
};
</script>
<style lang="scss"  scoped>
#index {
  width: 1920px;
  height: 1080px;
  color: #ffffff;
  overflow: hidden;
  #container {
    width: 1920px;
    height: 1080px;
    z-index: 100;
  }
}
</style>

在这里插入图片描述
如果你觉得这篇文章对你有帮助,请点赞 👍、收藏 👏 并关注我!👀
在这里插入图片描述

### 高德地图 LabelMarker 功能卡顿解决方案 在处理高德地图中的 `LabelMarker` 功能时,如果遇到量数据加载导致的地图卡顿问题,可以通过优化配置和使用高效的数据管理方法来改善性能。 #### 数据分批加载 对于规模数据集,一次性全部加载到地图上会显著影响渲染速度。采用分页或按需加载的方式能够有效减少初始加载时间并提高交互流畅度[^1]。 ```javascript // 假设有一个包含数万个位置数组 pointsData let batchedPoints = []; const batchSize = 500; // 每次显示的最数量 for (let i = 0, j = Math.ceil(pointsData.length / batchSize); i < j; i++) { let tempArray = pointsData.slice(i * batchSize, (i + 1) * batchSize); batchedPoints.push(tempArray); } ``` #### 使用 Loca 进行可视化增强 通过集成Loca库,不仅可以实现更丰富的视觉效果,还能利用其内置算法提升数据量下的表现效率。例如,在创建 `AMap.LabelMarker` 层之前先初始化一个Loca实例,并设置合理的参数以适应具体应用场景的需求[^2]。 ```javascript import { AMapLoader } from '@amap/amap-jsapi-loader'; AMapLoader.load({ "key": "your_api_key", // 开发者Key "version": "2.0", "plugins": ['Loca'] }).then((AMap) => { const map = new AMap.Map('container', {}); var locaData = new Loca.Dataset({ data: [] }); var layer = new Loca.LabelsLayer({ map, dataset: locaData, style: function(feature){ return { text: feature.properties.name || '', fontSize: '14px', fill: '#fff' } }, zooms: [3, 18], visible: true }); // 更新数据至Loca层而非直接操作LabelMarker function updateMarkers(dataChunk){ locaData.setDataSet(dataChunk); } }); ``` #### 减少不必要的属性计算 确保只传递必要的字段给每一个 `LabelMarker` 对象,避免因过多冗余信息而增加内存占用以及解析负担。同时简化样式定义逻辑,去除那些不会改变的静态部分,从而加快每次重绘的速度。 #### 合理运用缓存机制 针对频繁更新但实际内容变化不的场景,考虑引入客户侧缓存策略。比如将已经绘制好的图形元素保存下来,在后续刷新时不重新构建而是直接复用已有资源;或者预先准备好不同缩放级别下所需的图片素材,使得切换过程中无需等待网络请求完成即可立即呈现新视图。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水煮白菜王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值