Dienstag, 15. Januar 2013

How to use Google Maps in your own Windows Phone App


When Google pulled the plug for it’s maps for all Windows Phone users two weeks ago, a loud fuss went trough the loyal Windows Phone user and developer base. A couple of days later Google found the plug again and since then we’re able to use the web version of Google Maps from our Windows Phones again.
The discussion around the whole map provider thing reminded me about a an implementation I did a while back for Windows Phone 7. I developed an app that displayed various map provider instead of the provided Bing Maps. It changed the base layer and allowed to display basically all base layer that support a standard URL scheme. Google Maps, Bing Maps and OpenStreetMaps are just a few examples. In this post I would like to show you how to use the Maps control in Windows Phone 8 and change the underlying base layer from Bing Maps to a different one.
Unfortunately this explanation has to start with a disclaimer. In Windows Phone 7 the shipped map control was using Bing Maps as a Base Layer and supported the change of the base layer. In Windows Phone 8 the story is a bit different as the Maps Control that ships with WP8 is a complete rewrite of the control from WP7 and does not support the change of the base layer at this point – although Microsoft said in a forum it’ll support it in a future version. That said, you can still use the “old” map control that has Bing Maps as a base layer in your Windows Phone 8 application. Keep in mind though, that the control is deprecated.

Create a new project


First of all create a new Windows Phone 8 project and add the old Maps control as a reference to your project. You can find the assembly in the WP SDK folder here C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Libraries.

ReferenceWindow

Add maps control to view


The view, where you want to add the map, needs the following references in the header. Please pay attention to the correct paths as you need to reference the “old” map control and not the new one with the Nokia base layer.


The next step is to add the actual map control to the view, by adding the following xaml into your view.


By default the map control supports all the known features of a map control like navigating the map, zooming and pinching, and displays the Bing Map as a base layer.

Implement custom base layer as TileSource


In order to change the underlying base layer and add a custom one, we need to create a custom TileSource that maps the request from the control to the Google Maps URL Scheme. The Map control cannot load all images for all zoom level for a given position. Therefore the layer is divided into map tiles. The control calculates how many map tiles it needs to display the current map section and requests each map tile individually from the base map provider. In our case GetUri gets called for each map tile with different values for x and y. The zoom level stays constant for a given section of the map as the zoom level is the same.



Special binding for base layer


The last piece is to swap the base map provider from Bing Maps to Google Maps. To accomplish this, I’ve created a special binding class that binds to a TileSource implementation on the ViewModel. This way it is very easy to change the base map provider again, as we only need to implement a new TileSource and change the type of the bound property on the ViewModel to the new implementation.
The Binding Helper is listed below.


To bind to the map, please change the xaml in the view to the following.


Make sure you create a ViewModel, bind that to your View and have a property called GoogleMap in your ViewModel that is of type Google – the type of the custom TileSource implementation.
In our implementation we choose Google Street as map type. Google offers Satellite, Hybrid and others as well. You can change those by swapping the map type in the constructor of the Google Map TileSource implementation.

Google_Screenshot1Google_Screenshot2Google_Screenshot3

Adding another base layer


Google Maps is not the only publisher of Web Mapping Service (WMS). Openstreetmap offers a service as well. To integrate openstreetmap as a base layer, use the implementation below and change the used TileSource in the ViewModel.


The map control now displays openstreetmap tiles.

Mapnik1Mapnik2Mapnik3

Kommentare:

  1. Do you know if it is possible to use your own images from isostorage within Windows 8 map control TileSource? It was not possible on WP7.
    The idea is to provide offline functionalities. Who knows... maybe in-app map purchasing ;)

    AntwortenLöschen
    Antworten
    1. Hi Pablo, since the control I am using in this post is the 'old' control from Bing Maps Control from 7.1 you can't load images from isolated storage.

      The new maps control that ships with WP8 does not allow to use a custom TileSource unfortunately.

      Löschen
  2. I would be interested to hear about loading from isostore as well.

    AntwortenLöschen
    Antworten
    1. Hi Steve, since the control I am using in this post is the 'old' control from Bing Maps Control from 7.1 you can't load images from isolated storage as this control doesn't allow to load from isostore.

      The new maps control that ships with WP8 does not allow to use a custom TileSource unfortunately.

      Löschen
  3. This article may be of interest:
    http://kodira.de/2013/01/offline-maps-with-windows-phone-8/

    AntwortenLöschen
  4. hi...Im student from Informatics engineering nice article,
    thanks for sharing :)

    AntwortenLöschen