Click here to Skip to main content
15,861,168 members
Articles / Mobile Apps / Windows Phone 7

Google Maps for Windows Phone 7 using Bing Map Control

Rate me:
Please Sign up or sign in to vote.
4.74/5 (52 votes)
3 Feb 2011CPOL3 min read 172.4K   6.1K   46   38
This article covers the way we could use Google Map using the Map Control shipped by Microsoft with Windows Phone 7 Developer Tools
main.PNG

Introduction

Microsoft launched Bing Maps in recent times which is a direct competitor to Google Maps. Bing Maps being relatively new has of course less data and lesser depth in Maps than Google Maps which is in this field for quite a few years. Often, developers want to incorporate Google Maps in their Windows Phone application which seems quite impossible as the Map Control provided by Microsoft is compatible with Bing Maps.

But the thing that we don't know is that Map Control is so flexible that we could display almost any Map on it (thanks to Microsoft for providing us the flexibility). So in this manner we are not bound to show just Bing Maps but we could also use any other map like Google Maps which is covered in this article.

Background

Basically Map Control is shipped with default imagery of Bing Maps for which we only need to provide Developer Credentials available from Bing Website and we are ready to use the Bing Maps. Map Control has all the basic functionality already built in like zooming and navigating into the Map. All we need is to just drop the control, provide credentials and here we go.

Using the Code

For Google Maps, we need to first understand the way Map Control works, well it basically continuously calls a method Uri GetUri(int x, int y, int zoomLevel) which returns a Uri which contains the image of the tile to be displayed. A tile is an image of 256x256 defined by its X and Y position in the grid forming the map of the world on a specific zoom level.

C#
Uri GetUri(int x, int y, int zoomLevel)

All we have to do is to write a class that inherits from Microsoft.Phone.Controls.Maps.TileSource that contains a overridden method Uri GetUri(int x, int y, int zoomLevel) which will display our custom tile which in our case is Google Maps Tile.

First, we need to define an Enum that contains all the modes of maps that Google Maps supports. We will use this Enum later when we will inspect the mode of our Map.

C#
public enum GoogleTileTypes
    {
        Hybrid,
        Physical,
        Street,
        Satellite,
        WaterOverlay
    }

Next we move on towards writing the class that we discussed above that will contain Uri GetUri(int x, int y, int zoomLevel) and some utility methods that we have created for our convenience.

C#
public class GoogleTile : Microsoft.Phone.Controls.Maps.TileSource
    {
        private int _server;
        private char _mapmode;
        private GoogleTileTypes _tiletypes;

        public GoogleTileTypes TileTypes
        {
            get { return _tiletypes; }
            set
            {
                _tiletypes = value;
                MapMode = MapModeConverter(value);
            }
        }

        public char MapMode
        {
            get { return _mapmode; }
            set { _mapmode = value; }
        }

        public int Server
        {
            get { return _server; }
            set { _server = value; }
        }

        public GoogleTile()
        {
            UriFormat = @"http://mt{0}.google.com/vt/lyrs={1}&z={2}&x={3}&y={4}";
            Server = 0;
        }

        public override Uri GetUri(int x, int y, int zoomLevel)
        {
            if (zoomLevel > 0)
            {
                var Url = string.Format(UriFormat, Server, MapMode, zoomLevel, x, y);
                return new Uri(Url);
            }
            return null;
        }

        private char MapModeConverter(GoogleTileTypes tiletype)
        {
            switch (tiletype)
            {
                case GoogleTileTypes.Hybrid:
                    {
                        return 'y';
                    }
                case GoogleTileTypes.Physical:
                    {
                        return 't';
                    }
                case GoogleTileTypes.Satellite:
                    {
                        return 's';
                    }
                case GoogleTileTypes.Street:
                    {
                        return 'm';
                    }
                case GoogleTileTypes.WaterOverlay:
                    {
                        return 'r';
                    }
            }
            return ' ';
        }
    }

We use the following URL as our Google Tile Source:

C#
UriFormat = @"http://mt{0}.google.com/vt/lyrs={1}&z={2}&x={3}&y={4}";

Where we have the following parameters:

  • {0} refers to the server number which we had kept y to 1
  • {1} refers to the character code of the mode of the map
  • {2} refers to the zoom level of the map
  • {3} refers to the x cordinate of the map
  • {4} refers to y cordinate of the map

Now, we move on towards the XAML part where we actually define the Map Control and its layers. First, we need the following two namespaces to MainPage.xaml:

C#
xmlns:GoogleTileSource="clr-namespace:googlemaps;assembly=googlemaps"
xmlns:MSPCMCore="clr-namespace:Microsoft.Phone.Controls.Maps.Core;
	assembly=Microsoft.Phone.Controls.Maps"

We will keep or Map Mode to Mercator which tells the control not to load any default imagery for the Map. Next, we place layers on the Map Control on which Tiles of Google Maps will be displayed. We have used 5 layers as we want to change the Mode of Map as per user's selection of RadioButtons. One could also show more than one layer at the same time by playing around with the Opacity property of different layers. If you want to keep the Mode static, you will only be needing one layer. Each layer has its Tile Source which in this case is the class GoogleTile.

XML
<Microsoft_Phone_Controls_Maps:Map Name="googlemap" Margin="0,161,0,0" 
	CopyrightVisibility="Collapsed" LogoVisibility="Collapsed" 
	ScaleVisibility="Visible" CredentialsProvider=
		"ApBXPZf5IR94SLXE8nh5FYsb5WHKrH1XPY7428-EqQudseivcWhCROIJvGmtnkAV">
    <Microsoft_Phone_Controls_Maps:Map.Mode>
        <MSPCMCore:MercatorMode/>
    </Microsoft_Phone_Controls_Maps:Map.Mode>
    <Microsoft_Phone_Controls_Maps:MapTileLayer Name="street" Margin="0,0,0,32">
        <Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
            <GoogleTileSource:GoogleTile TileTypes="Street"/>
        </Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
    </Microsoft_Phone_Controls_Maps:MapTileLayer>
    <Microsoft_Phone_Controls_Maps:MapTileLayer Visibility="Collapsed" 
		Name="wateroverlay" Margin="0,0,0,32">
        <Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
            <GoogleTileSource:GoogleTile TileTypes="WaterOverlay"/>
        </Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
    </Microsoft_Phone_Controls_Maps:MapTileLayer>
    <Microsoft_Phone_Controls_Maps:MapTileLayer Visibility="Collapsed" 
		Name="hybrid" Margin="0,0,0,32">
        <Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
            <GoogleTileSource:GoogleTile TileTypes="Hybrid"/>
        </Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
    </Microsoft_Phone_Controls_Maps:MapTileLayer>
    <Microsoft_Phone_Controls_Maps:MapTileLayer Visibility="Collapsed" 
		Name="satellite" Margin="0,0,0,32">
        <Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
            <GoogleTileSource:GoogleTile TileTypes="Satellite"/>
        </Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
    </Microsoft_Phone_Controls_Maps:MapTileLayer>
    <Microsoft_Phone_Controls_Maps:MapTileLayer Visibility="Collapsed" 
		Name="physical" Margin="0,0,0,32">
        <Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>

            <GoogleTileSource:GoogleTile TileTypes="Physical"/>
        </Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
    </Microsoft_Phone_Controls_Maps:MapTileLayer>
</Microsoft_Phone_Controls_Maps:Map>

Finally to provide users with some basic functionality of changing Mode and Zooming in and out, we wire up some event handlers.

C#
private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (h.IsChecked == true)
            {
                hybrid.Visibility = Visibility.Visible;
                satellite.Visibility = Visibility.Collapsed;
                street.Visibility = Visibility.Collapsed;
                physical.Visibility = Visibility.Collapsed;
                wateroverlay.Visibility = Visibility.Collapsed;
            }
            else if (st.IsChecked == true)
            {
                hybrid.Visibility = Visibility.Collapsed;
                satellite.Visibility = Visibility.Collapsed;
                street.Visibility = Visibility.Visible;
                physical.Visibility = Visibility.Collapsed;
                wateroverlay.Visibility = Visibility.Collapsed;
            }
            else if (sl.IsChecked == true)
            {
                hybrid.Visibility = Visibility.Collapsed;
                satellite.Visibility = Visibility.Visible;
                street.Visibility = Visibility.Collapsed;
                physical.Visibility = Visibility.Collapsed;
                wateroverlay.Visibility = Visibility.Collapsed;
            }
            else if (p.IsChecked == true)
            {
                hybrid.Visibility = Visibility.Collapsed;
                satellite.Visibility = Visibility.Collapsed;
                street.Visibility = Visibility.Collapsed;
                physical.Visibility = Visibility.Visible;
                wateroverlay.Visibility = Visibility.Collapsed;
            }
            else
            {
                hybrid.Visibility = Visibility.Collapsed;
                satellite.Visibility = Visibility.Collapsed;
                street.Visibility = Visibility.Collapsed;
                physical.Visibility = Visibility.Collapsed;
                wateroverlay.Visibility = Visibility.Visible;
            }
        }

        private void ButtonZoomIn_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            googlemap.ZoomLevel++;
        }

        private void ButtonZoomOut_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            googlemap.ZoomLevel--;
        }

So we are ready to take off with just a few lines of code, we are now able to use Google Maps with Bing Map Control provided by Microsoft in Windows Phone Developer tools (thanks to Microsoft for flexible and generic nature of the Map Control).

hybrid.PNG physical.PNG wateroverlay.PNG

street.PNG satellite.PNG

Points of Interest

In future, I plan to provide a more detailed tutorial containing all the features that Google Map provides including directions and routes.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Student Unikrew Solutions
Pakistan Pakistan
A student of Computer Sciences at NUCES-FAST karachi, Pakistan.

Having interst in mostly Microsoft related tools and technologies like :

.Net Framework
Expresison Blend
Windows Phone 7
SQL Server
Asp.net
WPF
Silverlight

Comments and Discussions

 
QuestionAdding Searchbox Pin
Member 1082577424-May-14 0:06
Member 1082577424-May-14 0:06 
Suggestion[My vote of 1] illegal usage of both apis Pin
Sperneder Patrick27-May-13 1:34
professionalSperneder Patrick27-May-13 1:34 
QuestionGoogle Map Pin
sameer_r21-May-13 9:45
sameer_r21-May-13 9:45 
GeneralMy vote of 4 Pin
danyloid3-Dec-12 22:56
danyloid3-Dec-12 22:56 
thanks for the article. nice approach.
GeneralMy vote of 4 Pin
Pham Anh Khoa5-Nov-12 14:57
Pham Anh Khoa5-Nov-12 14:57 
GeneralMy vote of 5 Pin
Kanasz Robert21-Sep-12 3:29
professionalKanasz Robert21-Sep-12 3:29 
QuestionClose but no cigar!!!! Pin
Member 165621426-Aug-12 10:20
Member 165621426-Aug-12 10:20 
QuestionNavigation , Latitude ?? Pin
cuj3om3-Jun-12 0:47
cuj3om3-Jun-12 0:47 
GeneralMy vote of 5 Pin
Shibu K V7-May-12 9:28
Shibu K V7-May-12 9:28 
Generaldirections and routes. Pin
ewfweefewewfewf28-Mar-12 0:02
ewfweefewewfewf28-Mar-12 0:02 
GeneralMy vote of 4 Pin
mmabdullah14-Mar-12 22:56
mmabdullah14-Mar-12 22:56 
QuestionExcuse me! Pin
Tokisan10-Feb-12 13:34
Tokisan10-Feb-12 13:34 
GeneralMy vote of 5 Pin
MunChan Park3-Feb-12 3:24
MunChan Park3-Feb-12 3:24 
QuestionMap Problem Pin
Himanshu Nigam29-Aug-11 0:06
Himanshu Nigam29-Aug-11 0:06 
Questionadd pushpin Pin
fithri16-Aug-11 21:11
fithri16-Aug-11 21:11 
AnswerRe: add pushpin Pin
fithri16-Aug-11 21:37
fithri16-Aug-11 21:37 
GeneralThis is against the Terms of Use Pin
Ricky Brundritt15-Apr-11 11:00
Ricky Brundritt15-Apr-11 11:00 
GeneralMy vote of 1 Pin
Ricky Brundritt15-Apr-11 10:58
Ricky Brundritt15-Apr-11 10:58 
GeneralMy vote of 1 Pin
Morten on GIS8-Feb-11 17:50
Morten on GIS8-Feb-11 17:50 
GeneralLegal issues Pin
omeecode9-Feb-11 17:03
omeecode9-Feb-11 17:03 
GeneralRe: Legal issues Pin
Morten on GIS10-Feb-11 15:21
Morten on GIS10-Feb-11 15:21 
GeneralMy vote of 5 Pin
BenWintringham7-Feb-11 21:50
BenWintringham7-Feb-11 21:50 
QuestionWhat's the legal position Pin
BenWintringham7-Feb-11 1:45
BenWintringham7-Feb-11 1:45 
AnswerRe: What's the legal position Pin
Naveed tejani7-Feb-11 11:06
Naveed tejani7-Feb-11 11:06 
GeneralRe: What's the legal position Pin
BenWintringham7-Feb-11 21:49
BenWintringham7-Feb-11 21:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.