Thursday, April 23, 2009

MarkerClusterer: A Solution to the Too Many Markers Problem

Hi, I'm Xiaoxi (Frank) Wu. I'm a software engineer working for Beyondsoft in Beijing China, where I'm currently working on Maps API applications. While I was learning the Google Maps API, I got a lot of help from the forum and the open-source library, so I've decided to give back to the community with some of my own code.

The first library that I'm releasing is MarkerClusterer. Once, a friend of mine encountered a problem with his application. Using the API, he developed a map and added thousands of markers on the map, and saw that it made his map un-usably slow. This was because every marker is a combination of several DOM elements, and it's a lot of work for a browser to create many thousands of DOM elements. I decided that clustering would be a good solution for his problem, and came up with MarkerClusterer. MarkerClusterer collects markers into different clusters and displays the number of markers in each cluster with a label, creating new clusters as the map zoom level changes. The clustering algorithm is simple; for each new marker it sees, it either puts it inside a pre-existing cluster, or it creates a new cluster if the marker doesn't lie within the bounds of any current cluster. Because the clusters have a fixed size in each zoom level there are almost the same number of clusters in viewport in average - so MarkerClusterer has a good max and average run time. The screenshot below shows the effect of using MarkerClusterer on an array of 1000 markers (and the live demo shows you the speed difference):

It's easy to use - just add your markers to an array, pass that and your map into the MarkerClusterer, and it'll take care of the rest. Check out the simple example and code snippet below:

var markers = [];
  for (var i = 0; i < 100; ++i) {
    var latlng = new GLatLng(data.photos[i].latitude, data.photos[i].longitude);
    var marker = new GMarker(latlng);
    markers.push(marker);
  }
var markerCluster = new MarkerClusterer(map, markers);

You can also set some options for the MarkerClusterer like the cluster icons and the size of the clusters. You can see those used in this advanced example. If you want to learn more, check out the class reference or the how-to.

For other clustering options for your markers, check out the Maptimize hosted service or read this article that compares other 3rd-party clustering extensions.