Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Marker Clusterer Plus on a google map with retina images

I'm using Marker Clusterer Plus to group markers on a google map but the enableRetinaIcons option does not seem to work.

// Custom style to alter the default font color (style is always the same).
var styles = [
    {
        url: 'PATH_TO_MY_66x66px_IMAGE',
        textColor: '#ddddd',
        textSize: 18,
        width: 33,
        height: 33,
    }
];

// Calculator function to determine which style to use (I only have one)
var calculator = function (markers, iconstyles){
    return{ text: markers.length.toString(), index:1};
};

// Set Options
var clusterOptions = {
    title: 'Cluster Title',
    enableRetinaIcons: true,
    styles: styles,
    calculator: calculator
}

// Add to map
new MarkerClusterer(this.map, this.markers, clusterOptions);

The enableRetinaIcons option does not seem to work, the image is shown twice the size.

Setting the width to 66x66px does not help either.

Does someone know how to configure this properly?

like image 424
Tieme Avatar asked Jan 10 '14 15:01

Tieme


People also ask

What kind of object can you use to add one or more markers to a map?

You can use custom SVG vector paths to define the visual appearance of markers. To do this, pass a Symbol object literal with the desired path to the marker's icon property. You can define a custom path using SVG path notation, or use one of the predefined paths in google. maps.

How many markers can Google Maps handle?

Answers. you can add 200 markers at a time but if you are using google service it will not response more than 10 or 20 at a time and if you have array of collection Lattitude and longitude just try to modify above code.


2 Answers

This is apparently bug in Marker Clusterer Plus. The only place in code where they actually use this option is here:

img = "<img src='" + this.url_ + "' style='position: absolute; top: " + spriteV + "px; left: " + spriteH + "px; ";
if (!this.cluster_.getMarkerClusterer().enableRetinaIcons_) {
  img += "clip: rect(" + (-1 * spriteV) + "px, " + ((-1 * spriteH) + this.width_) + "px, " +
      ((-1 * spriteV) + this.height_) + "px, " + (-1 * spriteH) + "px);";
}
img += "'>";

So they in fact only disable the clipping for sprite icons, but they don't actually run the required retina action. The HTML tree of the icon actually looks like this:

enter image description here

so you can see that the div surrounding the icon has proper dimensions set (33x33), but the very image (the blue code) doesn't have any dimensions set.

I tried to fix the problem by patching the marker clusterer library, just by adding an else branch:

img = "<img src='" + this.url_ + "' style='position: absolute; top: " + spriteV + "px; left: " + spriteH + "px; ";
if (!this.cluster_.getMarkerClusterer().enableRetinaIcons_) {
  img += "clip: rect(" + (-1 * spriteV) + "px, " + ((-1 * spriteH) + this.width_) + "px, " +
      ((-1 * spriteV) + this.height_) + "px, " + (-1 * spriteH) + "px);";
}
else {
    img += "width: " + this.width_ + "px;" + "height: " + this.height_ + "px;";
}
img += "'>";

It seems to work:

Complete patched library @pastebin

Test example - http://jsfiddle.net/Rt28T/2/

You can report a bug and add this as a proposed patch :-)

like image 65
Tomas Avatar answered Oct 18 '22 09:10

Tomas


I know this question has been answered, but another way to solve this issue (and probably easier) is just using an SVG marker icon. That way:

  • Your solution will support any device pixel density
  • You don't need to patch the library (with all the problems it can cause)
  • The current browser support is quite good — check caniuse.com svg-img for browser stats
like image 26
3oheme Avatar answered Oct 18 '22 09:10

3oheme