高德地图js2.0使用MarkerCluster聚合点及添加点击事件
之前的博客中我便提过了在版本变化的趋势下,高德地图也在不断迭代,目前2.0一下版本已经在iOS15 beta版本不适用了,而且2.0一下版本由于卡顿等问题也不在符合用户的使用需要,升级迫在眉睫,但2.0对于标记的聚和与之前版本有较大区别,在此将写法记录一下,也希望能帮到大家。2.0以前对于标记的处理是将标记全部在地图上画出来之后通过MarkerClusterer聚合,不仅对标记的修改较为复杂,还会
之前的博客中我便提过了在版本变化的趋势下,高德地图也在不断迭代,目前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]);
});
renderMarker方法是通过地图缩放实时变化持续调用的,所以我们可以直接修改数据的方式实时修改点上的数据,注意修改完成后缩放一下地图,之后可以也通过this.cluster.setData方法修改要显示在地图上的点
注意:这种写法有个明显的问题,如果出现两个坐标完全相同的点,前一个坐标会被后一个顶掉,如果不能保证坐标完全不同的话,建议对坐标进行去重处理或是修改重复坐标,另外,由于float浮点数加减问题及context.data[0].lnglat方法会去除一部分小数,建议判断时统一所有数据小数精度。
更多推荐
所有评论(0)