一、问题
最近在做公司的一个项目,需要在百度地图生成海量点,最开始只是把全部的marker一起显示到地图上,因为一次生成的点比较多,会发生地图卡顿等问题;
二、解决方案:MarkerClusterer
百度地图-JS API官方文档
MarkerClusterer:多标注聚合器。此工具解决加载大量点要素到地图上造成缓慢,且产生覆盖现象的问题。
步骤:
1、在html文件中引入MarkerClusterer_min.js 、 TextIconOverlay_min.js 文件
MarkerClusterer_min.js 聚合器的库文件
TextIconOverlay_min.js 标记器样式的库文件
<script type="text/javascript" src="static/js/bmap-offline/TextIconOverlay_min.js"></script>
<script type="text/javascript" src="static/js/bmap-offline/MarkerClusterer_min.js"></script>
2、将所有生成的标记marker存入一个数组markers,再new BMapLib.MarkerClusterer传给第二个参数的markers属性,第一个参数传入地图实例
this.markerClusterer = new BMapLib.MarkerClusterer(this.map, {markers});
3、创建时也可根据需求自定义参数配置param,比如修改聚合器的图片和样式之类的:
* MarkerClusterer 创建时传入的参数列表
* @class 用来解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能
* @constructor
* @param {Map} map 地图的一个实例。
* @param {Json Object} options 可选参数,可选项包括:<br />
* markers {Array<Marker>} 要聚合的标记数组<br />
* girdSize {Number} 聚合计算时网格的像素大小,默认60<br />
* maxZoom {Number} 最大的聚合级别,大于该级别就不进行相应的聚合<br />
* minClusterSize {Number} 最小的聚合数量,小于该数量的不能成为一个聚合,默认为2<br />
* isAverangeCenter {Boolean} 聚合点的落脚位置是否是所有聚合在内点的平均值,默认为否,落脚在聚合内的第一个点<br />
* styles {Array<IconStyle>} 自定义聚合后的图标风格,请参考TextIconOverlay类<br />
三、采用聚合点的代码
this.markerClusterer && this.markerClusterer.clearMarkers(); //如果有聚合标记器,生成点之前从地图上彻底清除所有的标记
let markers = [];//存标记的数组
this.baiduMapMakerData.forEach((item, i) => { //baiduMapMakerData 后端返回的Marker数据
let {
X,
Y,
abnormal_type,
station_area_name
} = item;
let iconUrl = !abnormal_type ? '正常' : '异常';
var icon = new BMap.Icon(`static/image/mapicon/${iconUrl}.png`, new BMap.Size(24, 30));
let marker = new BMap.Marker(new BMap.Point(X, Y), { //生成maker
icon
});
markers.push(marker); //存入数组
})
let options = {
markers,
minClusterSize:5,
styles:[],
maxZoom:15,
isAverangeCenter:true
}
// 设置聚合icon样式
var sizes = [53, 56, 66, 78, 90];
for(var i = 0, size; size = sizes[i]; i++){
options.styles.push({
url:this.combineIconUrl + i + '.png',
size: new BMap.Size(size, size)
});
}//for循环的简洁写法
this.markerClusterer = new BMapLib.MarkerClusterer(this.map, options); //生成聚合器
四、改之前代码
//改之前的生成点的代码
this.map.clearOverlays();
this.baiduMapMakerData.forEach((item, i) => {
let index = i;
this.allBaiduIconcCreateTimer[index] = setTimeout(() => {
let {
X,
Y,
abnormal_type,
station_area_name
} = item;
let iconUrl = !abnormal_type ? '正常' : '异常';
var icon = new BMap.Icon(`static/image/mapicon/${iconUrl}.png`, new BMap.Size(24, 30));
let marker = new BMap.Marker(new BMap.Point(X, Y), {
icon
});
this.map.addOverlay(marker);
}, index * 5)
})
五、效果