百度地图自定义聚合点方法拓展

效果图

在这里插入图片描述

介绍

这是一个百度地图自定义聚合样式和图层控制拓展方法的API。
在百度官方版本的基础上拓展了自定义方法,具体见下方说明。

百度地图聚合原理

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

实现源码

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

拓展方法说明

MarkerClusterer.js

  • 增加属性
    type {Number} 自定义类型,用于方便控制隐藏和显示
    name {String} 自定资源名称,用于方便控制隐藏和显示
    markerControl {Boolean} 是否需要控制maker显示/隐藏,需要控制maker会默认被隐藏,否则直接显示

  • 拓展方法
    addLabel() // 对于单个点 添加自定义label
    addCustomizeMarker() // 对于单个点 添加自定义marker

TextIconOverlay.js

  • 增加属性
    type {Number} type 表示资源类型

  • 修改属性
    text 由{String}改为{Json Object} // 表示该覆盖物显示的文字信息

  • 拓展方法
    _updateClassName() // 更新覆盖物的类名

使用说明

  • 引入资源
<script type="text/javascript" src="//api.map.baidu.com/api?v=3.0&ak=您的密钥"></script>
<script type="text/javascript" src="TextIconOverlay.js"></script>
<script type="text/javascript" src="MarkerClusterer.js"></script>
  • Html部分
<!-- 地图容器 -->
<div id='map'></div>
  • Js部分 (代码基于Vue)
// 定义地图
var map;

// 初始化百度地图
baiduMapInit: function() {
    var self = this;
    // 百度地图API功能
    map = new BMap.Map(baidumapOptions.mapDiv,{
        enableMapClick: false, // 禁用景点,场所等点击事件
        minZoom: baidumapOptions.zoom
    });    // 创建Map实例
    map.centerAndZoom(new BMap.Point(baidumapOptions.center[1],baidumapOptions.center[0]), baidumapOptions.zoom);  // 初始化地图,设置中心点坐标和地图级别
    map.setMapStyle({ style: 'midnight' });
    map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
},
// 添加聚合点
createClustersMarker: function(markers,type,name){
    var markerClusterer = new BMapLib.MarkerClusterer(map, {
        markers: markers,
        minClusterSize: 3, //最小的聚合数量,小于该数量的不能成为一个聚合,默认为2
        type: type, // 资源类型
        name: name, // 资源名称
        markerControl: false, // 是否控制marker
        styles: [{
            textColor: '#fff',
            backgroundColor: '#0080ff',
            size: new BMap.Size(26, 26)
        }]
    });
},
// 获取警力(警员/警车/移动警务)
getPolice: function(){
    var self = this;
    
    // ... 省略无关代码

    var policeMan = res.data.policeMan;

    // 警力 [31|警员] - 地图点聚合需要
    if(policeMan.length){
        var markers = [];
        var type = '31';
        var name = 'jy';

        policeMan.map(function(item){
            if(item.jd && item.wd){
                var point = new BMap.Point(item.jd, item.wd);
                var marker = new BMap.Marker(point);
                
                // marker携带自定义参数
                marker.customData = {
                    "type": type,
                    "name": name,
                    "jd": item.jd,
                    "wd": item.wd,
                    "bmmc": item.bmmc,
                    "xm": item.xm,
                }

                marker.addEventListener('click', function(e){
                    // 绑定点击事件
                });

                markers.push(marker);
            } else{
                console.log('当前警员没有经纬度:', item);
            }
        });

        // 给地图添加聚合点
        self.createClustersMarker(markers,type,name);
    }

    // ... 省略无关代码

},
// 地图缩放、拖拽之后重新设置地图图层状态
chechMapLayerStatus(){
    // 此处为控制marker显示/隐藏的方法,具体可参考以下示例,
    if(item.type == 'xxbz'){ // 信息标识
        if(item.checked){
            $('.map .facility-xxbz-point').show();
            $('.map .map-xxbz-cluster').show();
        } else{
            $('.map .facility-xxbz-point').hide();
            $('.map .map-xxbz-cluster').hide();
        }
    }

    // 说明,
    // xxbz 为传递到js中的name属性
},


解决:添加超过2w+个点地图卡

在这里插入图片描述

MarkerClusterer.js

  • addMarker 删除来有打点方法
  • 新增 render 方法替换原有添加聚合点的方法
/**
* 向该聚合添加一个标记。
 * @param {Marker} marker 要添加的标记。
 * @return 无返回值。
 */
Cluster.prototype.addMarker = function(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); // 官方原版添加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;
    */
};

/**
* 进行dom操作
  * @return 无返回值
  */
 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]);
            this.addCustomizeMarker(this._markers[i]); // obear 添加自定义marker
        }
    } else {
        this._map.addOverlay(this._clusterMarker);
        this._isReal = true;
        this.updateClusterMarker();
    }
}


源码下载

下载地址:https://gitee.com/iobear/baiduMapClustersMarker

发布了147 篇原创文章 · 获赞 49 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/bigbear00007/article/details/103619991