谷歌地图:在markerclusterer上方渲染标记

Posted

技术标签:

【中文标题】谷歌地图:在markerclusterer上方渲染标记【英文标题】:Google Maps: Render marker above markerclusterer 【发布时间】:2012-05-01 21:34:28 【问题描述】:

我有一组标记聚集在我的地图上。 另一组标记单独显示,我碰巧需要将这些标记显示在群集上方。 我尝试在集群选项对象中设置 zIndex,低于第二组标记,但无济于事。 知道该怎么做吗?

【问题讨论】:

类似问题:***.com/questions/9330802/zindex-on-clusters, ***.com/questions/6894548/… 【参考方案1】:

它可以完成,但在你到达那里之前这是一个相当颠簸的方式......正如 Rick 所说,问题在于 MarkerClusterer 添加了一个自己的 OverlayView,其群集图标位于较高的窗格中作为常规标记。在集群上方添加标记的唯一方法是用他自己的武器击败集群并添加自己的 OverlayView 并将标记图标标记添加到更高的窗格(阅读有关窗格here)。我不太喜欢它 - 但这是我找到的唯一方法。

为此,您必须创建一个实现 google.maps.OverlayView (reference) 的自定义叠加层,可以在 here 找到一个很好的示例(带有解释,我使用了其中的一些代码)。

这是一个粗略的 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 写入图层,坏处是您必须自己处理 Maps API 为您所做的所有事情(例如标记图像锚点处理)。该示例仅适用于锚点位于图像中间的 32x32px 图像,因此仍然很粗糙。

要使用 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');

我希望这对你有用。

【讨论】:

我只会更改:style="'+'width:1px; height:1px;' 和 img style="position: absolute; top: -THE_HEIGHT_OF_IMAGE_HEREpx; left: -HALF_OF_THE_WIDTH_OF_IMAGE_HEREpx",因此绘图(应该使用经典的别针标记)出现在该位置的正上方【参考方案2】:

我遇到了同样的问题,但不想处理新的叠加层。

无需创建特定的叠加层,您只需切换叠加层的父容器 z-indexes。

这可以通过使用以下函数来实现:

_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;
    
;

希望对你有帮助。

【讨论】:

this.getPanes() 中的“this”是什么? @mouwah 的回答几乎是正确的,但地图对象没有 getPanes() 方法。您必须定义您的自定义 OverlayView() 类以使用 getPanes() 方法并更改 zIndexoverlayMouseTarget 窗格。 这段代码一直到现在都可以正常工作,但是现在google改变了一些东西,它突然停止工作了! 我已经对这个问题给予了赏金,所以如果你根据新情况调整你的答案,你就可以实现它【参考方案3】:

据我所知,这是不可能的。集群位于比标记图像更高的窗格中。

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

【讨论】:

【参考方案4】:

你可以用 CSS 覆盖它。

CSS

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

SCSS

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

【讨论】:

以上是关于谷歌地图:在markerclusterer上方渲染标记的主要内容,如果未能解决你的问题,请参考以下文章

使用markerclusterer v3获取谷歌地图范围内的标记列表

将自定义标记放在 markerclusterer

单击缩放上的markerClusterer

Google Maps api Detect使用markerclusterer点击标记[重复]

百度地图api 的MarkerClusterer 的使用

有没有办法在谷歌地图的叠加层上方添加标记反应?