Google Maps: Render marker above markerclusterer
It can be done, but it's a pretty bumpy way until you get there... As Rick says, the problem is that the MarkerClusterer adds an own OverlayView with its cluster icons on a higher pane as the regular markers. The only way to add a marker above the clusters is to beat the clusterer with his own weapons and add an own OverlayView and add the marker icon markup to an even higher pane (read about panes here). I don't really like it - but it's the only way I found.
To do this you have to create a custom overlay implementing google.maps.OverlayView (reference), a good example can be found here (with explanations, I used a bit of code from it).
Here is a rough CustomOverlay prototype:
// 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);
};
This overlay gets the map, a LatLng object and the URL of an icon. The good thing is that you can write your own HTML to the layer, the bad thing is that you have to handle all the stuff the Maps API does for you (like marker image anchor handling) by your own. The example only works good with 32x32px images where the anchor is in the middle of the image, so it's still pretty rough.
To use the CustomOverlay, just instantiate it like this:
// 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');
I hope this works for you.
I had the same issue but didn't want to handle a new overlay.
Without having to create a specific Overlay, you can just switch the overlay's parent containers z-indexes.
This can be achieved by using the following function :
_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;
}
};
Hope it helps.
As far as I know this can't be done. The clusters reside in higher pane than the marker image.
https://developers.google.com/maps/documentation/javascript/reference#MapPanes