百度地图(vue、加载海量点、点聚合)

本文介绍了如何在Vue应用中异步加载百度地图,实现点聚合功能以优化海量数据加载。通过分批加载数据,避免一次性加载大量点导致的地图响应慢问题。详细步骤包括加载地图库、创建地图、处理数据以及实现点聚合的自定义样式。此外,还提到了InfoBox的使用和自定义复杂样式的方法。
摘要由CSDN通过智能技术生成

百度地图(vue、加载海量点、点聚合)

1. 异步加载百度地图

export default function loadBMap (ak) {
    return new Promise((resolve, reject) => {
        //聚合API依赖基础库,因此先加载基础库再加载聚合API
        asyncLoadBaiduJs(ak)
            .then(() => {      
                // 调用加载第三方组件js公共方法加载其他资源库
                // 加载聚合API
                // MarkerClusterer_min.js依赖TextIconOverlay.js。因此先加载TextIconOverlay.js
                asyncLoadJs('http://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay.js')
                .then(() => {
                    asyncLoadJs('http://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js')
                    .then(() => {
                        asyncLoadJs('http://api.map.baidu.com/library/InfoBox/1.2/src/InfoBox_min.js')
                        .then(() => {
                            resolve()
                            return true
                        })
                        .catch(err => { reject(err) })
                    })
                    .catch(err => { reject(err) })
                })
                .catch(err => { reject(err) })
            })
            .catch(err => {
                reject(err)
            })
    })
}
// 加载百度地图基础组件js
export function asyncLoadBaiduJs (ak) {
    return new Promise((resolve, reject) => {
        if (typeof BMap !== 'undefined') {
            resolve(BMap)
            return true
        }
        window.onBMapCallback = function () {
            resolve(BMap)
        }
        let script = document.createElement('script')
        script.type = 'text/javascript'
        script.src = 'http://api.map.baidu.com/api?v=3.0&ak=' + ak + '&callback='
        script.onerror = reject
        document.head.appendChild(script)
    })
}
// 加载第三方组件js公共方法
export function asyncLoadJs (url) {
    return new Promise((resolve, reject) => {
        let script = document.createElement('script')
        script.type = 'text/javascript'
        script.src = url
        document.head.appendChild(script)
        script.onload = () => {
            resolve()
        }
        script.onerror = reject
    })
}

2. 创建地图

import loadBMap from '..../tool/loadBMap.js;

data() {
   return : {
   	pointerAllData: [],  // 存放获取的所有的点
   	allMapData:[], // 存放接口请求的所有的数据
   	markerClusterer: null   // 点聚合
   }
}

loadBMap(ak).then( () => {
     this.newMap = new BMap.Map('mapContain', {
          enableMapClick: false,
          maxZoom: 18,
          minZoom: 6
      }); 
      // 初始化地图实例
      this.newMap.enableScrollWheelZoom(true);
      let point = new BMap.Point(log, lat);
      // 设置中心点
      this.newMap.centerAndZoom(point, .zoom);
      // 个性化地图(自定义样式)
      this.newMap.setMapStyleV2({ 
          styleJson: mapStyleJson
      });
      // 初始化点聚合
      this.markerClusterer = new BMapLib.MarkerClusterer(this.newMap, {markers: this.markers})
      // 获取地图上所有点数据
      this.getAllData();
})

3.处理获取的数据
思路:将1000个点的数据,以100个或者200个截取,去加载。避免一次加载1000个点,地图加载很慢的效果。

getAllData() {
	   // 模拟1000个点数据
       let resultData= []                 
       for (let i = 0; i < 1000; i++){
           let new_point = new BMap.Point(Math.random() * 40 + 85, Math.random() * 30 + 21);
           resultData.push(new_point);
       }
       // 数据分流截取
       let partArr = resultData;
       // this.cutOutData 截取数据
       partArr =  this.cutOutData(resultData, 100);
       let i = 0;
       this.timer = setInterval(() => {
           if (i > partArr .length - 1) {
               clearInterval(this.timer);
           } else {
           	   // 加载海量点方法:
               this.addPointCollection(partArr [i])
           }
           i++
       }, 500)
},
// 加载海量点
addPointCollection(partArr) {
   this.pointerAllData.push(...partArr);
   // 我的思路是 分流截取汇总的点数据 和 接口请求的数据 条数 相同时候,加载海量点
   if (this.pointerAllData.length === this.allMapData.length) {
   	let resultData = [...this.pointerAllData]
   	if (document.createElement('canvas').getContext) { 
   		// 一顿处理数据(站点图标, 自定义popup样式等)
   		let myIcon = new BMap.Icon(mapPicUrl, new BMap.Size(28, 32), {
              imageSize: new BMap.Size(28, 32),
              offset: new BMap.Size(29, 40),
              imageOffset: new BMap.Size(0, 1)
          })
          let marker = new BMap.Marker(pointM, {
              icon: myIcon  // 设计给的图标
          });
          
   			// 利用插件 自定义样式,html 是自己画的样式,
   			// 如果要循环,在html 外面处理好,放入,如_table
   			let html = `<div>
   				<p class="mapclass">${v.name}</p>
   				<table>${_table}</table>
   			</div>`
            let infoBox = new BMapLib.InfoBox(this.map, html, {
                offset: new BMap.Size(10, 20),
                // enableAutoPan: true,
                closeIconMargin: "14px 8px 12px 10px",
                closeIconUrl: closeUrl,
                enableAutoPan: true,
                align: INFOBOX_AT_TOP
            });
            infoBox.open(marker);
   			// 官网方法:
   	       let options = {
   	            size: BMAP_POINT_SIZE_BIG,
   	            shape: BMAP_POINT_SHAPE_WATERDROP,
   	            color: '#d340c3'
   	        };
   	
   	        let pointCollection = new BMap.PointCollection(pointerAll, options);
   	        this.newMap.addOverlay(pointCollection);  // 添加Overlay

   		// 点聚合方法:
   		this.markers = 【处理好的数据】
   		this.toAddMarkerClusterer(this.markers)
   		}
   }
},
// 点聚合【和官网方法一样】
toAddMarkerClusterer() {
     // 清除聚合点
     this.markerClusterer.clearMarkers();
     this.markerClusterer.addMarkers(this.markers);
     // 修改点聚合的样式
     let myStyles = [
         {
             url: this.iconLocation,
             size: new BMap.Size(35, 41),
             opt_anchor: [16, 0], // 16
             textColor: '#ffffff',
             opt_textSize: 10
         }
     ]
     this.markerClusterer.setStyles(myStyles);
}

//  分流数据
cutOutData (array, size) {
   const length = array.length;
   if (!length || !size || size < 1) {
       return [];
   }
   let index = 0; //用来表示切割元素的范围start
   let resIndex = 0; //用来递增表示输出数组的下标
   let result = new Array(Math.ceil(length / size));
   while (index < length) {
       result[resIndex++] = array.slice(index, (index += size));
   }
   return result;
},

在这里插入图片描述
在这里插入图片描述
// onBMapCallback
// InfoBox ,好像还有 openWindow方法, 或者自定义复杂样式
// 还有,自定义样式,最好自己在页面上画好,js里面创建的时 就便捷多了。
感谢同事们的帮助~,希望自己不断进步!

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值