I have a google map using api version 3. I want to create markers with a custom icon and numbered labels. I've been trying to use what seems to be the most accepted method for this, the "labels.js" solution that I've provided below. However, no matter what I try, all the numbered overlays overlap all of the markers (despite me setting the marker and the label with the same zIndex). See the screenshot provided to see what I'm talking about. If you take a look at markers 14 and 15 in the screen, you'll see that the 15 label overlaps the 14 marker, but it shouldn't, it should be underneath the 14 marker.
http://i.imgur.com/QoYqcHJ.jpg
Many discussions about properly overlapping with custom overlays revolve around the line of code:
var pane = this.getPanes().overlayImage;
However, I have this in place. I'm setting each label overlay and marker pair to the same zIndex, and the properly overlapping markers proves that this zIndex increment is working. I've provided all of my code below, and have run into a brick wall. I've tried everything possible with no luck. Assume all variables have been properly declared.
label.js:
/* START label.js */
// Define the overlay, derived from google.maps.OverlayView
function Label(opt_options) {
// Initialization
this.setValues(opt_options);
// Here go the label styles
var span = this.span_ = document.createElement('span');
span.style.cssText = 'position: relative;' +
'white-space: nowrap;color:#666666;' +
'font-family: Arial; font-weight: bold;' +
'font-size: 11px;';
var div = this.div_ = document.createElement('div');
div.appendChild(span);
div.style.cssText = 'position: absolute; display: none;';
};
Label.prototype = new google.maps.OverlayView;
Label.prototype.onAdd = function () {
var pane = this.getPanes().overlayImage;
pane.appendChild(this.div_);
// Ensures the label is redrawn if the text or position is changed.
var me = this;
this.listeners_ = [
google.maps.event.addListener(this, 'position_changed',
function () { me.draw(); }),
google.maps.event.addListener(this, 'text_changed',
function () { me.draw(); }),
google.maps.event.addListener(this, 'zindex_changed',
function () { me.draw(); })
];
};
// Implement onRemove
Label.prototype.onRemove = function () {
this.div_.parentNode.removeChild(this.div_);
// Label is removed from the map, stop updating its position/text.
for (var i = 0, I = this.listeners_.length; i < I; ++i) {
google.maps.event.removeListener(this.listeners_[i]);
}
};
// Implement draw
Label.prototype.draw = function () {
var projection = this.getProjection();
var div = this.div_;
// Some custom code to properly get the offset for the numbered label for each marker
var labelOffset;
if (parseInt(this.get('text').toString()) < 10) labelOffset = new google.maps.Point(6, -35);
else labelOffset = new google.maps.Point(9, -35);
var point1 = this.map.getProjection().fromLatLngToPoint(
(this.get('position') instanceof google.maps.LatLng) ? this.get('position') : this.map.getCenter()
);
var point2 = new google.maps.Point(
((typeof (labelOffset.x) == 'number' ? labelOffset.x : 0) / Math.pow(2, map.getZoom())) || 0,
((typeof (labelOffset.y) == 'number' ? labelOffset.y : 0) / Math.pow(2, map.getZoom())) || 0
);
var offSetPosition = this.map.getProjection().fromPointToLatLng(new google.maps.Point(
point1.x - point2.x,
point1.y + point2.y
));
var position = projection.fromLatLngToDivPixel(offSetPosition);
// End custom code
div.style.left = position.x + 'px';
div.style.top = position.y + 'px';
div.style.display = 'block';
div.style.zIndex = this.get('zIndex'); //ALLOW LABEL TO OVERLAY MARKER
this.span_.innerHTML = this.get('text').toString();
};
/* END label.js */
Code to create map with markers:
var mapOptions = {
zoom: myZoom,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false
};
map = new google.maps.Map(document.getElementById("gmap"), mapOptions);
/* Insert logic here to iterate and add each marker */
// This function is called for every marker, i increases by 1 each call
function addMarker(latlng, mylabel, isShowroom, data, type, i) {
var markerImage;
var labelColor = '#666666';
if (isShowroom) {
markerImage = 'http://www.subzero-wolf.com/common/images/locator/pin-showroom.png';
} else {
if (type == 'service') {
markerImage = '/common/images/locator/pin-dealer.png';
} else if (type == 'parts') {
markerImage = '/common/images/locator/pin-parts.png';
} else {
markerImage = '/common/images/locator/pin-dealer.png';
}
}
var myMarker = new google.maps.Marker({
position: latlng,
draggable: false,
clickable: true,
map: map,
icon: markerImage,
zIndex: isShowroom ? 9999 : i
});
var html = "test content"
myMarker['isShowroom'] = isShowroom;
myMarker['infowindow'] = new google.maps.InfoWindow({
content: html
});
google.maps.event.addListener(myMarker, 'click', function() {
this['infowindow'].open(map, this);
});
// Dont show a label for the showroom because this is the marker with the star icon, no number needed
if (!isShowroom) {
var label = new Label({
map: map
});
label.set('zIndex', i);
label.bindTo('position', myMarker, 'position');
label.set('text', mylabel);
}
markerArray.push(myMarker);
}