先吹下牛:无线加载海量点进行绘制,显示时间控制在毫秒级别
实现原理:
1、获取大量点数据,生成point及marker,存储起来2、初始加载200(可忍受卡顿时间的临界值)3、地图拖动或缩放结束时,再次加载当前可视区域内的50个点(可忍受卡顿时间的临界值)4、地图层级放大到最大时,去掉限制,获取当前可视区域内所有点(因为可视区域经纬度很小了,因此不会出现大量数据点堆积导致卡顿)总结一句话:按照可视区域按需加载标注点,放大到最大显示当前可视区域的所有点
实现的先决条件:
实现步骤:1、绘制的标注点较多,达到百度绘点卡顿条件2、不需要一次性全部展示,可随地图拖动缩放而显示
1、为地图设置最大缩放级别2、为地图注册拖动及缩放事件var map = new BMap.Map("map_demo",{minZoom : 13, maxZoom : 18 });map.addEventListener("moveend", queryInRect); //拖动map.addEventListener("zoomend", queryInRect); //所当3、获取标注点数据,生成marker,并显示前200个点var bounds = map.getBounds();var sw = bounds.getSouthWest();var ne = bounds.getNorthEast();var lngSpan = Math.abs(sw.lng - ne.lng);var latSpan = Math.abs(ne.lat - sw.lat);var points=[],markers=[],currMarkers={};for (var i = 0; i < 26000; i ++) {var point = new BMap.Point(sw.lng + lngSpan * (Math.random() * 0.7+0.02), ne.lat - latSpan * (Math.random() * 0.7)-0.02);points.push(point);markers.push(new BMap.Marker(point));if(i<200){//初始显示200个点(可自定义自己能容忍卡顿时间的极限点数)map.addOverlay(markers[i]);//绘制到地图上currMarkers['markers'+i]=markers[i];//添加到已显示的点内}}4、地图拖动及缩放监听事件function queryInRect (event) {var cp = map.getBounds(); // 返回map可视区域,以地理坐标表示var sw = cp.getSouthWest(); // 返回矩形区域的西南角var ne = cp.getNorthEast(); // 返回矩形区域的东北角var zoom = map.getZoom(); //当前缩放级别var swlng=sw.lng,swlat=sw.lat,nelng=ne.lng,nelat=ne.lat,currShowCount=0;//本次拖动或缩放已显示的点数for(var i=0;i<points.length;i++){if(points[i].lng>swlng && points[i].lngswlat && points[i].latif(currMarkers['markers'+i]==undefined){//判断当前点是否已显示在地图上,显示则无需重新绘制if(zoom==18 || currShowCount<50){//放大到最大层数后,则显示当前可视区内所有点,鉴于层级较大显示的摄像头较少,因此不会出现卡顿情况map.addOverlay(markers[i]);currMarkers['markers'+i]=markers[i];//记录已显示的点currShowCount++;//本次已显示数加1}else{return;}}}}}5、打开文件体验一下,完美!
完整的js代码:
// 百度地图API功能
var map = new BMap.Map("map_demo",{minZoom : 13, maxZoom : 18 });
var point = new BMap.Point(116.400244,39.92556);
map.centerAndZoom(point, 13);
map.enableScrollWheelZoom(true);
map.addEventListener("moveend", queryInRect);
map.addEventListener("zoomend", queryInRect);
// 随机向地图添加26000个标注
var bounds = map.getBounds();
var sw = bounds.getSouthWest();
var ne = bounds.getNorthEast();
var lngSpan = Math.abs(sw.lng - ne.lng);
var latSpan = Math.abs(ne.lat - sw.lat);
var points=[];
var points=[],markers=[],currMarkers={};
for (var i = 0; i < 26000; i ++) {
var point = new BMap.Point(sw.lng + lngSpan * (Math.random() * 0.7+0.02), ne.lat - latSpan * (Math.random() * 0.7)-0.02);
points.push(point);
markers.push(new BMap.Marker(point));
if(i<200){//初始显示200个点(可自定义自己能容忍卡顿时间的极限点数)
map.addOverlay(markers[i]);//绘制到地图上
currMarkers['markers'+i]=markers[i];//添加到已显示的点内
}
}
function queryInRect (event) {
var cp = map.getBounds(); // 返回map可视区域,以地理坐标表示
var sw = cp.getSouthWest(); // 返回矩形区域的西南角
var ne = cp.getNorthEast(); // 返回矩形区域的东北角
var zoom = map.getZoom(); //当前缩放级别
var swlng=sw.lng,
swlat=sw.lat,
nelng=ne.lng,
nelat=ne.lat,
currShowCount=0;//本次拖动或缩放已显示的点数
for(var i=0;i<points.length;i++){
if(points[i].lng>swlng && points[i].lngswlat && points[i].lat
if(currMarkers['markers'+i]==undefined){//判断当前点是否已显示在地图上,显示则无需重新绘制
if(zoom==18 || currShowCount<50){//放大到最大层数后,则显示当前可视区内所有点,鉴于层级较大显示的摄像头较少,因此不会出现卡顿情况
map.addOverlay(markers[i]);
currMarkers['markers'+i]=markers[i];//记录已显示的点
currShowCount++;//本次已显示数加1
}else{
return;
}
}
}
}
}