So, I started this Google Maps based project last week, and the last time I had to do with the Google Maps API was several years ago (just right before the release of either v3 or maybe even v2) and I didn’t do much beyond playing around by adding some markers and lines back then. This time, I needed to display real-life data coming from a database in the form of markers, paths and areas, and when the project is live and as time proceeds, there will hopefully soon be hundreds or thousands of items to display.
Zooming out of a map with that amount of overlayed elements, will sooner or later end up looking very crowded, like this:
Not much of an eye candy, is it?
Beginning to dive into the Google Maps API documentation once again, one of the novelties I encountered were Data Layers and their ability to comfortably load GeoJSON data that is automatically converted to overlay objects – that can easily be exported to GeoJSON again after editing the map. If you don’t know about the GeoJSON format already, look at the specs, it’s worth a read. It’s a standardized JSON structure for geometrical features (Points, Lines, Polygons or collections of them). But I won’t go into any depth on this in this post, as it is intended to help those who are already working with GeoJSON data or who delayed working with data layers because of the problem related to handling large amounts of data as described above.
People were suggesting to either manually parse the GeoJSON data and create every point as a marker object, or listen to the ‘featureadded’ event on map.data when loading the GeoJSON and then remove it from the data layer and add it as a marker. This wouldn’t just be quite combersome, it would also make retrieving the markers as GeoJSON again more complex, and, quite bluntly, challenge the usefulness of the GeoJSON-to-data-layer feature in general, if you needed to something more than the rather simple demos provided in the API docs. So, just before I would have given up and done just that, I finally stumbled upon the data-layer-clusterer project by GitHub user “nantunes”.
Alas, needless to say that
Polygons were not implemented either – but I needed them so badly (, I grew tired of my confusion… Sorry – I don’t even really know that song, I just felt the urgent need to add a reference. Cat pics next time, it is.)
But, my ambition had been roused and I really wanted to make this work. And it actually did in less than a day, astonishingly. So, here it is, ladies and gentlemen and damsels in dire dispair, trying to add more than a dozen markers onto a Google Map (whoever could have imagined that people might feel the need to do this) – drumroll, please…
Lines and Polygons are currently clustered based on their center point (the center point of their bounding rectangle, to be exact). I also fixed the cluster marker images and created SVG versions of them, which are used by default if the browser supports SVG. I am also planning to add an option to force Lines and Polygons to be clustered when they fall below a pixel threshold value in either width or height.
Ahhh, a feast for the eyes.
Documentation is also to come, as there hadn’t been any (except for comments in the code) for the original repo of data-layer-clusterer. But its usage is pretty straight-forward, you can look at the JSFiddle code and into the code of the library itself. Basically, you can call most of the methods that you would call on the
map.data object directly on a
DataLayerClusterer, which are then passed on to the internally used data layer object. Or, as a last resort, you can get the internal data layer itself via the
_dataLayer property of any
I hope this will help many others in the future and lead to plenty of maps with plenty of GeoJSON content without making the users poke their eyes out with a fork due to sensory overload. Contributions are welcome, so bring on your shiny sparkly pull requests.
I added new boolean option, ‘setProperty’: If set to true, instead of changing the StyleOption attribute ‘visible’ of the features directly, a boolean property ‘in_cluster’ (or a configurable property name defined in the constant DataLayerClusterer.CLUSTER_PROPERTY_NAME)is set on the features, which can then be used to toggle visibility (for example in order to take into account other properties for additonal filtering, like I needed to do).
new option ‘recolorSvg’: (string) only takes action if SVG is supported and being used: a selector string for an SVG element in the set imagePath that can be used for re-coloring the cluster marker image. This saves requests and prevents the different marker images popping up after loading.
Updated the second demo to use the new version and a few LineStrings.
- This is actually the sound of a sheep, a snare drum and a snake falling of a cliff. Ok, never mind. ↩