公司要求做个百度地图点聚合的性能优化,需一次性加载9万条数据。

记录下自己的优化过程。(只想看优化代码的可直接移步:步骤三)

一、引入百度地图

  • vue项目中,在index.html文件中用script标签引入百度地图(ak=秘钥)
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=6BUBoNWirHMQajt9f2hzWF1mDK7MsR8n"></script>
  • 并初始化地图
    initMap() {
      this.map = new BMap.Map('map_layer', {mapType: BMAP_HYBRID_MAP});
      this.map.centerAndZoom(new BMap.Point(116.404, 39.915), 5);
      this.map.enableScrollWheelZoom(true);
    },

二、在页面的头部应用点聚合工具开源库的文件

  vue项目,可在index.html中用script标签引入

  <script type="text/javascript" src="http://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js"></script>
  <script type="text/javascript" src="./static/MarkerClusterer.js"></script>

 

三、点聚合优化,参考博客1 + 参考博客2

  百度的点聚合算法 是基于方格和距离的聚合算法,即开始的时候地图上没有任何已知的聚合点,然后遍历所有的点,去计算点的外包正方形(由gridSize指定),若此点的外包正方形与现有的聚合点的外包正方形不相交,则新建聚合点,若相交就把该点加到该聚合点,效果如下图。

百度地图点聚合MarkerClusterer性能优化

  应用百度地图源码,超过2000点,就卡顿的无法使用了。于是对源码进行优化。

  百度地图中的点聚合主要有两个文件,一个控制聚合即MarkerClusterer.js,一个控制显示的样子TextIconOverlay.js,(这里吐槽一下,官方给的文档并没有说明!!!)

http://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js(无格式压缩版)

http://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay.js

http://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js(无格式压缩版)

http://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer.js


 百度地图源码解析,可参考博客

 这里展示百度地图MarkerClusterer.js的部分源码,用以说明优化的原理。

/**
     * 根据所给定的标记,创建聚合点
     * @return 无返回值
     */
    MarkerClusterer.prototype._createClusters = function(){
        var mapBounds = this._map.getBounds();
        var extendedBounds = getExtendedBounds(this._map, mapBounds, this._gridSize);
        for(var i = 0, marker; marker = this._markers[i]; i++){
            if(!marker.isInCluster && extendedBounds.containsPoint(marker.getPosition()) ){ 
                this._addToClosestCluster(marker);
            }
        }   
    };

    /**
     * 根据标记的位置,把它添加到最近的聚合中
     * @param {BMap.Marker} marker 要进行聚合的单个标记
     *
     * @return 无返回值。
     */
    MarkerClusterer.prototype._addToClosestCluster = function (marker){
        var distance = 4000000;
        var clusterToAddTo = null;
        var position = marker.getPosition();
        for(var i = 0, cluster; cluster = this._clusters[i]; i++){
            var center = cluster.getCenter();
            if(center){
                var d = this._map.getDistance(center, marker.getPosition());
                if(d < distance){
                    distance = d;
                    clusterToAddTo = cluster;
                }
            }
        }
    
        if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)){
            clusterToAddTo.addMarker(marker);
        } else {
            var cluster = new Cluster(this);
            cluster.addMarker(marker);            
            this._clusters.push(cluster);
        }    
    };
View Code

相关文章: