百度地图中自定义点聚合实现
点聚合 (MarkerClusterer 标记聚合器)用来解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能。
点聚合的实现原理是按照以某点为中心的正方形作为区域,把此区域的点聚合在一个点上,并随着地图比例尺改变此点区域大小,同时改变聚合点的数量。
默认百度地图的聚合marker效果如下:
官方聚合示例:http://lbsyun.baidu.com/jsdemo.htm#c1_4
- 点击聚合点默认放大
在实际项目开发中,我遇到了点聚合的一个难题:如何实现自定义聚合点点击事件。
如果直接在源码上修改,时间成本很高,
聚合点默认是没有点击监听事件的,而marker有点击监听事件
因此最终得到一个解决方案:
思路:
1. 根据百度聚合API创建聚合点,但是只需要用到点聚合后的数据,利用自定义样式进行隐藏此聚合点(目的是消除默认聚合点会点击放大效果)
2. 拿到数据后创建一个自定义标注marker,可设置标注样式(相当于利用标注模拟一个聚合点)
3. 创建标注的label,自定义label样式,用来显示聚合数量(利用聚合API的数据可得到聚合点的marker数量,进行自定义label样式模拟聚合点数字的显示)
4. 给marker设置点击监听事件,自定义事件函数内容
示例效果:
下面是具体实现:
核心代码部分:
var datas = [{
'localtion': '120.585239,31.298881'
}, {
'localtion': '120.585239,31.298881'
}, {
'localtion': '120.585239,31.298881'
}, {
'localtion': '120.585239,31.298881'
}, {
'localtion': '120.585239,31.298881'
}]
//先创建初始marker点
var markers = [];
for (var i = 0; i < datas.length; i++) {
var data = datas[i];
var localtion = data.localtion.split(',');
var m = new BMap.Marker(new BMap.Point(localtion[0], localtion[1]));
m.data = data;
markers.push(m);
}
//调用聚合封装函数
markerClustersPoint(markers);
//
//地图缩放重新计算聚合点
map.addEventListener("zoomend",function(){
markerClustersPoint(markers);
});
//
//聚合添加
markerClustersPoint(markers) {
if (markerClusterer) {
markerClusterer.clearMarkers();//清除聚合
}
//添加点聚合API(index.html中需引入文件)
// <script type="text/javascript" src="http://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js">
// </script>
// <script type="text/javascript" src="http://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js">
// </script>
markerClusterer = new BMapLib.MarkerClusterer(this.map, {
markers: markers,
minClusterSize: 3, //最小的聚合数量,小于该数量的不能成为一个聚合,默认为2
styles: [
{
//此处仅放置style,不要写任何内容,否则会有默认聚合的数字显示溢出
// url: "img/info.png",
// size: new BMap.Size(0, 0)
}
]
});
console.log("进入聚合函数markerClusterer", markerClusterer);
//
// 拿到所有的聚合点
//markerClusterer中的 _clusters是一个数组,包含了可视范围的所有聚合点
var cluster = markerClusterer._clusters;
var oldmk = [];
for (var i = 0; i < cluster.length; i++) {
//cluster[i]._markers中包含此聚合点的所有marker集合
//marker长度大于2时不进行聚合效果显示
if (cluster[i]._markers.length < 2) continue;
//自定义函数内容,可进行聚合点数据获取操作
//......
//......
//拿到聚合点中的marker数量,用于数字显示
var cluserMakerSum = cluster[i]._markers.length;
//添加marker
oldmk.push(addMarkerCluser(cluster[i]._center));
}
},
// 标记自定义marker
addMarkerCluser(point) {
var markerdef = new BMap.Marker(point, {
// icon: 设置marker样式
icon: new BMap.Symbol(BMap_Symbol_SHAPE_CIRCLE, {
scale: 20,
strokeWeight: 1,
strokeColor: "white",
fillColor: "blue",
fillOpacity: 0.59
})
});
//设置marker的label
var labelTitleCluser = cluserMakerSum ;
let label = new BMap.Label(labelTitleCluser, {
offset: new BMap.Size(12, 12)
});
//设置label样式
label.setStyle({
color: "#fff",
fontSize: "14px",
backgroundColor: "0.05",
border: "0px "
});
markerdef.setLabel(label);
//监听点击事件
markerdef.addEventListener("click", function() {
console.log("点击自定义聚合maker");
});
map.addOverlay(markerdef);
//
return markerdef;
},