Google maps v3: кластеризация с пользовательскими маркерами

Я пытаюсь использовать MarkerClusterer для кластеризации маркеров на моей карте. Проблема в том, что я использую не маркеры по умолчанию (google.maps.Marker), а вместо этого пользовательский класс, который гинерит из google.maps.OverlayView. К сожалению, похоже, что библиотека была разработана в расчете на использование основных маркеров, на самом деле я получаю ошибки, потому что мой класс не реализует методы, определенные в google.maps.Marker. Возможно ли использовать MarkerClusterer, сохранив мои пользовательские маркеры?

EDIT: это оказалось намного проще, чем я ожидал, я решил проблему путем реализации 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;
};

5
задан daveoncode 29 November 2011 в 11:58
поделиться

1 ответ

Надо надеяться, это также поможет людям, пытающимся получить это решение работать. Спасибо @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);
}
0
ответ дан 15 December 2019 в 05:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: