Карты Google: отображать маркер над markerclusterer

У меня есть набор маркеров, которые сгруппированы на моей карте. Другой набор маркеров отображается индивидуально, и мне нужно, чтобы они отображались над кластерами. Я попытался установить zIndex в объекте параметров кластера ниже, чем у 2-го набора маркеров, но безрезультатно. Любая идея, как это сделать?


person cv87    schedule 20.04.2012    source источник
comment
Похожие вопросы: stackoverflow.com/questions/9330802/zindex-on-clusters, stackoverflow.com/questions/6894548/   -  person Tomas    schedule 09.03.2014


Ответы (4)


Насколько я знаю, этого делать нельзя. Кластеры находятся на панели выше, чем изображение маркера.

https://developers.google.com/maps/documentation/javascript/reference#MapPanes

person Rick    schedule 20.04.2012
comment
Это можно сделать с помощью трюка @rkallensee - person Fanky; 24.06.2021

Это можно сделать, но это довольно ухабистый путь, пока вы не доберетесь туда... Как говорит Рик, проблема в том, что MarkerClusterer добавляет собственный OverlayView со своими значками кластера на более высокую панель, как обычные маркеры. Единственный способ добавить маркер над кластерами — победить кластеризатора его собственным оружием и добавить собственный OverlayView и добавить разметку значка маркера на еще более высокую панель (читайте о панелях здесь). Мне это не очень нравится, но это единственный способ, который я нашел.

Для этого необходимо создать пользовательское наложение, реализующее google.maps.OverlayView (reference), хороший пример можно найти здесь (с пояснениями, я использовал оттуда немного кода).

Вот грубый прототип CustomOverlay:

// build custom overlay class which implements google.maps.OverlayView
function CustomOverlay(map, latlon, icon, title) {
    this.latlon_ = latlon;
    this.icon_ = icon;
    this.title_ = title;
    this.markerLayer = jQuery('<div />').addClass('overlay');
    this.setMap(map);
};
CustomOverlay.prototype = new google.maps.OverlayView;
CustomOverlay.prototype.onAdd = function() {
    var $pane = jQuery(this.getPanes().floatPane); // Pane 6, one higher than the marker clusterer
    $pane.append(this.markerLayer);
};
CustomOverlay.prototype.onRemove = function(){
    this.markerLayer.remove();
};
CustomOverlay.prototype.draw = function() {
    var projection = this.getProjection();
    var fragment = document.createDocumentFragment();

    this.markerLayer.empty(); // Empty any previous rendered markers

    var location = projection.fromLatLngToDivPixel(this.latlon_);
    var $point = jQuery('<div class="map-point" title="'+this.title_+'" style="'
                            +'width:32px; height:32px; '
                            +'left:'+location.x+'px; top:'+location.y+'px; '
                            +'position:absolute; cursor:pointer; '
                        +'">'
                        +'<img src="'+this.icon_+'" style="position: absolute; top: -16px; left: -16px" />'
                    +'</div>');

    fragment.appendChild($point.get(0));
    this.markerLayer.append(fragment);
};

Это наложение получает карту, объект LatLng и URL-адрес значка. Хорошо то, что вы можете написать свой собственный HTML для слоя, плохо то, что вы должны самостоятельно обрабатывать все, что API Карт делает за вас (например, обработку привязки изображения маркера). Пример хорошо работает только с изображениями размером 32x32 пикселя, где якорь находится в середине изображения, поэтому он все еще довольно грубый.

Чтобы использовать CustomOverlay, просто создайте его следующим образом:

// your map center / marker LatLng
var myLatlng = new google.maps.LatLng(24.247471, 89.920990);

// instantiate map
var map = new google.maps.Map(
    document.getElementById("map-canvas"),
    {zoom: 4, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP}
);  

// create the clusterer, but of course with markers
//var markerClusterer = new MarkerClusterer(map, []);

// add custom overlay to map
var customCustomOverlay = new CustomOverlay(map, myLatlng, 'http://www.foo.bar/icon.png');

Я надеюсь, что это работает для вас.

person rkallensee    schedule 05.10.2012
comment
Только я бы поменял: style="'+'width:1px; height:1px;' и в img style="position: absolute; top: -THE_HEIGHT_OF_IMAGE_HEREpx; left: -HALF_OF_THE_WIDTH_OF_IMAGE_HEREpx" чтобы рисунок (как и должно быть с классическим булавочным маркером) появился прямо поверх места - person Fanky; 24.06.2021

У меня была такая же проблема, но я не хотел обрабатывать новый оверлей.

Без необходимости создавать конкретный оверлей вы можете просто переключить z-индексы родительских контейнеров оверлея.

Этого можно добиться с помощью следующей функции:

_changeOverlayOrder = function(map) {
    var panes = map.getPanes();
    var markerOverlayDiv = panes.overlayImage.parentNode;
    var clusterOverlayDiv = panes.overlayMouseTarget.parentNode;
    // Make the clusters clickable.
    if(!markerOverlayDiv.style.pointerEvents) {
        markerOverlayDiv.style.cssText += ";pointer-events: none;";
    }
    // Switch z-indexes
    if(markerOverlayDiv.style.zIndex < clusterOverlayDiv.style.zIndex) {
        var tmp = markerOverlayDiv.style.zIndex;
        markerOverlayDiv.style.zIndex = clusterOverlayDiv.style.zIndex;
        clusterOverlayDiv.style.zIndex = tmp;
    }
};

Надеюсь, поможет.

person mouwah    schedule 29.01.2013
comment
Что это в this.getPanes()? - person marcovtwout; 11.06.2013
comment
Ответ @mouwah почти правильный, но для объекта карты нет метода getPanes(). Вы должны определить свой пользовательский класс OverlayView() для использования метода getPanes() и изменить zIndex панели overlayMouseTarget. - person Maximus S; 14.04.2014
comment
Этот код до сих пор работал идеально, но сейчас Google что-то изменил, и он внезапно перестал работать! - person Tomas; 08.07.2014
comment
Я назначил награду за этот вопрос, поэтому, если вы адаптируете свой ответ к новой ситуации, вы сможете этого добиться. - person Tomas; 11.07.2014
comment
Есть новости по этому поводу? - person dan_boy; 15.07.2021

Вы можете переопределить его с помощью CSS.

CSS

.gm-style-pbc + div > div > div:first-child{ z-index: 108 !important; }

СКСС

.gm-style-pbc{
   + div{
     > div{
       >div{
         &:first-child{
            z-index: 108 !important;
         }
       }
     }
   }
}
person Arif Cakiroglu    schedule 12.04.2020