This blog post provides a simple utility class that will cluster pushpins on a Bing Map control. This utility provides a way to achieve great performance with 1000s of pushpins.
The Bing Map control for Windows Phone 7 is a versatile control, allowing you to provide your users with an interactive map. The control has some very useful features such as Pushpins, which you can anchor to a map coordinate so that they move automatically as the user pans / zooms the map. However, I have found that in practice, if you have more than ~30 pushpins visible on a map, the pan / zoom performance starts to degrade (on a real device). Therefore, in order to provide the best user-experience, it is advisable to only render a handful of pushpins on the map at any one time.
This blog post describes a simple approach to clustering pushpins, as shown in the video below, which renders the location of ~500 juggling clubs worldwide:
The clustering code is very easy to use; just create a PushpinClusterer instance, pass your Pushpins, the map and the template to use for the clusters marker:
And that's it!
Clustering of map markers is a common problem. Searching the internet I found a number of blog posts describing techniques for clustering Google Maps markers, one such blog post described a simple algorithm which clusters points that are within a fixed pixel distance from each other. I decided to take this algorithm and apply it to the Silverlight Bing Maps control.
The clusterer is a pretty simple class, whenever the map view changes (which occurs after pan or zoom), the clusterer iterates over all the pins, any that are closer than 50 pixels to each other, are merged together.
Once the pins have been clustered, only those which would currently be visible (based on the map viewport) are added to the map:
The PushpinContainer is a class that holds a Pushpin, however, if one or more additional Pushpins are added to it, it will become a cluster. The class is given in full below:
The GetElement method will either return the Pushpin, if it has not been clustered, or a new Pushpin with the ClusterTemplate applied. Note, the Content property of the clustered pin is a list of the DataContext properties of all the pins it 'contains'.
The example application, which renders the location of ~500 juggling clubs, uses a very simple cluster template which simply indicates the number of points that have been clustered:
However, I am sure that with a bit of creativity, a more interesting template could be created!
Finally, the example application handles left mouse-clicks on the map, inspecting the DataContext of the clicked element in order to render the juggling club or cluster of juggling clubs which were clicked upon:
Let me know if you find this code useful, or you apply it in your application.
I am CTO at Scott Logic and am a prolific technical author, blogger and speaker on a range of technologies.
I'm board member of FINOS, which is encouraging open source collaboration in the financial sector. I'm also very active on GitHub, contributing to a number of different projects.