I was playing with the Telerik Map control that out of the box provides you Bing Maps and Open Street Maps OSM maps. I found myself wondering how long would take to implement a provider for ArcGIS Online, so I gave myself a few minutes while the kids were watching TV and I created this provider that will attached to the Silverlight Telerik Map Control to consume ArcGIS.com Tiled map services.
The XAML for the Telerik Silverlight 4 Map Control:
<UserControl x:Class="TestMap.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:telerik="http://schemas.telerik.com/2008/xaml/presentation"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<telerik:RadMap x:Name="RadMap1" ZoomLevel="7" />
</Grid>
</UserControl>
The Code Behind
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
//this.RadMap1.Provider = new OpenStreetMapProvider();
this.RadMap1.Provider = new ArcGISServerMapProvider(Telerik.Windows.Controls.Map.MapMode.Aerial, true);
RadMap1.Center = new Location(34, -117);
RadMap1.ZoomLevel = 7;
}
}
The provider:
public class ArcGISServerMapProvider : MapProviderBase
{
public string mapServiceUrl { get; set; }
public string Token { get; set; }
public ArcGISServerMapProvider(MapMode mode, bool labelVisible) :
base(mode, labelVisible)
{
// You can always change this property to another map service.
mapServiceUrl = "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer";
}
public override MapProviderBase GetSource(MapMode mode, bool isLabelVisible)
{
return this;
}
/// <summary>
/// Only supports Web Mercator for now
/// </summary>
public override ISpatialReference SpatialReference
{
get
{
return new MercatorProjection();
}
}
public override Uri GetTile(int tileLevel, int tilePositionX, int tilePositionY)
{
StringBuilder builder = new StringBuilder();
builder.AppendFormat("{0}/tile/{1}/{2}/{3}", new object[] { this.mapServiceUrl, tileLevel/2, tilePositionY, tilePositionX });
if (!string.IsNullOrEmpty(this.Token))
{
builder.AppendFormat("?token={0}", new object[] { this.Token });
}
Uri uri = new Uri(builder.ToString());
return uri;
}
public override void Initialize()
{
}
public override bool IsLabelSupported
{
get { return false; }
}
public override bool IsModeSupported(MapMode mode)
{
return false;
}
public override System.Collections.Generic.IEnumerable<MapMode> SupportedModes
{
get { return null; }
}
protected override void OnMapModeChanged(MapMode oldMode, MapMode newMode)
{
}
}
The results is a nice looking map that you can zoom in and out and pan around.

Download the Source Code with the project file to play around or to fix my bugs.
I already found out that when zooming in very close, the viewer is requesting tiles from a level that does not exist, when I get sometime or the kids decide to go to sleep earlier, I’ll debug with the help of Fiddler to see what is the tiles requesting schema.
Disclaimer: The map consume is from ArcGIS Online, so please make sure you read this below to use it in a commercial application:
To use this map in a commercial (revenue-generating) application, you must purchase an annual subscription for the World Street Map Bundle or the USA/World Bundle. Please call 1-800-447-9778 or contact your local ESRI office to purchase a subscription.
5aa8fc3c-9e79-40fb-ace3-5e3f34b1e696|1|5.0