Mobile Zone is brought to you in partnership with:

Tim Murphy is a Solutions Architect at PSC Group, LLC (www.psclistens.com). He has been an IT Consultant since 1999 specializing in Microsoft technologies and Software Architecture. Tim is a co-founder of the Chicago Information Technology Architects Group as well as a contributing author of the book The Definitive Guide to the Microsoft Enterprise Library and part of the Influceners program on the geekswithblogs.net site. He has also spoken at the nPlus1 ArcSummit in Chicago, the Chicago Code Camp and has appeared on the Thirsty Developer podcast. Tim is a DZone MVB and is not an employee of DZone and has posted 56 posts at DZone. You can read more from them at their website. View Full User Profile

Using BingMapsDirectionsTask In Windows Phone 7

08.28.2012
| 2770 views |
  • submit to reddit

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.

image

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);
watcher.Start();

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.Stop();
watcher.Dispose();
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);
geoService.GeocodeAsync(request);

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;
    task.Show();
}
else
{
    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.

Published at DZone with permission of Tim Murphy, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)