Handling huge amount of markers on Google Maps with clusters

If you used Google Maps in your projects as a developer,  probably you faced with a problem to display huge amount of markers on the map. Problem seems more User Interface related, than technical. On small zoom it does not look good. I solved it using a very nice marker clustering library available from Google.

How marker cluster looks like

On the map below try to zoom in/out to see nice little penguins.

How to use it in your code

Usage is very simple and clear, have a code snipped below
var markerCluster = new MarkerClusterer(map, marker_list);
  • map - Google Map object
  • marker_list - javascript array of all markers added to the map
Indeed very simple!!

Advanced usage

There are some configuration options, that can change default behaivior. In this example I change cluser size and colors:
var markerCluster = new MarkerClusterer(map, marker_list, {
    gridSize:40,
    minimumClusterSize: 4,
    calculator: function(markers, numStyles) {
       if (markers.length >= 50) return {text: markers.length, index: 3}; // red
       if (markers.length >= 5) return {text: markers.length, index: 2};  // yellow
       return {text: markers.length, index: 0};    }                      // blue
});
  • map - Google Map object
  • marker_list - javascript array of all markers
  • gridSize - determines how many markers to unite into cluster
  • minimumClusterSize - clear by its name
  • calculator - function to change default cluster text and color

Full code

document.write('<div id="gmap" style="width:500px; height:500px;"></div>');
// Get center
var map_center = new google.maps.LatLng(0.1700235000, 20.7319823000);
 
// Load google map
var map = new google.maps.Map(document.getElementById("gmap"), {
    zoom:1,
    center:map_center,
    mapTypeId:google.maps.MapTypeId.HYBRID,
    panControl:false,
    streetViewControl:false,
    mapTypeControl:false
});
 
var pos;
var marker;
var marker_list = [];
for (var i = 0; i < 100; i++) {
    pos = new google.maps.LatLng(Math.floor(Math.random() * 50), Math.floor(Math.random() * 100));
    marker = new google.maps.Marker({
        position:pos,
        map:map,
        title:'Title',
        icon:'/other/gmap/marker.gif'
    });
    var storyClick = new Function("event", "alert('Click on marker " + i + " ');");
    google.maps.event.addListener(marker, 'click', storyClick);
 
    marker_list.push(marker);
}
 
    // Add marker clustering
    var markerCluster = new MarkerClusterer(map, marker_list, {
        gridSize:40,
        minimumClusterSize: 4,
        calculator: function(markers, numStyles) {
	    // Custom style can be returned here
            return {
                text: markers.length,
                index: numStyles
            };
        }
    });
 
 
Do not forget to include scripts: <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false" /> <script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.12/src/markerclusterer_packed.js" />

Several datasource

Have a look at new post with using two datasources with different cluster styles.

Links

 

29 comments

  1. I mean, is there a way with an option setting to change this range values? Let’s say 1-5 blue icon, 5-50 yellow icon, over 50 red icon…some told me to change the function in markercluster.js :
    MarkerClusterer.prototype.calculator_ = function(markers, numStyles) {
    var index = 0;
    var count = markers.length;
    var dv = count;
    while (dv !== 0) {
    dv = parseInt(dv / 10, 10);
    index++;
    }

    index = Math.min(index, numStyles);
    return {
    text: count,
    index: index
    };
    };
    I want to call the function out to my .php file

  2. all you need is custom calculator function like this:

    // Add marker clustering
    var markerCluster = new MarkerClusterer(map, marker_list, {
    gridSize:40,
    minimumClusterSize: 4,
    calculator: function(markers, numStyles) {
    if (markers.length >= 50) return {text: markers.length, index: 3};
    if (markers.length >= 5) return {text: markers.length, index: 2};
    return {text: markers.length, index: 0};
    }
    });

    it will display colors as you needed

  3. I am trying to show 2 types of data at different intersections, 1) ticket 2)accident, I have all the data in excel file, can I show both at the same time? i’m thinking semi-transparent circles of different colors, or a circle for one, a bar for the other

  4. Using Ajax, I am looking for a way or changing the icon of a marker in a cluster as in:

    markerArray[index].setIcon(imageFilePath);

    I can make the new marker icon appear by using:

    markerArray[index].setMap(myMap);

    But because the icon is within a cluster I would like the cluster to change.

    As soon as I zoom the cluster colour changes but I would like the cluster to change colour as soon as marker colour is changed. The cluster has styles for the various colours.

    If my question is difficult to follow let me know and I will provide more information.

    Thanks in advance

  5. Do you know what I have to add if I want the cluster color always to be “grey”? No matter how many places are in one cluster.

  6. Just return constant value in calculator Function, like this:

    // Add marker clustering
    var markerCluster = new MarkerClusterer(map, marker_list, {
    gridSize:40,
    minimumClusterSize: 4,
    calculator: function(markers, numStyles) {
    return {
    text: markers.length,
    index: 1
    };
    }
    });

    Put 1 or 2 or 3, etc.. to change colors.

  7. Please help a complete dummie…

    Can you provide the ful code including the javascript stuff…

    Where can I paste my custom Google Mpa URL…?

    Thanks

  8. Hi,

    Great stuff!!
    I want to use clustering of markers and I find very useful tips in your posts.
    There is slight difference I would love to be able to show.
    I have a large number of markers whose lat/long and other details (for the purpose of infobox) are picked up from a mySQL table and written to an xml file. These markers actually represent several locations across the country. These locations are aggregated into higher levels of groups until national level. To elaborate, the country consists of 5 Zones. Each Zone comprises of 10 regions. Each region comprises of 10 districts. Under each district I have about 10 locations. Is it possible to show the map at the lowest appropriate zoom so that all the Zones show as cluster icons(with their names displayed in acronyms and details showing in infowindow; and then on clicking any Zone, the map zooms and shows only the Regions under that zone as cluster icons of different colour and maybe smaller; and so on … Finally when we reach the level of districts, on clicking a district the final, most granular markers show.
    I am a complete dummy and would require real handholding please! Can you help?

  9. Hello,
    Could you give me plz small hint how to change standard text on marker clusterer?
    I want to place there avarage rating from clustered locals. It’s not possible by simple modification in calculator, isn’t it?
    Regards,
    M.M.

  10. the map is displaying but clustering is not showing on it plz help me out i badly needed to implement the clusterers

  11. Can someone help me add infowindow to each marker?

    Also, I dont understand the marker_list array and how it is being used in the example above. Is the marker_list array empty, and you are using the for loop just as an example to populate random markers?

    should i delete the for loop and instead fill in the marker_list array?

    Im so confused.

    Im so new to this, could someone please help me out?

  12. Hi,
    Really a great work specially for me, thanks!

    Could you give me please small hint about how to make sub clusters using this example?
    I want to make sub clusters if any cluster have more then the predefined size. for example if a cluster have more then 20 markers then this cluster further divide into 2 sub clusters and each cluster contains half of the markers. if we click on a cluster, the map zooms and shows only those sub clusters which are under that specific cluster. and so on … Finally when we clicking on any sub cluster then it will show individual markers that this cluster contain.

    i am a beginner, could someone kindly help or any guide to sort out the above problem!
    Thanks in advance.

  13. Hey!

    Awesome post! Loved it! The only thing I would add is some comment in the calculator that would say that index should be 1 greater than array index. And change “return {text: markers.length, index: 0};” to “return {text: markers.length, index: 1};” to make it a bit more clear. I wasted a few hours before I realized that I should use index+1 there.

    Anyway, great post!

  14. Hi,
    Really a great work & Good stuff specially for me, thanks!
    Could you give me please small hint about how to make sub clusters using this example?
    I want to make sub clusters if any cluster have more then the predefined size. for example if a cluster have more then 20 markers then this cluster further divide into 2 sub clusters and each cluster contains half of the markers. if we click on a cluster, the map zooms and shows only those sub clusters which are under that specific cluster. and so on … Finally when we clicking on any sub cluster then it will show individual markers that this cluster contain.
    i am a beginner, could you plz help or any guide to sort out the above problem!
    Thanks in advance.

  15. Hi,
    Great stuff!!
    I want to use clustering of markers and I find very useful tips in your posts.
    There is slight difference I would love to be able to show.
    I have a large number of markers whose lat/long and other details (for the purpose of infobox) are picked up from a mySQL table and written to an xml file. These markers actually represent several locations across the country. These locations are aggregated into higher levels of groups until national level. To elaborate, the country consists of 5 Zones. Each Zone comprises of 10 regions. Each region comprises of 10 districts. Under each district I have about 10 locations. Is it possible to show the map at the lowest appropriate zoom so that all the Zones show as cluster icons(with their names displayed in acronyms and details showing in infowindow; and then on clicking any Zone, the map zooms and shows only the Regions under that zone as cluster icons of different colour and maybe smaller; and so on … Finally when we reach the level of districts, on clicking a district the final, most granular markers show.
    I am a complete dummy and would require real handholding please! Can you help?

  16. This GridSize value should be given in Pixel, How the Value of GridSize in MarkerClusterer effects to Clustering ?

    What is the range of GridSize Value ? How it’s helpful for the markers to show up as a Cluster ? What exactly the practical significance of this Grid Size?

Leave a Reply

Your email address will not be published.