Windows Phone has a number of great capabilities built into it for developers.  The Bing APIs allows you to easily give your application mapping functionality.  You may just want to give users directions to a fixed location.  What happens though when you want to give a user directions from their current location to an address that they are picking from application data?  This article will cover just that scenario.

Since almost everything in Windows Phone development is asynchronous this can get a little tricky.  You end up creating an event handler for a GeoCoordinateWatcher and follow that with a call to the Bing GeocodeService.  You end up with a chain of events where you are following the bouncing ball, but this is the sequence that I have found works. 

Let’s take a closer look.  In my example I am using a ListBox that is data bound to a ViewModel.  I am using the selected item to index into the ViewModel’s collection to pull back the address information.

First you are going to need to reference the System.Device namesapce.


You will also need to add a service reference to the Bing GeocodeService.

In the code file you will need to include the following using statements along with a using statement for your service reference.

using Microsoft.Phone.Tasks;
using Microsoft.Phone.Controls.Maps;
using System.Device.Location;

Add the following global variable in to communicate between your events.

private GeoCoordinateWatcher watcher;
private ItemViewModel itemModel;
private GeoCoordinate location;

The first thing you need to do is put code into one of the ListBox events to grab the current location of the phone.  This is done by creating a new GeoCoordinateWatcher and passing is a method to fire on completion.

watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(geoWatcherChanged);

In the geoWatcherChanged method we will capture the get the resulting phone location and fire off a request to the GeocodeService.  Before we do you will need an interpreter for the properties of the GeocodeRequest.Address.  Of course my conversion is from an American perspective.

  1. AddressLine = Street address
  2. Locality = City
  3. AdminDistrict = State
  4. PostalCode = Zip Code

Now lets look at the code for this section.  One thing to note is that you do need to get a Bing application key in order to use this call.

int index = this.myList.SelectedIndex;
itemModel = App.ViewModel.Items[index];

watcher = null;
location = e.Position.Location;

GeoService.GeocodeServiceClient geoService = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
GeocodeRequest request = new GeocodeRequest();
request.Credentials = new Credentials();
request.Credentials.ApplicationId = "Your Bing Key";

// Set the options to only return high confidence results
FilterBase[] filters = new FilterBase[1];
filters[0] = new ConfidenceFilter() { MinimumConfidence = Confidence.High };

GeocodeOptions geocodeOptions = new GeocodeOptions();
geocodeOptions.Filters = new ObservableCollection<FilterBase>(filters);
request.Options = geocodeOptions;
request.Address = new Address();
request.Address.AddressLine = itemModel.Address;
request.Address.Locality = itemModel.City;
request.Address.AdminDistrict = itemModel.State;
request.Address.PostalCode = itemModel.Zip;

geoService.GeocodeCompleted += new EventHandler<GeocodeCompletedEventArgs>(geocodeService_GeocodeCompleted);

The last step is to get the resulting location code and call the BingMapsDirectionsTask to launch the turn by turn directions. To do this we will use the geo code from both operation and label them so that it is easier for the user.

GeocodeResponse geocodeResponse = e.Result;

if (geocodeResponse.Results.Count() > 0)
BingMapsDirectionsTask task = new BingMapsDirectionsTask();
LabeledMapLocation labeledMapLocation = new LabeledMapLocation(itemModel.CompanyName, geocodeResponse.Results[0].Locations[0]);
task.Start = new LabeledMapLocation("You", location);
task.End = labeledMapLocation;
MessageBox.Show("Could not find the destination address");

Now we have an interactive set of direction based on your application data which make life easier for your users.  Have fun.