Display Google Maps Imagery using Bing Maps Silverlight Control

I’ve gotten a couple emails asking how to show Google Maps imagery using the Bing Maps Silverlight Control. I previously post how to display OpenStreetMaps and Yahoo maps imagery using the control, but is it possible to show Google Maps imagery too?? Yes, absolutely; well technically, but the Google Maps Terms of Use does prohibit it. Actually, the Google Maps Terms of Use prohibits the direct access of the map tile images, and does not specifically prohibit using them with the Bing Maps Silverlight Control.

SLBingMapsControl_GoogleMapsImagery

You may only continue reading if you are willing to break the Google Maps Terms of Use, and see how similar the two mapping platforms really are.

Remember the below code most likely violates the Google Maps Terms of Use, and probably shouldn’t be used in a production system; unless of course you really don’t mind breaking the terms of use.

The below code follows suite after the code I posted a while back on displaying OpenStreetMap and Yahoo Maps imagery within the Bing Maps Silverlight Control.

First, here’s some XAML usage samples using the Google Maps TIle Source classes listed further down. The first one is showing the Google Maps Road/Terrain imagery, the second shows the Google Maps Aerial/Satellite imagery:

<m:Map CopyrightVisibility="Collapsed" LogoVisibility="Collapsed">
    <m:Map.Mode>
        
        <mCore:MercatorMode></mCore:MercatorMode>
    </m:Map.Mode>
    <m:Map.Children>
        <m:MapTileLayer>
            <m:MapTileLayer.TileSources>
                <local:GoogleMapsRoadTileSource></local:GoogleMapsRoadTileSource>
            </m:MapTileLayer.TileSources>
        </m:MapTileLayer>
    </m:Map.Children>
</m:Map>

<m:Map CopyrightVisibility="Collapsed" LogoVisibility="Collapsed">
    <m:Map.Mode>
        
        <mCore:MercatorMode></mCore:MercatorMode>
    </m:Map.Mode>
    <m:Map.Children>
        <m:MapTileLayer>
            <m:MapTileLayer.TileSources>
                <local:GoogleMapsAerialTileSource></local:GoogleMapsAerialTileSource>
                <local:GoogleMapsLabelsTileSource></local:GoogleMapsLabelsTileSource>
            </m:MapTileLayer.TileSources>
        </m:MapTileLayer>
    </m:Map.Children>
</m:Map>

If you notice, the second example showing the usage of the Google Maps Aerial/Satellite imagery is displaying 2 tile sources. This is because Google Maps has separate tile sources for both the Aerial/Satellite imagery and the Labels. This example shows the Labels tile source over the top of the Aerial/Satellite tile source to give the desired effect of “Aerial with Labels.”

Now, here’s the main attraction of this article; the actual Google Maps TileSource objects referred to above:

public class GoogleMapsRoadTileSource : GoogleMapsTileSourceBase
{
    public GoogleMapsRoadTileSource()
        : base("http://mt{0}.google.com/vt/lyrs=m@128&hl=en&x={1}&y={2}&z={3}&s=")
    { }
}

public class GoogleMapsAerialTileSource : GoogleMapsTileSourceBase
{
    public GoogleMapsAerialTileSource()
        : base("http://khm{0}.google.com/kh/v=62&x={1}&y={2}&z={3}&s=")
    { }
}

public class GoogleMapsLabelsTileSource : GoogleMapsTileSourceBase
{
    public GoogleMapsLabelsTileSource()
        : base("http://mt{0}.google.com/vt/lyrs=h@128&hl=en&x={1}&y={2}&z={3}&s=")
    { }
}

public abstract class GoogleMapsTileSourceBase : Microsoft.Maps.MapControl.TileSource
{
    public GoogleMapsTileSourceBase(string uriFormat)
        : base(uriFormat)
    { }

    public override System.Uri GetUri(int x, int y, int zoomLevel)
    {
        return new Uri(string.Format(this.UriFormat, new Random().Next() % 4, x, y, zoomLevel));
    }
}

Disclaimer: Use the above posted code at your own risk. The usage of it may be in violation of the Google Maps Terms of Use.