Geocoding and Routing with Bing Maps

Location-aware applications offer some of the richest experiences on a smartphone that really showcase the smartphone's unique blend of portability and network connectivity.  These applications often use geocoding and route calculation to power their experiences.  With the Bing Maps Control and Bing Maps Web Services, you can incorporate these features into Windows Phone applications to bring your location-aware concepts to life.

Get a Bing Maps Key

In order to access the Bing Maps Web Services for geocoding and route calculation, you'll first need to get a Bing Maps key for your application.  This key identifies your application to Bing and is sent with every request to the Bing Maps Web Services.

Configure Service References

The next step is to configure service references in your application to create proxy classes for interfacing with the Bing Maps Web Services.

  1. In Visual Studio, right click on your application project and select "Add Service Reference...".
  2. Enter https://dev.virtualearth.net/webservices/v1/GeocodeService/GeocodeService.svc for the Geocode Service and click Go.
  3. Once the service is discovered, enter "GeocodeService" for the namespace and click OK.
  4. Repeat steps 1-3 using https://dev.virtualearth.net/webservices/v1/RouteService/RouteService.svc for the Routing Service and "RouteService" for the namespace.

Add a Reference to the Bing Maps Control

The Bing Maps Control ships with the Windows Phone Developer Tools but resides in an assembly that is not referenced by default in the Visual Studio project templates.  Right click on your application project, select "Add Reference", and then select the Microsoft.Phone.Controls.Maps assembly to add the necessary reference.

Import the MapHelper Class

The Bing Maps Interactive SDK provides sample code for interacting with the Bing Maps Web Services.  I felt that the necessary modularity needed to make this code truly reusable was missing, so I wrapped the sample code in a helper class called MapHelper that exposes three public methods of interest.

  1. Geocode(string address, Map map)
  2. ReverseGeocode(double latitude, double longitude, Map map)
  3. CalculateRoute(string source, string destination, Map map)

These methods wrap the results from the service proxy responses into EventArgs objects and expose them in the GeocodeResultAvailable, ReverseGeocodeResultAvailable, and RouteResultAvailable events, respectively.  Simply add the attached MapHelper.cs file to your project, update its namespace to match the default namespace of your project, and then call the above methods with the desired parameters like below.

 var Map = new Map()
{
    CredentialsProvider = new ApplicationIdCredentialsProvider("[ApplicationId]")
};

Observable.FromEvent<GeocodeResultAvailableEventArgs>(
    ev => MapHelper.GeocodeResultAvailable += ev,
    ev => MapHelper.GeocodeResultAvailable -= ev).
    Where(args => args.EventArgs.Address.Equals("One Microsoft Way Redmond WA")).
    Take(1).
    Subscribe(
    (args) =>
    {
        if (args.EventArgs.GeocodeResult != null)
        {
            MessageBox.Show(args.EventArgs.Address + " = " + args.EventArgs.GeocodeResult.DisplayName);
        }
        else
        {
            MessageBox.Show("No match for " + args.EventArgs.Address);
        }
    });


MapHelper.Geocode("One Microsoft Way Redmond WA", Map);

In the above example, I create the Map control in code for simplicity.  If you already have a Map control in XAML, you can reference it via its x:Name.  I also use the Reactive Extensions for Windows Phone to provide more robust event handling.

To verify that you can in fact talk to the Bing Maps Web Service at this point, copy the above code into your main page's constructor.  Replace "[ApplicationId]" with your Bing Maps key created earlier, add references in your project to Microsoft.Phone.Controls.Maps, Microsoft.Phone.Reactive and System.Observable if they are not already there, and add using statements for Microsoft.Phone.Controls.Maps and Microsoft.Phone.Reactive.  If all goes well, you should receive a message box with the geocode result for "One Microsoft Way Redmond WA" when you launch your application.

Plot the Results on a Map

The above example simply displays the results in a message box in order to demonstrate how the MapHelper class simplifies talking to the Bing Maps Web Services.  In many scenarios, you will want to plot the results on the Bing Maps Control.

Attached is a Windows Phone Application Page I created for a local events application that contains a Bing Maps Control, a Progress Bar, and some additional map layers used for plotting results.  The code behind file contains callbacks for plotting geocodes as well as route calculations.  This particular page will try to calculate a route first and fall back to a geocode of the destination if a route cannot be calculated.  The page also contains logic so that the map will remember its state during tombstone scenarios.

While I don't expect this page to compile for you, I feel that it is a good reference for how to use the Bing Maps Control and MapHelper class in practice.

Conclusion

The possibilities for location-aware applications on smartphones are endless.  With the Bing Maps Control and the MapHelper class, you should be well equipped to light up the location-aware features of your Windows Phone applications.

Attachments.zip