This is a migrated thread and some comments may be shown as answers.

Caching maps

3 Answers 195 Views
Map
This is a migrated thread and some comments may be shown as answers.
Andrew
Top achievements
Rank 2
Andrew asked on 27 Nov 2013, 03:20 PM

I have two questions regarding the mapping control.


1) What mapping service do I need to purchase from Microsoft? Is it the service known as "Bing Maps for Enterprise - Known User Full"?



2) Thanks to Microsoft bending over backwards to accommodate any NSA request my client is unable to provide internet access (for fear NSA will have backdoor access to their critical infrastructure). Is there a way for me to (legally) cache the map data prior to shipment so internet access is not required once I've delivered the system to the customer. I understand the Microsoft license agreement requires full time internet access as part of the agreement. Could I run some sort of web cache? Are unique URL's used for each request to prevent caching? I'm not trying to avoid the license fees, I'm happy with those, it's the lack of internet access that's my problem.



Andrew

3 Answers, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 28 Nov 2013, 09:00 AM
Hello Andrew,



1) I'm afraid we aren't experienced much with MS licensing model and Bing Maps Platform API product lines. You have to ask MS what product is good for you and your application. Probably you can find some additional information here:

http://msdn.microsoft.com/en-us/library/ff428642.aspx

http://www.microsoft.com/maps/product/terms.html



2) I think you should consider the following two ways to show map tiles offline (without internet access):

1. You can implement a custom map provider which reads the individual map images from the file system. I have attached a sample solution which implements the file system map provider. For additional information you can check this help topic and this forum thread.

2. You can create own local tile server with full set of the tile images or it can be a server which is accessible within intranet. In this case you also will need to implement a custom map provider for loading tiles from this server.

Unfortunately the download and usage of the Bing map tiles besides the Bing services is illegal. It is strongly prohibited by the Microsoft Bing license agreement. So, I'll describe a way which uses offline OpenStreetMap content for the RadMap control.

It is quite simple to create tile server 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 in a separate directory in the C:\inetpub\wwwroot folder. 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 whole structure of the OpenStreet images to this new folder.

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



/// <summary>
/// Tile source which read map tiles from the given URI.
/// </summary>
public class LocalhostTileSource : TiledMapSource
{
    private string tileUriFormat;
    
    /// <summary>
    /// Initializes a new instance of the LocalhostTileSource class.
    /// </summary>
    /// <param name="tileUriFormat">Format string to access tiles on the localhost.</param>
    public LocalhostTileSource(string tileUriFormat)
        : base(1, 20, 256, 256)
    {
        this.tileUriFormat = tileUriFormat;
    }
    
    /// <summary>
    /// Initialize provider.
    /// </summary>
    public override void Initialize()
    {
        // Raise provider intialized event.
        this.RaiseInitializeCompleted();
    }
    
    /// <summary>
    /// Gets the image URI.
    /// </summary>
    /// <param name="tileLevel">Tile level.</param>
    /// <param name="tilePositionX">Tile X.</param>
    /// <param name="tilePositionY">Tile Y.</param>
    /// <returns>URI of image.</returns>
    protected override Uri GetTile(int tileLevel, int tilePositionX, int tilePositionY)
    {
        int zoomLevel = ConvertTileToZoomLevel(tileLevel);
    
        string url = this.tileUriFormat.Replace("{zoom}", zoomLevel.ToString(CultureInfo.InvariantCulture));
        url = url.Replace("{x}", tilePositionX.ToString(CultureInfo.InvariantCulture));
        url = url.Replace("{y}", tilePositionY.ToString(CultureInfo.InvariantCulture));
        return new Uri(url);
    }
}
/// <summary>
/// Map provider which read map tiles from the file system.
/// </summary>
public class LocalhostProvider : TiledProvider
{
    private MercatorProjection spatialReference;
  
    /// <summary>
    /// Initializes a new instance of the LocalhostProvider class.
    /// </summary>
    /// <param name="tileUriFormat">Format string to access tiles on the localhost.</param>
    public LocalhostProvider(string tileUriFormat)
        : base()
    {
        this.spatialReference = new MercatorProjection();
        LocalhostTileSource source = new LocalhostTileSource(tileUriFormat);
        this.MapSources.Add(source.UniqueId, source);
    }
    
    /// <summary>
    /// Returns the SpatialReference for the map provider.
    /// </summary>
    public override ISpatialReference SpatialReference
    {
        get
        {
            return this.spatialReference;
        }
    }
}






Now you can use new map provider in your application:





<UserControl x:Class="LocalhostMapProvider.MainPage"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="400">
    
    <Grid x:Name="LayoutRoot" Background="White">
        <telerik:RadMap x:Name="radMap"
                        Center="48.95,2.3"
                        ZoomLevel="13">
        </telerik:RadMap>
    </Grid>
</UserControl>








using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
    
namespace LocalhostMapProvider
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
    
            this.radMap.Provider = new LocalhostProvider("http://myhost/os_images/{zoom}/{x}/{y}.png");
        }
    }
}




The ConvertTileToZoomLevel method is inherited from TiledMapSource class so you do not need to bother about its implementation.



Regards,

Andrey Murzov

Telerik



TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.

Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.

Sign up for Free application insights >>




0
Andrew
Top achievements
Rank 2
answered on 30 Nov 2013, 10:50 AM

Andrey,



Thanks that's very cool. Do you know of any companies who sell satellite image tiles (compatible with your control) that allow offline use?


Andrew

0
Andrey
Telerik team
answered on 03 Dec 2013, 01:49 PM
Hi Andrew,

Unfortunately we don't have such information.However, I did a quick search in internet and I found the ArcGIS sells map tiles. You can find more details about them here: http://www.esri.com/software/arcgis/data-appliance.

Regards,
Andrey Murzov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.

Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.

Sign up for Free application insights >>
Tags
Map
Asked by
Andrew
Top achievements
Rank 2
Answers by
Andrey
Telerik team
Andrew
Top achievements
Rank 2
Share this question
or