Click here to Skip to main content
Click here to Skip to main content

Google Maps for Windows Phone 7 using Bing Map Control

, 3 Feb 2011
Rate this:
Please Sign up or sign in to vote.
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.

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.

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.

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:

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:

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.

<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.

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)

About the Author

Naveed tejani
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

 
GeneralMy vote of 4 Pinmembermmabdullah14-Mar-12 22:56 
QuestionExcuse me! [modified] PinmemberTM50010-Feb-12 13:34 
GeneralMy vote of 5 PinmemberPark,munchan3-Feb-12 3:24 
QuestionMap Problem PinmemberHimanshu Nigam29-Aug-11 0:06 
Questionadd pushpin Pinmemberfithri16-Aug-11 21:11 
AnswerRe: add pushpin Pinmemberfithri16-Aug-11 21:37 
GeneralThis is against the Terms of Use PinmemberRicky Brundritt15-Apr-11 11:00 
GeneralMy vote of 1 PinmemberRicky Brundritt15-Apr-11 10:58 
GeneralMy vote of 1 PinmemberMorten on GIS8-Feb-11 17:50 
GeneralLegal issues Pinmembermuhammadumairomee9-Feb-11 17:03 
GeneralRe: Legal issues PinmemberMorten on GIS10-Feb-11 15:21 
GeneralMy vote of 5 PinmemberBenWintringham7-Feb-11 21:50 
QuestionWhat's the legal position PinmemberBenWintringham7-Feb-11 1:45 
AnswerRe: What's the legal position PinmemberNaveed tejani7-Feb-11 11:06 
GeneralRe: What's the legal position PinmemberBenWintringham7-Feb-11 21:49 
AnswerRe: What's the legal position PinmemberMorten on GIS8-Feb-11 17:41 
GeneralMy vote of 3 Pinmemberch3ckmat36-Feb-11 20:28 
GeneralMy vote of 5 Pinmemberkarim aslam5-Feb-11 22:44 
GeneralMy vote of 4 Pinmemberfiza hassan5-Feb-11 22:39 
GeneralMy vote of 5 Pinmemberkhan ali asif5-Feb-11 22:31 
GeneralMy vote of 4 PinmemberMasaki Katata20105-Feb-11 3:53 
GeneralMy vote of 5 Pinmemberkamii474-Feb-11 21:50 
GeneralRe: My vote of 5 PinmemberNaveed tejani5-Feb-11 0:31 
GeneralMy vote of 5 Pinmemberfarxana4-Feb-11 21:46 
GeneralMy vote of 2 Pinmembercatfish1014-Feb-11 0:45 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 3 Feb 2011
Article Copyright 2011 by Naveed tejani
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid