美文网首页vueFront-End
百度地图聚合功能自定义聚合文字

百度地图聚合功能自定义聚合文字

作者: sphenginx | 来源:发表于2019-04-08 16:09 被阅读1次

    缘起

    近日, 产品提了个新的功能,需要用到地图点聚合功能。 了解了 leaflet 框架,是基于地图瓦片实现的,但是我司要求使用百度地图实现该功能, 发现 leaflet 对天地图、高德比较友好。 对百度地图支持度并不好。

    但是,研究百度聚合demo发现,百度聚合只支持自定义样式,并不支持自定义文字。

    最终,我发现百度地图聚合功能是第三方实现的,似乎可以自己下载下来, 重写聚合设置聚合文字相关功能。 简单记录如下,希望对有需要的童鞋有所帮助吧。

    分析

    研究百度地图聚合源码发现,如果打算自定义文字需要修改两处:
    一、修改 BMapLib.MarkerClusterer.js 插件中 Cluster.prototype.updateClusterMarker 方法,实现过程如下:

    /**
     * 更新该聚合的显示样式,也即TextIconOverlay。
     * @return 无返回值。
     */
    Cluster.prototype.updateClusterMarker = function () {
        if (this._map.getZoom() > this._markerClusterer.getMaxZoom()) {
            this._clusterMarker && this._map.removeOverlay(this._clusterMarker);
            for (var i = 0, marker; marker = this._markers[i]; i++) {
                this._map.addOverlay(marker);
            }
            return;
        }
    
        if (this._markers.length < this._minClusterSize) {
            this._clusterMarker.hide();
            return;
        }
    
        this._clusterMarker.setPosition(this._center);
        
        this._clusterMarker.setText(this._markers.length);
    
        var thatMap = this._map;
        var thatBounds = this.getBounds();
        this._clusterMarker.addEventListener("click", function(event){
            thatMap.setViewport(thatBounds);
        });
    };
    

    方法中: this._clusterMarker.setText(this._markers.length); 表示, 聚合点的内容是 当前Cluster 类 _markers 属性 的 长度;

    二、修改 TextIconOverlay.js 中的 构造方法 和 样式方法

        查看 `TextIconOverlay.js` 的源码发现, text 只支持 数字类型的值,而且和 styles 属性绑定,需要修改constructor 方法, 和 设置属性的方法。
    

    性空

    如上,知道了聚合的文字是 Cluster.prototype.updateClusterMarker 方法 , 那么我们需要进行以下步骤:

    1、把百度地图的聚合库存到自己的项目;
    2、不要使用百度地图默认的maker,改用自己定义的复杂覆盖物;
    3、重写 updateClusterMarker 方法;
    4、重写 TextIconOverlay.js 的 setText() 方法;
    5、引用类聚合文件,由百度的官方网站,改为自己的项目路径;
    6、大功告成。

    • 第一步,自己操作即可;
    • 第二步,自定义自己的复杂覆盖物,传入自定义 text
    //复杂的自定义覆盖物
    function ComplexCustomOverlay(point, text, mouseoverText){
      this._point = point;
      this._text  =  text;
    };
    //复杂覆盖物实例,继承自百度 overlay
    ComplexCustomOverlay.prototype = new BMap.Overlay();
    //重写 initialize 方法
    ComplexCustomOverlay.prototype.initialize = function(map){
        this._map = map;
        let div = document.createElement("div");
        let span = this._span = document.createElement("span");
        span.appendChild(document.createTextNode(this._text));
        div.appendChild(span);
        this._map.getPanes().labelPane.appendChild(div);
        this._div = div;
        this._cwidth = this._div.clientWidth;
        this._cheight = this._div.clientHeight;
        return div;
    }
    //重写 draw 方法
    ComplexCustomOverlay.prototype.draw = function(){
        let pixel = this._map.pointToOverlayPixel(this._point);
        this._div.style.left = pixel.x - this._cwidth/2 + "px";
        this._div.style.top  = pixel.y - this._cheight  + "px";
    }
    

    通过查看百度地图聚合源码,发现 Cluster 类调用了 marke r的 getPositiongetMap 方法,我们需要自定义这俩方法如下:

    //在调用聚合方法时会将会调用标注的getPosition和getMap方法
    ComplexCustomOverlay.prototype.getPosition = function(){
        return this._point;
    };
    ComplexCustomOverlay.prototype.getMap = function(){
        return this._map;   
    };
    // 获取自定义text,不建议通过 marker._text 获取
    ComplexCustomOverlay.prototype.getText = function(){
        return this._text;  
    };
    
    • 第三步,重写 Cluster.prototype.updateClusterMarker 方法:
    /**
     * 更新该聚合的显示样式,也即TextIconOverlay。
     * @return 无返回值。
     */
    Cluster.prototype.updateClusterMarker = function () {
        if (this._map.getZoom() > this._markerClusterer.getMaxZoom()) {
            this._clusterMarker && this._map.removeOverlay(this._clusterMarker);
            for (var i = 0, marker; marker = this._markers[i]; i++) {
                this._map.addOverlay(marker);
            }
            return;
        }
    
        if (this._markers.length < this._minClusterSize) {
            this._clusterMarker.hide();
            return;
        }
    
        this._clusterMarker.setPosition(this._center);
        
        // 这里重写 
        // this._clusterMarker.setText(this._markers.length);
        // 自定义文字
        var _text = "";
        for (var i = 0, marker; marker = this._markers[i]; i++) {
            //自定义文字,这里简单连接
            _text += marker.getText() + "<br>"; // setText 方法是 TextOverlay 的 innerHtml 赋值, 这里支持 html 标记
        }
        this._clusterMarker.setText(_text);
    
        var thatMap = this._map;
        var thatBounds = this.getBounds();
        this._clusterMarker.addEventListener("click", function(event){
            thatMap.setViewport(thatBounds);
        });
    };
    
    • 第四步各位看官可以自己实现

    • 第五步、第六步略。

    最终,我们实现了自定义 百度地图点聚合文字 信息。

    附Github: https://github.com/sphenginx/vue-slider

    注: 自定义了 SVGIconOverlay 自定义覆盖物, 基于SVG的,可以自定义文字 和 填充颜色 等, 欢迎使用

    附:

    类 BMapLib.MarkerClusterer

    相关文章

      网友评论

        本文标题:百度地图聚合功能自定义聚合文字

        本文链接:https://www.haomeiwen.com/subject/gzfpiqtx.html