Loading Microsoft CDN Hosted OpenStreetMap Imagery in Silverlight Bing Maps Control

MSHostedOpenStreetMapImageryFromSilverlight Recently a new Bing Maps App for OpenStreetMap (OSM) was released. This new feature of the Bing Maps consumer facing website is hosting the OpenStreetMap imagery using the Azure CDN, rather than relying on OpenStreetMap’s server. There has been some question as to whether developers can use the Microsoft hosted OpenStreetMap imagery within their own applications.

I have not seen anything official from Microsoft on this, so I assume that doing this is against their terms of use. You assume any and all responsibility in violating their terms of use if you use the below code. Sorry for the disclaimer, but I don’t want you to tell Microsoft I told you it was ok. Basically, do not use this in a production application, unless you get consent from Microsoft.

Now the code…

Displaying the Map (XAML):

<UserControl x:Class="Silverlight_NewBingMapsRoadImagery_2010.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Silverlight_NewBingMapsRoadImagery_2010"
    xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"
    xmlns:mCore="clr-namespace:Microsoft.Maps.MapControl.Core;assembly=Microsoft.Maps.MapControl"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">

        <m:Map NavigationVisibility="Collapsed">
            <m:Map.Mode>
                
                <mCore:MercatorMode />
            </m:Map.Mode>
            <m:Map.Children>
                <m:MapTileLayer>
                    <m:MapTileLayer.TileSources>
                        
                        <local:OpenStreetMapTileSource />
                    </m:MapTileLayer.TileSources>
                </m:MapTileLayer>
            </m:Map.Children>
        </m:Map>
        
    </Grid>
</UserControl>

OpenStreetMapTileSource (C#):

public class OpenStreetMapTileSource : Microsoft.Maps.MapControl.TileSource
{
    public OpenStreetMapTileSource()
        : base()
    {
        this.UriFormat = "{UriScheme}://{3}.osm.virtualearth.net/{2}/{0}/{1}.png"
            .Replace("{UriScheme}", OpenStreetMapTileSource.PageUriScheme); // <-- set "http" or "https" appropriately
    }

    public override System.Uri GetUri(int x, int y, int zoomLevel)
    {
        // Randomly decide which server to use
        string server;
        var rnd = new Random();
        var i = rnd.Next(0, 2);
        switch (i)
        {
            case 1:
                server = "b";
                break;
            case 2:
                server = "c";
                break;
            default:
                server = "a";
                break;
        }

        // Format Uri for the desired map tile image
        return new Uri(string.Format(this.UriFormat, x, y, zoomLevel, server));
    }

    internal static string PageUriScheme
    {
        get
        {
            if ((HtmlPage.IsEnabled && (HtmlPage.Document != null)) && (HtmlPage.Document.DocumentUri != null))
            {
                return HtmlPage.Document.DocumentUri.Scheme;
            }
            return "HTTP";
        }
    }
}