zoukankan      html  css  js  c++  java
  • 百度地图点聚合MarkerClusterer,性能优化

    参考文献:http://www.cnblogs.com/lightnull/p/6184867.html

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

    好的,笔者开始了作死之旅。上面笔者只是生成了50个随机点。

    接下来要测试下1000个点,嗯有点小卡,但是还能操作,

    2000个点,我的天,这shit一样的卡顿是什么鬼!!

    5000个点,好的,完美,动也动不了 简直漂亮

    10000个点,页面无响应。。。。。。。

    ----------我只是一条漂亮的分割线----------

    百度地图 点聚合的部分源码:

    /**
         * 根据所给定的标记,创建聚合点
         * @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);
            }    
        };

    以上两个方法就是前文所述的算法的具体实现,

    先排除所有不在可视范围的点,然后通过比较marker点和聚合点的距离,拿到距离最近的聚合点,判断marker点是否在聚合点的外包正方形内;

    这一段是正常算法需要没啥问题,看起来问题只能出在  cluster.addMarker(marker);  了

    if(this.isMarkerInCluster(marker)){
                return false;
            }//也可用marker.isInCluster判断,外面判断OK,这里基本不会命中
        
            if (!this._center){
                this._center = marker.getPosition();
                this.updateGridBounds();//
            } else {
                if(this._isAverageCenter){
                    var l = this._markers.length + 1;
                    var lat = (this._center.lat * (l - 1) + marker.getPosition().lat) / l;
                    var lng = (this._center.lng * (l - 1) + marker.getPosition().lng) / l;
                    this._center = new BMap.Point(lng, lat);
                    this.updateGridBounds();
                }//计算新的Center
            }
        
            marker.isInCluster = true;
            this._markers.push(marker);
        
            var len = this._markers.length;
            if(len < this._minClusterSize ){     
                this._map.addOverlay(marker);
                //this.updateClusterMarker();
                return true;
            } else if (len === this._minClusterSize) {
                for (var i = 0; i < len; i++) {
                    this._markers[i].getMap() && this._map.removeOverlay(this._markers[i]);
                }
                
            } 
            this._map.addOverlay(this._clusterMarker);
            this._isReal = true;
            this.updateClusterMarker();
            return true;
        };

    果然不出所料,在addMarker() 方法内不停的去进行dom操作,不卡才怪。为什么度娘就不等计算结束后,在去一次操作完呢,

    于是笔者把标黄的代码抽离了出来给cluster类加了一个render方法, 然后在MarkerClusterer.createClusters方法最后加了一个遍历所有聚合点的操作,代码如下:

    Cluster.prototype.render = function(){
        var len = this._markers.length;
             
        if (len < this._minClusterSize) {
                for (var i = 0; i < len; i++) {
                    this._map.addOverlay(this._markers[i]);
                }
        } else {
                this._map.addOverlay(this._clusterMarker);
                this._isReal = true;
                this.updateClusterMarker();
        }
    }
    var len = this._markers.length;
    for (var i = 0; i < len; i++) {
        if(this._clusters[i]){
            this._clusters[i].render();
        }
    }

    测试比较一下吧!

    Maker数量 原版点聚合js(时间:毫秒 ms) 优化后点聚合js(时间:毫秒 ms)
    100 95 88 60 65
    1000 588 612 146 133
    10000 5840 5772 439 424
    30000 19987 20170 1334 1457

    新手上路!!

    贴上修改后的代码:

      1 /**
      2  * @fileoverview MarkerClusterer标记聚合器用来解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能。
      3  * 主入口类是<a href="symbols/BMapLib.MarkerClusterer.html">MarkerClusterer</a>,
      4  * 基于Baidu Map API 1.2。
      5  *
      6  * @author Baidu Map Api Group 
      7  * @version 1.2
      8  */
      9   
     10  
     11 /** 
     12  * @namespace BMap的所有library类均放在BMapLib命名空间下
     13  */
     14 var BMapLib = window.BMapLib = BMapLib || {};
     15 (function(){
     16      
     17     /**
     18      * 获取一个扩展的视图范围,把上下左右都扩大一样的像素值。
     19      * @param {Map} map BMap.Map的实例化对象
     20      * @param {BMap.Bounds} bounds BMap.Bounds的实例化对象
     21      * @param {Number} gridSize 要扩大的像素值
     22      *
     23      * @return {BMap.Bounds} 返回扩大后的视图范围。
     24      */
     25     var getExtendedBounds = function(map, bounds, gridSize){
     26         bounds = cutBoundsInRange(bounds);
     27         var pixelNE = map.pointToPixel(bounds.getNorthEast());
     28         var pixelSW = map.pointToPixel(bounds.getSouthWest()); 
     29         pixelNE.x += gridSize;
     30         pixelNE.y -= gridSize;
     31         pixelSW.x -= gridSize;
     32         pixelSW.y += gridSize;
     33         var newNE = map.pixelToPoint(pixelNE);
     34         var newSW = map.pixelToPoint(pixelSW);
     35         return new BMap.Bounds(newSW, newNE);
     36     };
     37  
     38     /**
     39      * 按照百度地图支持的世界范围对bounds进行边界处理
     40      * @param {BMap.Bounds} bounds BMap.Bounds的实例化对象
     41      *
     42      * @return {BMap.Bounds} 返回不越界的视图范围
     43      */
     44     var cutBoundsInRange = function (bounds) {
     45         var maxX = getRange(bounds.getNorthEast().lng, -180, 180);
     46         var minX = getRange(bounds.getSouthWest().lng, -180, 180);
     47         var maxY = getRange(bounds.getNorthEast().lat, -74, 74);
     48         var minY = getRange(bounds.getSouthWest().lat, -74, 74);
     49         return new BMap.Bounds(new BMap.Point(minX, minY), new BMap.Point(maxX, maxY));
     50     }; 
     51  
     52     /**
     53      * 对单个值进行边界处理。
     54      * @param {Number} i 要处理的数值
     55      * @param {Number} min 下边界值
     56      * @param {Number} max 上边界值
     57      * 
     58      * @return {Number} 返回不越界的数值
     59      */
     60     var getRange = function (i, mix, max) {
     61         mix && (i = Math.max(i, mix));
     62         max && (i = Math.min(i, max));
     63         return i;
     64     };
     65  
     66     /**
     67      * 判断给定的对象是否为数组
     68      * @param {Object} source 要测试的对象
     69      *
     70      * @return {Boolean} 如果是数组返回true,否则返回false
     71      */
     72     var isArray = function (source) {
     73         return '[object Array]' === Object.prototype.toString.call(source);
     74     };
     75  
     76     /**
     77      * 返回item在source中的索引位置
     78      * @param {Object} item 要测试的对象
     79      * @param {Array} source 数组
     80      *
     81      * @return {Number} 如果在数组内,返回索引,否则返回-1
     82      */
     83     var indexOf = function(item, source){
     84         var index = -1;
     85         if(isArray(source)){
     86             if (source.indexOf) {
     87                 index = source.indexOf(item);
     88             } else {
     89                 for (var i = 0, m; m = source[i]; i++) {
     90                     if (m === item) {
     91                         index = i;
     92                         break;
     93                     }
     94                 }
     95             }
     96         }        
     97         return index;
     98     };
     99  
    100     /**
    101      *@exports MarkerClusterer as BMapLib.MarkerClusterer
    102      */
    103     var MarkerClusterer =  
    104         /**
    105          * MarkerClusterer
    106          * @class 用来解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能
    107          * @constructor
    108          * @param {Map} map 地图的一个实例。
    109          * @param {Json Object} options 可选参数,可选项包括:<br />
    110          *    markers {Array<Marker>} 要聚合的标记数组<br />
    111          *    girdSize {Number} 聚合计算时网格的像素大小,默认60<br />
    112          *    maxZoom {Number} 最大的聚合级别,大于该级别就不进行相应的聚合<br />
    113          *    minClusterSize {Number} 最小的聚合数量,小于该数量的不能成为一个聚合,默认为2<br />
    114          *    isAverangeCenter {Boolean} 聚合点的落脚位置是否是所有聚合在内点的平均值,默认为否,落脚在聚合内的第一个点<br />
    115          *    styles {Array<IconStyle>} 自定义聚合后的图标风格,请参考TextIconOverlay类<br />
    116          */
    117         BMapLib.MarkerClusterer = function(map, options){
    118             if (!map){
    119                 return;
    120             }
    121             this._map = map;
    122             this._markers = [];
    123             this._clusters = [];
    124              
    125             var opts = options || {};
    126             this._gridSize = opts["gridSize"] || 60;
    127             this._maxZoom = opts["maxZoom"] || 18;
    128             this._minClusterSize = opts["minClusterSize"] || 2;           
    129             this._isAverageCenter = false;
    130             if (opts['isAverageCenter'] != undefined) {
    131                 this._isAverageCenter = opts['isAverageCenter'];
    132             }    
    133             this._styles = opts["styles"] || [];
    134          
    135             var that = this;
    136             this._map.addEventListener("zoomend",function(){
    137                 that._redraw();     
    138             });
    139      
    140             this._map.addEventListener("moveend",function(){
    141                  that._redraw();     
    142             });
    143  
    144             var mkrs = opts["markers"];
    145             isArray(mkrs) && this.addMarkers(mkrs);
    146         };
    147  
    148     /**
    149      * 添加要聚合的标记数组。
    150      * @param {Array<Marker>} markers 要聚合的标记数组
    151      *
    152      * @return 无返回值。
    153      */
    154     MarkerClusterer.prototype.addMarkers = function(markers){
    155         for(var i = 0, len = markers.length; i <len ; i++){
    156             this._pushMarkerTo(markers[i]);
    157         }
    158         this._createClusters();   
    159     };
    160  
    161     /**
    162      * 把一个标记添加到要聚合的标记数组中
    163      * @param {BMap.Marker} marker 要添加的标记
    164      *
    165      * @return 无返回值。
    166      */
    167     MarkerClusterer.prototype._pushMarkerTo = function(marker){
    168         var index = indexOf(marker, this._markers);
    169         if(index === -1){
    170             marker.isInCluster = false;
    171             this._markers.push(marker);//Marker拖放后enableDragging不做变化,忽略
    172         }
    173     };
    174  
    175     /**
    176      * 添加一个聚合的标记。
    177      * @param {BMap.Marker} marker 要聚合的单个标记。
    178      * @return 无返回值。
    179      */
    180     MarkerClusterer.prototype.addMarker = function(marker) {
    181         this._pushMarkerTo(marker);
    182         this._createClusters();
    183     };
    184  
    185     /**
    186      * 根据所给定的标记,创建聚合点,并且遍历所有聚合点
    187      * @return 无返回值
    188      */
    189     MarkerClusterer.prototype._createClusters = function(){
    190         var mapBounds = this._map.getBounds();
    191         var extendedBounds = getExtendedBounds(this._map, mapBounds, this._gridSize);
    192         for(var i = 0, marker; marker = this._markers[i]; i++){
    193             if(!marker.isInCluster && extendedBounds.containsPoint(marker.getPosition()) ){ 
    194                 this._addToClosestCluster(marker);                
    195             }
    196         }
    197 
    198         var len = this._markers.length;
    199         for (var i = 0; i < len; i++) {
    200             if(this._clusters[i]){
    201                 this._clusters[i].render();
    202             }
    203         }
    204     };
    205  
    206     /**
    207      * 根据标记的位置,把它添加到最近的聚合中
    208      * @param {BMap.Marker} marker 要进行聚合的单个标记
    209      *
    210      * @return 无返回值。
    211      */
    212     MarkerClusterer.prototype._addToClosestCluster = function (marker){
    213         var distance = 4000000;
    214         var clusterToAddTo = null;
    215         var position = marker.getPosition();
    216         for(var i = 0, cluster; cluster = this._clusters[i]; i++){
    217             var center = cluster.getCenter();
    218             if(center){
    219                 var d = this._map.getDistance(center, marker.getPosition());
    220                 if(d < distance){
    221                     distance = d;
    222                     clusterToAddTo = cluster;
    223                 }
    224             }
    225         }
    226      
    227         if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)){
    228             clusterToAddTo.addMarker(marker);
    229         } else {
    230             var cluster = new Cluster(this);
    231             cluster.addMarker(marker);            
    232             this._clusters.push(cluster);
    233         }    
    234     };
    235  
    236     /**
    237      * 清除上一次的聚合的结果
    238      * @return 无返回值。
    239      */
    240     MarkerClusterer.prototype._clearLastClusters = function(){
    241         for(var i = 0, cluster; cluster = this._clusters[i]; i++){            
    242             cluster.remove();
    243         }
    244         this._clusters = [];//置空Cluster数组
    245         this._removeMarkersFromCluster();//把Marker的cluster标记设为false
    246     };
    247  
    248     /**
    249      * 清除某个聚合中的所有标记
    250      * @return 无返回值
    251      */
    252     MarkerClusterer.prototype._removeMarkersFromCluster = function(){
    253         for(var i = 0, marker; marker = this._markers[i]; i++){
    254             marker.isInCluster = false;
    255         }
    256     };
    257     
    258     /**
    259      * 把所有的标记从地图上清除
    260      * @return 无返回值
    261      */
    262     MarkerClusterer.prototype._removeMarkersFromMap = function(){
    263         for(var i = 0, marker; marker = this._markers[i]; i++){
    264             marker.isInCluster = false;
    265             tmplabel = marker.getLabel();
    266             this._map.removeOverlay(marker);       
    267             marker.setLabel(tmplabel);
    268         }
    269     };
    270  
    271     /**
    272      * 删除单个标记
    273      * @param {BMap.Marker} marker 需要被删除的marker
    274      *
    275      * @return {Boolean} 删除成功返回true,否则返回false
    276      */
    277     MarkerClusterer.prototype._removeMarker = function(marker) {
    278         var index = indexOf(marker, this._markers);
    279         if (index === -1) {
    280             return false;
    281         }
    282         tmplabel = marker.getLabel();
    283         this._map.removeOverlay(marker);
    284         marker.setLabel(tmplabel);
    285         this._markers.splice(index, 1);
    286         return true;
    287     };
    288  
    289     /**
    290      * 删除单个标记
    291      * @param {BMap.Marker} marker 需要被删除的marker
    292      *
    293      * @return {Boolean} 删除成功返回true,否则返回false
    294      */
    295     MarkerClusterer.prototype.removeMarker = function(marker) {
    296         var success = this._removeMarker(marker);
    297         if (success) {
    298             this._clearLastClusters();
    299             this._createClusters();
    300         }
    301         return success;
    302     };
    303      
    304     /**
    305      * 删除一组标记
    306      * @param {Array<BMap.Marker>} markers 需要被删除的marker数组
    307      *
    308      * @return {Boolean} 删除成功返回true,否则返回false
    309      */
    310     MarkerClusterer.prototype.removeMarkers = function(markers) {
    311         var success = false;
    312         for (var i = 0; i < markers.length; i++) {
    313             var r = this._removeMarker(markers[i]);
    314             success = success || r; 
    315         }
    316  
    317         if (success) {
    318             this._clearLastClusters();
    319             this._createClusters();
    320         }
    321         return success;
    322     };
    323  
    324     /**
    325      * 从地图上彻底清除所有的标记
    326      * @return 无返回值
    327      */
    328     MarkerClusterer.prototype.clearMarkers = function() {
    329         this._clearLastClusters();
    330         this._removeMarkersFromMap();
    331         this._markers = [];
    332     };
    333  
    334     /**
    335      * 重新生成,比如改变了属性等
    336      * @return 无返回值
    337      */
    338     MarkerClusterer.prototype._redraw = function () {
    339         this._clearLastClusters();
    340         this._createClusters();
    341     };
    342  
    343     /**
    344      * 获取网格大小
    345      * @return {Number} 网格大小
    346      */
    347     MarkerClusterer.prototype.getGridSize = function() {
    348         return this._gridSize;
    349     };
    350  
    351     /**
    352      * 设置网格大小
    353      * @param {Number} size 网格大小
    354      * @return 无返回值
    355      */
    356     MarkerClusterer.prototype.setGridSize = function(size) {
    357         this._gridSize = size;
    358         this._redraw();
    359     };
    360  
    361     /**
    362      * 获取聚合的最大缩放级别。
    363      * @return {Number} 聚合的最大缩放级别。
    364      */
    365     MarkerClusterer.prototype.getMaxZoom = function() {
    366         return this._maxZoom;       
    367     };
    368  
    369     /**
    370      * 设置聚合的最大缩放级别
    371      * @param {Number} maxZoom 聚合的最大缩放级别
    372      * @return 无返回值
    373      */
    374     MarkerClusterer.prototype.setMaxZoom = function(maxZoom) {
    375         this._maxZoom = maxZoom;
    376         this._redraw();
    377     };
    378  
    379     /**
    380      * 获取聚合的样式风格集合
    381      * @return {Array<IconStyle>} 聚合的样式风格集合
    382      */
    383     MarkerClusterer.prototype.getStyles = function() {
    384         return this._styles;
    385     };
    386  
    387     /**
    388      * 设置聚合的样式风格集合
    389      * @param {Array<IconStyle>} styles 样式风格数组
    390      * @return 无返回值
    391      */
    392     MarkerClusterer.prototype.setStyles = function(styles) {
    393         this._styles = styles;
    394         this._redraw();
    395     };
    396  
    397     /**
    398      * 获取单个聚合的最小数量。
    399      * @return {Number} 单个聚合的最小数量。
    400      */
    401     MarkerClusterer.prototype.getMinClusterSize = function() {
    402         return this._minClusterSize;
    403     };
    404  
    405     /**
    406      * 设置单个聚合的最小数量。
    407      * @param {Number} size 单个聚合的最小数量。
    408      * @return 无返回值。
    409      */
    410     MarkerClusterer.prototype.setMinClusterSize = function(size) {
    411         this._minClusterSize = size;
    412         this._redraw();
    413     };
    414  
    415     /**
    416      * 获取单个聚合的落脚点是否是聚合内所有标记的平均中心。
    417      * @return {Boolean} true或false。
    418      */
    419     MarkerClusterer.prototype.isAverageCenter = function() {
    420         return this._isAverageCenter;
    421     };
    422  
    423     /**
    424      * 获取聚合的Map实例。
    425      * @return {Map} Map的示例。
    426      */
    427     MarkerClusterer.prototype.getMap = function() {
    428       return this._map;
    429     };
    430  
    431     /**
    432      * 获取所有的标记数组。
    433      * @return {Array<Marker>} 标记数组。
    434      */
    435     MarkerClusterer.prototype.getMarkers = function() {
    436         return this._markers;
    437     };
    438  
    439     /**
    440      * 获取聚合的总数量。
    441      * @return {Number} 聚合的总数量。
    442      */
    443     MarkerClusterer.prototype.getClustersCount = function() {
    444         var count = 0;
    445         for(var i = 0, cluster; cluster = this._clusters[i]; i++){
    446             cluster.isReal() && count++;     
    447         }
    448         return count;
    449     };
    450  
    451     /**
    452      * @ignore
    453      * Cluster
    454      * @class 表示一个聚合对象,该聚合,包含有N个标记,这N个标记组成的范围,并有予以显示在Map上的TextIconOverlay等。
    455      * @constructor
    456      * @param {MarkerClusterer} markerClusterer 一个标记聚合器示例。
    457      */
    458     function Cluster(markerClusterer){
    459         this._markerClusterer = markerClusterer;
    460         this._map = markerClusterer.getMap();
    461         this._minClusterSize = markerClusterer.getMinClusterSize();
    462         this._isAverageCenter = markerClusterer.isAverageCenter();
    463         this._center = null;//落脚位置
    464         this._markers = [];//这个Cluster中所包含的markers
    465         this._gridBounds = null;//以中心点为准,向四边扩大gridSize个像素的范围,也即网格范围
    466         this._isReal = false; //真的是个聚合
    467      
    468         this._clusterMarker = new BMapLib.TextIconOverlay(this._center, this._markers.length, {"styles":this._markerClusterer.getStyles()});
    469         //this._map.addOverlay(this._clusterMarker);
    470     }
    471     
    472     /**
    473      * 向该聚合添加一个标记。
    474      * @param {Marker} marker 要添加的标记。
    475      * @return 无返回值。
    476      */
    477     Cluster.prototype.addMarker = function(marker){
    478         if(this.isMarkerInCluster(marker)){
    479             return false;
    480         }//也可用marker.isInCluster判断,外面判断OK,这里基本不会命中
    481      
    482         if (!this._center){
    483             this._center = marker.getPosition();
    484             this.updateGridBounds();//
    485         } else {
    486             if(this._isAverageCenter){
    487                 var l = this._markers.length + 1;
    488                 var lat = (this._center.lat * (l - 1) + marker.getPosition().lat) / l;
    489                 var lng = (this._center.lng * (l - 1) + marker.getPosition().lng) / l;
    490                 this._center = new BMap.Point(lng, lat);
    491                 this.updateGridBounds();
    492             }//计算新的Center
    493         }
    494      
    495         marker.isInCluster = true;
    496         this._markers.push(marker);
    497     };
    498     
    499     /**
    500      * 进行dom操作
    501      * @return 无返回值
    502      */
    503     Cluster.prototype.render = function(){
    504         var len = this._markers.length;
    505          
    506         if (len < this._minClusterSize) {
    507             for (var i = 0; i < len; i++) {
    508                 this._map.addOverlay(this._markers[i]);
    509             }
    510         } else {
    511             this._map.addOverlay(this._clusterMarker);
    512             this._isReal = true;
    513             this.updateClusterMarker();
    514         }
    515     }
    516 
    517     /**
    518      * 判断一个标记是否在该聚合中。
    519      * @param {Marker} marker 要判断的标记。
    520      * @return {Boolean} true或false。
    521      */
    522     Cluster.prototype.isMarkerInCluster= function(marker){
    523         if (this._markers.indexOf) {
    524             return this._markers.indexOf(marker) != -1;
    525         } else {
    526             for (var i = 0, m; m = this._markers[i]; i++) {
    527                 if (m === marker) {
    528                     return true;
    529                 }
    530             }
    531         }
    532         return false;
    533     };
    534  
    535     /**
    536      * 判断一个标记是否在该聚合网格范围中。
    537      * @param {Marker} marker 要判断的标记。
    538      * @return {Boolean} true或false。
    539      */
    540     Cluster.prototype.isMarkerInClusterBounds = function(marker) {
    541         return this._gridBounds.containsPoint(marker.getPosition());
    542     };
    543      
    544     Cluster.prototype.isReal = function(marker) {
    545         return this._isReal;
    546     };
    547  
    548     /**
    549      * 更新该聚合的网格范围。
    550      * @return 无返回值。
    551      */
    552     Cluster.prototype.updateGridBounds = function() {
    553         var bounds = new BMap.Bounds(this._center, this._center);
    554         this._gridBounds = getExtendedBounds(this._map, bounds, this._markerClusterer.getGridSize());
    555     };
    556  
    557     /**
    558      * 更新该聚合的显示样式,也即TextIconOverlay。
    559      * @return 无返回值。
    560      */
    561     Cluster.prototype.updateClusterMarker = function () {
    562         if (this._map.getZoom() > this._markerClusterer.getMaxZoom()) {
    563             this._clusterMarker && this._map.removeOverlay(this._clusterMarker);
    564             for (var i = 0, marker; marker = this._markers[i]; i++) {
    565                 this._map.addOverlay(marker);
    566             }
    567             return;
    568         }
    569  
    570         if (this._markers.length < this._minClusterSize) {
    571             this._clusterMarker.hide();
    572             return;
    573         }
    574  
    575         this._clusterMarker.setPosition(this._center);
    576          
    577         this._clusterMarker.setText(this._markers.length);
    578  
    579         var thatMap = this._map;
    580         var thatBounds = this.getBounds();
    581         this._clusterMarker.addEventListener("click", function(event){
    582             thatMap.setViewport(thatBounds);
    583         });
    584  
    585     };
    586  
    587     /**
    588      * 删除该聚合。
    589      * @return 无返回值。
    590      */
    591     Cluster.prototype.remove = function(){
    592         for (var i = 0, m; m = this._markers[i]; i++) {
    593             tmplabel = this._markers[i].getLabel(); 
    594             this._markers[i].getMap() && this._map.removeOverlay(this._markers[i])
    595             this._markers[i].setLabel(tmplabel)
    596         }//清除散的标记点
    597         this._map.removeOverlay(this._clusterMarker);
    598         this._markers.length = 0;
    599         delete this._markers;
    600     }
    601  
    602     /**
    603      * 获取该聚合所包含的所有标记的最小外接矩形的范围。
    604      * @return {BMap.Bounds} 计算出的范围。
    605      */
    606     Cluster.prototype.getBounds = function() {
    607         var bounds = new BMap.Bounds(this._center,this._center);
    608         for (var i = 0, marker; marker = this._markers[i]; i++) {
    609             bounds.extend(marker.getPosition());
    610         }
    611         return bounds;
    612     };
    613  
    614     /**
    615      * 获取该聚合的落脚点。
    616      * @return {BMap.Point} 该聚合的落脚点。
    617      */
    618     Cluster.prototype.getCenter = function() {
    619         return this._center;
    620     };
    621  
    622 })();
  • 相关阅读:
    JZOJ 4298. 【NOIP2015模拟11.2晚】我的天
    JZOJ 4314. 【NOIP2015模拟11.4】老司机
    JZOJ 4313. 【NOIP2015模拟11.4】电话线铺设
    SP2416 DSUBSEQ
    JZOJ 2020.08.03【NOIP提高组】模拟 &&【NOIP2015模拟11.5】
    Android一些网站介绍
    http://www.androiddevtools.cn/
    Eclipse的安装使用
    JDK环境配置
    关于appcompat_v7的说明
  • 原文地址:https://www.cnblogs.com/anyuan9/p/6232137.html
Copyright © 2011-2022 走看看