In this article I show a simple example of integrating Bing and Google mapping into in WPF, Silverlight, and Windows Phone applications. I was inspired to investigate how easy it is to get up and running with maps on these platforms when I saw how similar the Bing APIs are in each case. While Google does not provide specific mapping controls for Silverlight/WPF, it's still quite straightforward to integrate the browser version, once you know where to start.
Overview
WPF | Silverlight | WP7 | Metro | |
Bing | Bing Maps WPF Control | Bing Maps Silverlight Control | Bing Maps Silverlight Control for Windows Phone | Bing Maps for Metro Style Apps (Beta) |
WebBrowser +Maps JavaScript API (or Maps API for Flash) |
Maps JavaScript API + OOB:WebBrowser In Browser:HTML overlay (windowless) |
WebBrowser + Maps JavaScript API | WebView + JavaScript API? |
Microsoft provide Bing mapping controls for Silverlight, Windows Phone 7, WPF, with a very similar API (and by very similar I mean in most cases there is just a different namespace). There is also an AJAX version, but there's no real reason to use that here.
Google provide a JavaScript API which can be used by hosting in a browser control, which works well in WPF, WP7 and Silverlight out-of-browser; in Silverlight in the browser, hosting HTML content is not possible, so I'll demonstrate overlaying HTML on top of the Silverlight app. For WPF (or WinForms) applications there's also the option of embedding the Google Maps Flash control, but I'll stick with the web version as it spans these different platforms.
In both cases there are "reasonable use" limits for free use of the service, which seem to me quite... reasonable. In the case of Google Maps there is a restriction around using the service for free if your app is not also free, and it's not clear to me exactly what this means, while Bing does not impose such a restriction, which might be relevant if you're publishing a WP7 app.
Data
As a data source I'll import data in the GPX format (an XML format for exchange of GPS data). I'll just pull out a sequence of locations from this, which we can then plot on the map. GPX files contain two types of locations, "track points" (part of a "track" which is meant to be logged GPS data), and "way points" (which are more meant to be part of a plotted course or significant locations), here we'll just play dumb and extract everything in a flattened format.
I'm just embedding a few GPX files in the app resources for this example. I've chosen a few running routes which you can see in the examples below, no prizes will be awarded for guessing which one I logged myself.
Lastly I'll expose the available tracks as a property AllTracks
and the selected track as Track
:
Bing - Silverlight
It's refreshingly simple to create a map to display our route. Setting the DataContext to the class described above, the following XAML displays a map of the route:
On top of this it's nice to actually show the relevant part of the map, so lets set the view based on the bounding rectangle of the given locations. I wanted to do this in XAML, but unfortunately this is a method on the Map class. First step, wrap this in an attached property:
Then we can make a converter to get the bounding LocationRect of our Locations collection:
It's quite nice to see pushpins for the route start/end, so lets add them. Just as MapPolyline is analogous to Polyline, MapItemsControl is to ItemsControl. So I can add pushpins by binding to the appropriate collection. Add a property and update it when loading a new track:
Here's the updated XAML with the view setting and push pins:
And the end result:
Bing - WPF
The WPF Bing control follows the Silverlight control API very closely, and other than the namespace there's little difference. Some options are different for the surrounding UI, but the main API is the same. It literally is as simple as using the same code files with:
The XAML is very similar - see the project at the end of the post for other details.
Bing - WP7
Again the WP7 API is similar, although in this case there are some differences. An obvious one is the Location class is supplemented with the Geolocation class - for example LocationCollection is now an ObservableCollection<Geolocation>. In fact there are implicit conversions between Location and Geolocation, so in most cases we can again get away with the same C# code with some careful use of types - other than some conditional includes:
Of course the end result looks somewhat different:
And finally
The various projects with the above code can be downloaded here. If I was going to create the same thing again I'd keep references to Bing namespaces entirely out of the common code with some more aggressive use of converters, rather than dancing around the differences, but as an exploration of the APIs I found it interesting to see how little had to change.
I'm going to pause for there and show the Google Maps version in another installment. There there will be some more interesting issues to consider.