Blog Archives

Generic Bing maps pushpin clustering component for Windows Phone 7

A couple of weeks ago I wrote my own Windows Phone app Lovely Neighbourhood which is showing pushpins on the Bing maps control for Windows Phone 7. Because there where quit some pushpins close to each other I decided to use pushpin clustering (sometimes called marker clustering) to make map in the app look less chaotic than with all the pushpins on the map. (There where a few regions where you couldn’t even see the map anymore.)

After a little search I found a blog post by Colin Eberhardt who has a guide to pushpin clustering in WP7. I started implementing and after a few changes it works fine in my app. But than I saw an app from my colleague which was not using pushpin clustering and also on his map view it was pretty hard to see the map. At that moment I started thinking about rewriting the pushpin clustering code in a generic way, so it would be easy to implement in any app.

In this article I want to show you how to use my pushpin clustering component in your app.

The first step that you need to do is add a reference to the PushPinClusterer.dllin your project.

The next step will be to add the IClusteredGeoObject interface to your entity which has the GeoCoordinate property.

1 public class MyGeoObject : IClusteredGeoObject 2 { 3 public string Name { get; set; } 4 public string Country { get; set; } 5 6 public GeoCoordinate Coordinate { get; set; } 7 8 }

When you implement the interface, you have to implement the Coordinate property which is of type GeoCoordinate. You can just use this property as your location property, or in the getter/setter return/set your own GeoCoordinate property. After implementing the IClusteredGeoObject your entity is ready to be clustered.

The next step will be to setup your xaml so you have a layer where you can add the pushpins and a DataTemplate so you can make a difference between the objects you want to show on the map in case of a clustered pushpin or a normal pushpin.

Below you find the XAML for my Bing maps control with the MapItemsControl where I bind the ObservableCollection<T> from my pushpin clusterer and we reference the “pushpinSelector” datatemplate.

1 <my:Map Height="601" Name="map1" Width="456"> 2 <my:MapItemsControl Name="pushPinModelsLayer" 3 ItemsSource="{Binding PushpinModels}" 4 ItemTemplate="{StaticResource pushpinSelector}" /> 5 </my:Map>

The next step is adding the datatemplate to our resources section like below:

1 <DataTemplate x:Key="pushpinSelector"> 2 <my:Pushpin Location="{Binding Location}" CacheMode="BitmapCache"> 3 <my:Pushpin.Template> 4 <ControlTemplate> 5 <clusterer:PushpinTemplateSelector Content="{Binding}"> 6 <clusterer:PushpinTemplateSelector.ClusterTemplate> 7 <DataTemplate> 8 <Grid VerticalAlignment="Center" HorizontalAlignment="Center"> 9 <Ellipse Fill="Red" Width="40" Height="40" /> 10 <TextBlock Foreground="White" Text="{Binding ClusterCount}" 11 HorizontalAlignment="Center" VerticalAlignment="Center" /> 12 </Grid> 13 </DataTemplate> 14 </clusterer:PushpinTemplateSelector.ClusterTemplate> 15 <clusterer:PushpinTemplateSelector.PushpinTemplate> 16 <DataTemplate> 17 <StackPanel Background="Black"> 18 <TextBlock Text="{Binding CurrentObject.Name}" Foreground="White" /> 19 </StackPanel> 20 </DataTemplate> 21 </clusterer:PushpinTemplateSelector.PushpinTemplate> 22 </clusterer:PushpinTemplateSelector> 23 </ControlTemplate> 24 </my:Pushpin.Template> 25 </my:Pushpin> 26 </DataTemplate>

As you can see in the above xaml markup we have two pushpin templates, one for the clustered pushpins and one for the normal pushpins. The pushpin clusterer is telling you how many pushpins there are clustered by binding the Count property. In the “normal” pushpin you will get your object back from the binding by calling the CurrentObject property. So if you have a property Name on your entity you can bind it here by calling CurrentObject.Name.

The only thing we now have to do is load our data, for example in the OnNavigatedTo event where you can load the list of entities which have IClusteredGeoObject implemented. The following code can be used to start clustering your pushpins.

1 var clusterer = new PushpinClusterer<MyGeoObject>(map1, pins, 50); 2 pushPinModelsLayer.DataContext = clusterer;

When instantiating the PushPinClusterer you give the Type of your entity to the clusterer and as parameters the map you have defined in your xaml, the list of entities and an integer with the distance in pixels in which pushpins have to be clustered.

If you need to know when the clustering is complete you can subscribe to the ClusteringCompleted event, which will fire when it is finished clustering the pushpins.

That’s it, if you start your app now it will start clustering your pushpins.

I have created an example solution with the steps as described above, which you can download from my blog.

Hope this will help you adding pushpin clustering to your app, and I love to hear it from you if used it and in which app. If you have any questions, suggestions or anything else you can contact me on twitter by using @bloodyairtimer or leave a comment on this post.

Happy coding!

Lovely neighbourhood enters the Windows Phone marketplace

This weekend my official first Windows Phone app has been tested and certified for the Windows Phone marketplace. It’s called Lovely neighbourhood and can be downloaded by clicking on the name.

The concept of this app is that everyone knows the feeling that you are walking around somewhere and have the feeling “This is a lovely Neighbourhood”, I would like to live here. Well, with this app it shows you exactly what options you have to buy a house in this neighbourhood. You can filter the results based on price and distance from your location. When it has found the results it will show you them on the map. Based on how many items there are close to each other and your zoomlevel on the map it will cluster the pushpins.

When you tap on one of the house you would like to see it shows you the details about the the selected house. Besides that it will load the photo’s, neighbourhood information (average income, rental versus buying percentage etc) and also it shows which public objects (doctor, hospital, schools etc.) are close to this house so you can decide if this is really your “Lovely neighbourhood”.

Below you will find some screenshots of the app.

Screenshot_1Screenshot_2Screenshot_3Screenshot_4

In addition: This app only works when you’re located in the Netherlands because it will use the Huizenzoeker API to fetch data about the houses for sale.  

I’m open for feature requests, so if you have any good feedback or a feature request don’t hesitate to contact me by email or place a comment on this post.

And last but not least don’t forget to download the app.

WP-Download-English-Med

“Integrate" Bing Maps directions in your WP7 app

in the upcoming “Mango” update for Windows Phone 7, Microsoft has already released the Windows Phone Developer Tools Beta 2 for this new version which has got version number 7.1.

One of the new cool features which is included in this beta release is the support to use the “Directions” feature in Bing Maps from your app. This feature makes it very easy to make a location aware app and makes it interactive to the user to help him find a specific spot. (Think about an app that helps users find only your restaurants, ATM’s, your company or anything else that has a coordinate)

Please note that I’m trying to keep away from the “integrate” part, cause actually it’s not integrating but more like navigating away from your app to Bing Maps with the location you specified in your app.

Okay, bring on this new feature and show us how to do this.

First, let’s start with the introduction of this feature/class/task or how you want to call it. We are talking about the BingMapsDirectionsTask which is a very simple class that lives in the Microsoft.Phone.Tasks namespace. You can use this task to create a route on Bing Maps from your app. In short terms this class has three important objects (2 properties / 1 method). It has a Start and an End property, and a method Show() which is it.

Both properties are of type LabeledMapLocation, which have a constructor that expected a string for the name and GeoCoordinate for the location.

In general below code will be enough to create a route on the Bing Maps app:

1 BingMapsDirectionsTask directionTask = new BingMapsDirectionsTask(); 2 directionTask.Start = new LabeledMapLocation("Start", new GeoCoordinate(52.512794, 6.091539)); 3 directionTask.End = new LabeledMapLocation("End", new GeoCoordinate(52.512794, 6.091539)); 4 5 directionTask.Show();

Just three lines of code. Can it be easier?

Yes it can!

If you don’t assign a value to the start property than it will automatically take your location and calculate a route to your End location.

I have created a sample solution where you can use the locations from the emulator to specify a start location and when you click on the map it will take your position (which is set by the emulator) and calculate a route to the location you have clicked.

BingMapsLocationChooser

Choose a location by using the Additional tools.

BingMapsDirections

And there it is our own created direction in the Bing Maps app.

To be honest I’m a bit in doubt about what I think about this feature. On one side it’s a very handy, easily to implement feature that will give you navigation/routing to your location in minutes.

Another thought I still have is I’m adding a map control to my app, a user clicks around and if it needs to calculate a route it exits my app, and starts Bing Maps. No real integration.

Anyone having some thoughts about it?

Download:

Windows phone 7 directions button missing

When playing around in Windows Phone 7 I noticed that the Bing Maps functionality has a very nice and fast way to calculate a route from the point where you are by pressing the Directions button. (Your current location is determined by the A-GPS sensor in your WP7 device.) When calculating the route you have the choice to calculate a route driven by a car, or for walking.  Also finding a location on the map works easy by pressing the Find button and type a location or just speak to your phone to find it :) . When selecting details of the calculated route it smoothly zooms to the selected location. Very nice done.

“Current location on Bing Maps”

Normally I don’t use navigation a lot, but on my last vacation I was kind of lost the way back to my vacation home. I thought no problem at all, get my WP7 phone, start Bing Maps and voila find the route back home. WRONG…… Bing Maps was starting up and my current location was found within seconds, but there was no way to calculate a route or find a location on the map. The directions button was just disappeared. And when I tried to find a location, it only searches the internet and not the map. After a few tries Idecided to pickup my hardcopy map and navigate my way back on the ‘old school’ way. At that moment I was thinking that I did something wrong or that the internet connection wasn’t stable enough to calculate the route.

“Details of the calculated route on Bing Maps”

Back home I gave it another few tries, but without luck. Than I start thinking what settings do I have changed since I got my device. After a while I found out that I have changed the region settings from English to Netherlands. I have reverted this change, restarted my device and yes…….my directions button is back again.

I took the following steps to get my Directions and Find  functionality back on the Bing Maps:

1. Go to Settings

2. Open Region & Language

3. Change Browser & search language to English (United States)

4. Click on the link on top of the screen to accept the changes and restart your device.

I think that this functionality is only available in the languages in which WP7 is official launched. I will update this settings back to Netherlands when WP7 is officially launched in the Netherlands.