高德地图js2.0使用MarkerCluster聚合点及添加点击事件

高德地图也在不断迭代,目前2.0以下版本已经在iOS15 beta版本不适用了,而且2.0以下版本由于卡顿等问题也不在符合用户的使用需要,升级迫在眉睫,但2.0对于标记的聚和与之前版本有较大区别,在此将写法记录一下,也希望能帮到大家。

2.0以前对于标记的处理是将标记全部在地图上画出来之后通过MarkerClusterer聚合,不仅对标记的修改较为复杂,还会导致严重的卡顿问题。而在升级到2.0后,标记的聚合便是通过MarkerCluster将标记的坐标打在地图上,然后直接渲染的方式了,如下所示:

方式一:
      this.cluster = new AMap.MarkerCluster(this.map, this.allLnglat, {
            styles: styles,
            renderMarker: this.renderMarker
      });

其中只列举出了最重要的几个参数:

  • this.map:当前渲染的地图

  • this.allLnglat:所有的标记坐标,例如:[{ lnglat: [117.366,36.577] }]

  • styles: 聚合点上显示的图标,例如:

    [{
     url: 'https://a.amap.com/jsapi_demos/static/images/blue.png',
     size: new AMap.Size(32, 32),
     offset: new AMap.Pixel(-16, -16)
    },{
     url: 'https://a.amap.com/jsapi_demos/static/images/green.png',
     size: new AMap.Size(32, 32),
     offset: new AMap.Pixel(-16, -16)
    }]
    
    • renderMarker:非聚合点上显示的标记,也就是单个点显示的标记,和2.0版本前我们定义的marker是一个东西,可以自定义样式添加点击事件等,例如:

      renderMarker(context) {
      //显示点的经纬度context.data[0].lnglat
      //此处应有逻辑,通过遍历所有点的经纬度来识别当前标记对应的数据
      //此处content为设置当个标记的样式
      context.marker.setContent(content);
      //此处为设置标记在地图上的偏移,根据标记物大小处理
      context.marker.setOffset(new AMap.Pixel(-20, -20));
      //此处为设置标记是否显示在最上方,一般只有选中的标记在最上方
      context.marker.setTop(top);
      //此处为设置标记携带的数据,点击事件会使用
      context.marker.setExtData({
         id: id
       });
      //此处为添加单个标记点击事件
        context.marker.on('click', ev => {
            //当前标记居中
           this.map.setZoomAndCenter(16, ev.target.getPosition());
           //获取标记携带的数据
           const extData = ev.target.getExtData();
           const id = extData.id;
         });
        },
      

由于现在聚合点和标记点都是使用的标记,因此聚合点没有提供点击散开的功能,我们可以通过一下方式实现:

 this.cluster.on('click', (item) => {
    //此处是通过包含点的数量判断是否是聚合点,不是聚合点就执行上方单个点的点击方式
   if(item.clusterData.length <= 1) {
     return;
   }
   //这里是计算所有聚合点的中心点
   let alllng = 0, alllat = 0;
  for(const mo of item.clusterData) {
    alllng += mo.lnglat.lng;
    alllat += mo.lnglat.lat;
   }
   const lat = alllat / item.clusterData.length;
   const lng = alllng / item.clusterData.length;
     //这里是放大地图,此处写死了每次点击放大的级别,可以根据点的数量和当前大小适应放大,体验更佳
    this.map.setZoomAndCenter(this.map.getZoom() + 2, [lng, lat]);
 });
方式二:
    new AMap.MarkerClusterer(
     //地图实例对象
      map:Map,  
     //经纬度数组对象
     dataOptions:Array   
     //点聚合属性
     markerClusterOptions:Object 
 )

  dataOptions:[
      {
       weight: Number, //权重(可选)以权重高的点为中心进行聚合
       lnglat: Array //经纬度数组 string[] | number[]
      }
    ]

在2.0版本中,markerClusterOptions去掉了minClusterSize 集合的最小数量,zoomOnclick 点击聚合点时是否散开;对renderClusterMarker属性进行了修改,去掉了renderClusterMarker:function的markers属性;新增了renderMarker: function 用于实现非聚合点的自定义设置

  new AMap.MarkerClusterer(map, marker, { 

   gridSize: number, //聚合计算时网格的像素大小,默认60
   //minClusterSize 聚合的最小数量(已弃用)
   maxZoom: number, //最大聚合级别,超出级别不进行聚合,默认18
   averageCenter: boolean, //聚合点的图标位置是否是所有聚合内点的中心点,默认true,如果有权重则以权重高的为中心进行聚合
   clusterByZoomChange: boolean, //地图缩放过程中是否聚合,默认false
   styles: Array<Object>, //聚合后点标记样式
   // styles包含以下属性
   // url{string} (必选)图标的url地址
   // size{AMap.Size} (必选)图标的图片大小
   // offset{AMap.Pixel} (可选)图标相对于左上角的偏移量
   // imageOffset{AMap.Pixel} (可选)图片在可视区域的偏移量
   // textColor{String} (可选)文字颜色,默认#000000
   // textSize{Number} (可选)文字大小,默认10
    renderClusterMarker: (cluster: any) => {
       cluster.count //当前聚合点下marker的数量
       cluster.marker //当前聚合点的marker对象
    },
    renderMarker: (context: any) => {
        context.marker //非聚合点的marker对象
    }
   // zoomOnClick 点击聚合点时是否散开(已弃用)

点聚合及点标记的鼠标移入、移出、点击效果的实现(只提供思路,不进行数据效果实现)

const markerData: any[] //获取的标记坐标等信息
const markers: [{
   weight: number, //权重
   lnglat: number[] | string [], //经纬度
   extData:object //其他需要传递的信息,如id、name等
}] = [] 


markerData.map((item: any) => {
markers.push({
    weight: item.weight,
    lnglat: [item.lon, item.lat],
    extData: {
        id: item.id,
        icon: url,
        markerIcon: url
       }
     })
  })


  const clu = new AMap.MarkerClusterer(map, markers, {
    //聚合点自定义样式交互
    renderClusterMarker: (cluster: any) = {
     //marker点标记API
     //自定义聚合样式
    //cluster.data[0].extData可获取到传入的其他数据
    cluster.marker.setAnchor('bottom-center');
    cluster.marker.setIcon(new AMap.Icon({ image: cluster.data[0].extData.markerIcon }));
    cluster.marker.setLabel({
        content: `<span style="cursor: pointer;">${cluster.count}</span>`,
        direction: 'center',
        offset: new AMap.Pixel(0, -5),
    })
    //添加鼠标移入放大效果
    cluster.marker.on('mouseover', () => {
        cluster.marker.setIcon(
            new AMap.Icon({
                image: cluster.marker.getIcon()._opts.image,
                size: new AMap.Size(40, 50), //根据image分辨率计算放大后尺寸
                imageSize: new AMap.Size(40, 50),
            }),
        );
        cluster.marker.setLabel({
            content: `<span style="cursor: pointer;font-size: 20px;">${cluster.count}</span>`,
            direction: 'center',
            offset: new AMap.Pixel(0, -5),
        });
    });
    //鼠标移出还原
    cluster.marker.on('mouseout', () => {
        cluster.marker.setIcon(
            new AMap.Icon({
                image: cluster.marker.getIcon()._opts.image,
                size: new AMap.Size(32, 40),
                imageSize: new AMap.Size(32, 40),
            }),
        );
        cluster.marker.setLabel({
             content: `<span style="cursor: pointer;">${cluster.count}</span>`,
             direction: 'center',
             offset: new AMap.Pixel(0, -5),
        });
    });
},
//非聚合点自定义样式交互
renderMarker: (context: any) => {
    context.marker.setAnchor('bottom-center');
    context.marker.setOffset(new AMap.Pixel(0, 0));
    context.marker.setIcon(new AMap.Icon({ image: context.data[0].extData.markerIcon }));
    context.marker.setLabel({
        content: `<img src=${context.data[0].extData.icon} style="cursor: pointer;" />`,
        direction: 'center',
        offset: new AMap.Pixel(0, -5),
    });
    //鼠标移入移出同上,不再重复
    //marker鼠标点击事件
    context.marker.on('click', () => {
        const params = context.data[0].extData;
        console.log(params.id) //id
        });
     }
 })


  //添加聚合点点击事件
 clu.on('click', (data: any) => {
//判断是否是聚合点,不是聚合点就执行单个点击方式
 if (data.clusterData.length <= 1) return;
//计算所有聚合点的中心点
    let alng = 0,
    alat = 0;
     for (const m of data.clusterData) {
        alng += m.lnglat.lng;
        alat += m.lnglat.lat;
     }
     const lat = alat / data.clusterData.length;
     const lng = alng / data.clusterData.length;
   //以中心点固定倍数放大地图,达到展开聚合点的效果
   map.setZoom(10);
   map.setCenter([lng, lat]);
 });
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容