【问题标题】:Google maps v3: clustering with custom markers谷歌地图 v3:使用自定义标记进行聚类
【发布时间】:2019-12-13 02:18:27
【问题描述】:

我正在尝试使用MarkerClusterer 对地图上的标记进行聚类。 问题是我没有使用默认标记 (google.maps.Marker),而是使用了一个自定义类,它阻碍了 google.maps.OverlayView。 不幸的是,该库似乎是在使用基本标记的情况下开发的,实际上我得到了错误,因为我的类没有实现 google.maps.Marker 中定义的方法。 是否可以通过保留我的自定义标记来使用 MarkerClusterer

编辑:这比我预期的要容易得多,我通过在我的自定义类中实现 2 个方法来解决:

setVisible()getPosition()

为了帮助别人以下是我的完整接口(没有完整实现):

BFPushpin = function(config) 
{
    this.setMap(config.map);
    this.set("position", config.position);
    // other settings...
};

// my class extends google.maps.OverlayView
BFPushpin.prototype = new google.maps.OverlayView();

BFPushpin.prototype.getBounds = function() 
{
    return new google.maps.LatLngBounds(this.position, this.position); 
};

BFPushpin.prototype.getPoint = function() 
{
    var bounds = this.getBounds();
    var projection = this.getProjection();
    var sw = projection.fromLatLngToDivPixel(bounds.getSouthWest());  
        var ne = projection.fromLatLngToDivPixel(bounds.getNorthEast()); 

    return new google.maps.Point(sw.x, ne.y);
};

BFPushpin.prototype.getSuperContainer = function()
{
    var panes = this.getPanes();
    return jQuery(panes ? panes.overlayImage : "");
};

BFPushpin.prototype.getContainer = function()
{
    // return inner container
};

BFPushpin.prototype._generatePopupContent = function()
{
    // return markup for the popupwindow
};

BFPushpin.prototype._addListeners = function()
{
    // add handlers for the pushpin
};

BFPushpin.prototype.onAdd = function()
{
    // customize content here
};

BFPushpin.prototype.onRemove = function()
{
    // remove pin container here
};

BFPushpin.prototype.draw = function()
{
    // set display style here
};

BFPushpin.prototype.setVisible = function(visible)
{
    // set display block or hidden
};

BFPushpin.prototype.getPosition = function()
{
    return this.position;
};

【问题讨论】:

  • 我对你的解决方案有点困惑。我正在尝试做类似的事情,我有一个从 OverlayView “继承”的自定义叠加层,并且我通过简单地在绘图函数中枚举我自己制作的对象列表来在其中绘制标记作为标记。那么,您如何协调此处“标记”的使用以使集群发挥作用?
  • 您是否为每个标记渲染一个完整的叠加层?

标签: javascript google-maps google-maps-api-3


【解决方案1】:

或者只定义 MarkerClusterer 期望在标记上的函数。 setMap 和 getPosition() 以及其他一些。

【讨论】:

  • 这很危险,因为您永远不知道未来版本/其他库和方法等可以使用哪些方法。
  • 并非如此,因为您只是在实现 API 中相当稳定的 Marker 接口,您应该没有问题。 MarkerClusterer 只关心获取项目的位置并能够设置其可见性/地图。
【解决方案2】:

您可能应该以这样一种方式定义您的新标记类,即它也继承自google.maps.Marker(即它实现了它的接口)。 MarkerClusterer 使用这个接口是合乎逻辑的——它必须假设标记是标记才能使用它们:-)

【讨论】:

    【解决方案3】:

    希望这也能帮助那些试图让这个解决方案发挥作用的人。感谢@daveoncode 的示例。我能够对其进行修改以使其适合我:

    renderMap() {
        const mapProperties = {
            center: new google.maps.LatLng(34.0234, -84.6155),
            zoom: 10,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        this.map = new google.maps.Map(this.mapElement.nativeElement, mapProperties);
    
        let markers = [];
        for (let i=0; i<this._sitesList.length; i++) {
            let bounds = new google.maps.LatLngBounds(
                new google.maps.LatLng(this._sitesList[i].lat, this._sitesList[i].lon)
            );
            let position = new google.maps.LatLng(this._sitesList[i].lat, this._sitesList[i].lon);
            let html = this.makeHtmlForSitePanel(i, this._sitesList[i]); // I have a function to return html for my OverlayView panels here.
            markers.push( this.generateSitePanel(bounds, html, this.map, position) );
        }
    
        var markerCluster = new MarkerClusterer(this.map, markers, {
            imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
        });
    
    }
    
    generateSitePanel(bounds, html, map, position) {
    
        SitePanel.prototype = new google.maps.OverlayView();
    
        function SitePanel (bounds, html, map, position) {
            this.bounds_ = bounds;
            this.set('position', position);
            this.html_ = html;
            this.map_ = map;
            this.div_ = null;
            this.setMap(map);
        }
    
        SitePanel.prototype.getBounds = function() {
            return new google.maps.LatLngBounds(this.position, this.position); 
        };
    
        SitePanel.prototype.getPoint = function() {
            var bounds = this.getBounds();
            var projection = this.getProjection();
            var sw = projection.fromLatLngToDivPixel(bounds.getSouthWest());  
                var ne = projection.fromLatLngToDivPixel(bounds.getNorthEast()); 
    
            return new google.maps.Point(sw.x, ne.y);
        };
    
        SitePanel.prototype.getSuperContainer = function(){
            var panes = this.getPanes();
            return $(panes ? panes.overlayImage : '');
        };
    
        SitePanel.prototype.getContainer = function()
        {
            // return inner container
            // I don't have anything for this one
        };
    
        SitePanel.prototype.getPosition = function() {
            return this.position;
        };
    
        SitePanel.prototype.onAdd = function() {
            var div = document.createElement('div');
            div.className = 'tooltip-container-';
            div.innerHTML = this.html_;
            div.style.position = 'absolute';
            this.div_ = div;
            var panes = this.getPanes();
            panes.overlayImage.appendChild(div);
        };
    
        SitePanel.prototype.draw = function() {
            var overlayProjection = this.getProjection();
            var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
            var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
    
            var div = this.div_;
            div.style.left = sw.x + 'px';
            div.style.top = ne.y + 20 + 'px';
        };
    
        SitePanel.prototype.onRemove = function() {
            this.div_.parentNode.removeChild(this.div_);
            this.div_ = null;
        };
    
        return new SitePanel(bounds, html, map, position);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-27
      • 2012-12-17
      • 2013-01-08
      • 2014-04-05
      • 1970-01-01
      • 2013-08-21
      相关资源
      最近更新 更多