Currently RadMap supports three built-in map providers: Bing Maps, Open Street Maps and Empty provider. The empty provider does not show any map tiles. It just provides spatial reference (projection) for other operations (i.e. KML or ESRI shape files).
The Bing Maps and Open Street Map providers read their tile images from internet. Of course a browser can use these images from its cache, but the Bing Maps provider requires internet connection because it uses a WCF service to get URLs of the tile images.
It is a common scenario that the map tiles would be fetched offline from a corporate server instead of internet.
This blog post will demonstrate how to create your own tile server which fetches the tiles and runs on localhost.

It is quite simple to create a tile server on localhost when you have images which can be identified by the zoom level and (x,y) position of the tile.

All that you need to do is put your tiles(the downloaded images) in a separate directory in the C:\inetpub\wwwroot folder for example. So if you have the OpenStreet map tiles organized in a way similar to the structure on the OpenStreet servers (zoom\x_pos\y_pos.png) then you can create tile server on localhost in a couple of steps:

1. Create new folder like "os_images" in the "C:\inetpub\wwwroot" folder.
2. Copy the whole structure of the OpenStreet images to this new folder.
Here are some details about how to achieve this:

First you need to download and save locally the map images(tiles) that you need to show. For example, if you are using the Openstreet map provider there is an application called Easy OpenstreetMap Downloader that can be used to do this automatically for you. You can find instructions here.

Now you can create new map tile source and map provider which will access images from this folder:

  1. /// <summary>
  2.     /// Tile source which read map tiles from the file system.
  3.     /// </summary>
  4.     public class LocalhostTileSource : TiledMapSource
  5.     {
  6.         private string tileUriFormat;
  7.  
  8.         /// <summary>
  9.         /// Initializes a new instance of the FileSystemTileSource class.
  10.         /// </summary>
  11.         /// <param name="tileUriFormat">Format string to access tiles on the localhost.</param>
  12.         public LocalhostTileSource(string tileUriFormat)
  13.             : base(1, 20, 256, 256)
  14.         {
  15.             this.tileUriFormat = tileUriFormat;
  16.         }
  17.  
  18.         /// <summary>
  19.         /// Initialize provider.
  20.         /// </summary>
  21.         public override void Initialize()
  22.         {
  23.             // Raise provider intialized event.
  24.             this.RaiseIntializeCompleted();
  25.         }
  26.  
  27.         /// <summary>
  28.         /// Gets the image URI.
  29.         /// </summary>
  30.         /// <param name="tileLevel">Tile level.</param>
  31.         /// <param name="tilePositionX">Tile X.</param>
  32.         /// <param name="tilePositionY">Tile Y.</param>
  33.         /// <returns>URI of image.</returns>
  34.         protected override Uri GetTile(int tileLevel, int tilePositionX, int tilePositionY)
  35.         {
  36.             int zoomLevel = ConvertTileToZoomLevel(tileLevel);
  37.  
  38.             string url = this.tileUriFormat.Replace("{zoom}", zoomLevel.ToString(CultureInfo.InvariantCulture));
  39.             url = url.Replace("{x}", tilePositionX.ToString(CultureInfo.InvariantCulture));
  40.             url = url.Replace("{y}", tilePositionY.ToString(CultureInfo.InvariantCulture));
  41.             return new Uri(url);
  42.         }
  43.     }
  44.  
  45.     /// <summary>
  46.     /// Map provider which read map tiles from the file system.
  47.     /// </summary>
  48.     public class LocalhostProvider : TiledProvider
  49.     {
  50.         /// <summary>
  51.         /// Initializes a new instance of the LocalhostProvider class.
  52.         /// </summary>
  53.         /// <param name="tileUriFormat">Format string to access tiles on the localhost.</param>
  54.         public LocalhostProvider(string tileUriFormat)
  55.             : base()
  56.         {
  57.             LocalhostTileSource source = new LocalhostTileSource(tileUriFormat);
  58.             this.MapSources.Add(source.UniqueId, source);
  59.         }
  60.  
  61.         /// <summary>
  62.         /// Returns the SpatialReference for the map provider.
  63.         /// </summary>
  64.         public override ISpatialReference SpatialReference
  65.         {
  66.             get
  67.             {
  68.                 return new MercatorProjection();
  69.             }
  70.         }
  71.     }

Here is how to use the new map provider in your application:

  1.    <UserControl x:Class="LocalhostMapProvider.MainPage"
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
  5.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  6.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  7.              mc:Ignorable="d"
  8.              d:DesignHeight="300" d:DesignWidth="400">
  9.    
  10.     <Grid x:Name="LayoutRoot" Background="White">
  11.         <telerik:RadMap x:Name="radMap"
  12.                         Center="48.95,2.3"
  13.                         ZoomLevel="13">
  14.         </telerik:RadMap>
  15.     </Grid>
  16. </UserControl>
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Windows;
  20. using System.Windows.Controls;
  21.    
  22. namespace LocalhostMapProvider
  23. {
  24.     public partial class MainPage : UserControl
  25.     {
  26.         public MainPage()
  27.         {
  28.             InitializeComponent();
  29.    
  30.             this.radMap.Provider = new LocalhostProvider("http://localhost/os_images/{zoom}/{x}/{y}.png");
  31.         }
  32.     }
  33. }

The ConvertTileToZoomLevel method is inherited from TiledMapSource class so you don't need to bother about its implementation.

Note: Download and usage of the Bing map tiles besides the Bing services is illegal. It is prohibited by the Microsoft Bing license agreement and we discourage you from using it as sample offline provider. If you have some questions do not hesitate to drop us a line here or in the Forum threads.

Happy coding with our controls!


About the Author

Evgenia Milcheva

Front-End Developer
Telerik XAML Team

Related Posts

Comments