1.需要引入MarkerClusterer_min.js和textIconOverlay.js
<script src="js/bmap/textIconOverlay/textIconOverlay.js"></script> <script src="js/bmap/MarkerClusterer_min.js"></script>2.js
//初始化打点数据 var markers=[]; //初始化点聚合 var markerClusterer=new BMapLib.MarkerClusterer(page.map, {markers:markers}); var data=[]//数据 var markers = [];var pointslng=[] data.forEach(function(item,idx){ var myIcon = new BMap.Icon("image/circle.png", new BMap.Size(24, 24), { // offset: new BMap.Size(20, 20), // 指定定位位置 //imageOffset: new BMap.Size(0, 0) // 设置图片偏移 }); var pt=new BMap.Point(lng,lat); pointslng.push(pt) var marker=new BMap.Marker(pt,{icon:myIcon}) marker.addEventListener('click', function (e) { var str='<div>str</div>' var p=new BMap.Point(e.point.lng,e.point.lat); var myLabel = new BMap.Label(str, //为lable填写内容 {offset:new BMap.Size(0,0), //label的偏移量,为了让label的中心显示在点上 position:p}); //label的位置 myLabel.setStyle({ //给label设置样式,任意的CSS都是可以的 fontSize:"14px", //字号 border:"0", //边 textAlign:"left", //文字水平靠左显示 borderRadius:'5px', color:'#fff', cursor:"pointer", AutoSize:"false", maxWidth:'1000px', backgroundColor:'rgba(0,0,0,0.7)' }); myLabel.setZIndex(99) map.addOverlay(myLabel);//把label添加到地图上 }); markers.push(marker); }) //添加聚合点 markerClusterer.addMarkers(markers) map.setViewport(pointslng)markerClusterer.clearMarkers(); 注意:全局要先进行初始化markerClusterer
因为项目要求刚开始必须加载所有的点,所以刚开始的数据没办法减少,导致移动或者缩放很卡,如果使用点聚合,因为个别点归于接近,在18级(项目只到18级)还是显示多个,显示不了单个,所以目前做了2项优化: 1.接口使用gzip获取数据(减少数据传输时间),然后把数据分成若干份,使用setTimeout,延迟渲染部分数据 2.点只显示可视范围内的 接下来主要讲第二项: 1.先定义一个全局的空数组markers var marker=[]; 2.渲染全部的点(我们项目要求全部。。。)
pointData(data) function pointData(data){//海量点 markers=[]//重新渲染需要清空 data.forEach(function(item,idx){ //logo_type 1:蓝色,2:灰色,3:红色 var logo='image/china_telecom.png'; var myIcon = new BMap.Icon(logo, new BMap.Size(16, 16)); var pt=new BMap.Point(item.lng,item.lat); var marker=new BMap.Marker(pt,{icon:myIcon}) map.addOverlay(marker) markers.push(marker) //PointClick(marker,item)//点击事件可不写 //pointMouse(marker,item)//鼠标滑过事件可不写 }) }2.监听缩放平移 这一部分事件来源于这位大神的文章
map.addEventListener("zoomend", function () { getBounds('zoomend'); }); //地图绑定拖拽事件 map.addEventListener('dragend', function(e){ getBounds('dragend'); }); /** * 获取可视区域 * @type {string} 类型 * */ function getBounds(type){ //函数节流 if(getBounds.timer){ clearTimeout(getBounds.timer); getBounds.timer=null; } getBounds.timer=setTimeout(function(){ var map=page.map var bounds = map.getBounds(), //获取可视区域 SouthWest = bounds.getSouthWest(), //可视区域左下角 NorthEast = bounds.getNorthEast(); //可视区域右上角 // console.log("当前地图可视范围是:" + SouthWest.lng + "," + SouthWest.lat + "到" + NorthEast.lng + "," + NorthEast.lat); var data=boundsShow(SouthWest.lng,NorthEast.lng,SouthWest.lat,NorthEast.lat) //把不在可视区域的maker隐藏起来 for(var i=0,lengths=data.listhide.length;i<lengths;i++){ data.listhide[i].hide(); } console.log('共有:'+markers.length+'个点位,显示:'+data.listshow.length+'个点位');//设置地图上的marker数量) },200); } /** * 在可视区域显示,不在可视区域隐藏 * @smlng {number} 小 经度 * @bglng {number} 大 经度 * @smlat {number} 小纬度 * @bglat {number} 大纬度 * * return 返回显示的数量与隐藏的数量 * */ function boundsShow(smlng,bglng,smlat,bglat){ var listhide=[],//隐藏的数据 listshow=[];//显示的数据 for(var i=0,lengths=markers.length;i<lengths;i++){ var _point=markers[i].point; //如果marker的经度 小于可视范围的最大经度大于可视范围的最小经度-- //并且marker的纬度 小于可是范围的最大纬度大于可视范围的最小纬度--则需要显示 if(smlng<_point.lng && _point.lng<bglng && smlat<_point.lat && _point.lat < bglat){ //显示 listshow.push(markers[i]); //如果之前被隐藏则显示 if(!markers[i].isVisible()){ markers[i].show(); } }else{ //不显示 listhide.push(markers[i]); } } //返回显示的数量与隐藏的数量 return{ listshow:listshow, listhide:listhide } }类似于批量点的优化