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

Offline Map Server

16 Answers 740 Views
Map
This is a migrated thread and some comments may be shown as answers.
Rami Aouizerate
Top achievements
Rank 1
Rami Aouizerate asked on 18 Aug 2010, 11:15 AM
Hello,
Can I use the telerik map contol, with one of the providers such as:
Bind, open source, google or any other you may know, while
the computer is not conected to the Internet?
I have a local server at the site which is conected to the web.
And maybe it can be used as the tiles provider, but I have no
Idea how to implement this.
Thank you,
Or.

16 Answers, 1 is accepted

Sort by
0
Velin
Telerik team
answered on 23 Aug 2010, 04:42 PM
Hi Rami Aouizerate,

It is possible to use the map control while offline. Here are some details about how to achieve this:
  1. First you need to download and save locally the 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.
  2. Create custom map provider to read the Open Street tiles from the file system.  

Here is some example code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Telerik.Windows.Controls.Map;
   
namespace Telerik.RadMap.WPF
{
    public class FileSystemProvider : MapProviderBase
    {
        private const int TILE_SIZE = 256;
        private bool initialized;
        private string tileLocation;
   
        /// <summary>
        /// Initializes a new instance of the FileSystemProvider class.
        /// </summary>
        /// <param name="mode">Map mode.</param>
        /// <param name="labelVisible">Is labels visible.</param>
        public FileSystemProvider(string tileLocation)
            : base(MapMode.Road, true)
        {
            this.tileLocation = tileLocation;
        }
   
        /// <summary>
        /// Initializes a new instance of the FileSystemProvider class.
        /// </summary>
        public FileSystemProvider()
            : this(null)
        {
        }
   
        /// <summary>
        /// Gets or sets location of the map tiles.
        /// </summary>
        public string TileLocation
        {
            get
            {
                return this.tileLocation;
            }
   
            set
            {
                this.tileLocation = value;
            }
        }
   
        /// <summary>
        /// Gets the IsInitialized property.
        /// Indicates that the provider is initialized.
        /// </summary>
        public override bool IsInitialized
        {
            get
            {
                return this.initialized;
            }
        }
   
        /// <summary>
        /// Gets value which indicates whether labels are supported by the map provider.
        /// </summary>
        public override bool IsLabelSupported
        {
            get
            {
                return false;
            }
        }
   
        /// <summary>
        /// Returns the SpatialReference for the map provider.
        /// </summary>
        public override ISpatialReference SpatialReference
        {
            get
            {
                return new MercatorProjection();
            }
        }
   
        /// <summary>
        /// Gets list of the supported map modes.
        /// </summary>
        /// <returns>List of the supported map modes.</returns>
        public override IEnumerable<MapMode> SupportedModes
        {
            get
            {
                yield return MapMode.Road;
            }
        }
   
        /// <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>
        public override Uri GetTile(int tileLevel, int tilePositionX, int tilePositionY)
        {
            int zoomLevel = ConvertTileToZoomLevel(tileLevel);
   
            string tileFileName = string.Format("os_{0}_{1}_{2}.png", tilePositionX, tilePositionY, zoomLevel);
            tileFileName = Path.Combine(this.TileLocation, tileFileName);
   
            if (File.Exists(tileFileName))
            {
                return new Uri(tileFileName);
            }
            else
            {
                return null;
            }
        }
   
        /// <summary>
        /// Initialize provider.
        /// </summary>
        public override void Initialize()
        {
            this.initialized = base.IsInitialized;
        }
   
        /// <summary>
        /// Gets value which indicates whether given mode is supported by map provider.
        /// </summary>
        /// <param name="mode">Map mode to check.</param>
        /// <returns>true if given mode is supported. Otherwise - false.</returns>
        public override bool IsModeSupported(MapMode mode)
        {
            return (mode == MapMode.Road);
        }
   
        /// <summary>
        /// MapModeChanged handler.
        /// </summary>
        protected override void OnMapModeChanged(MapMode oldMode, MapMode newMode)
        {
            if (!this.IsSuspended)
            {
                this.Initialize();
            }
        }
    }
}

Here is an example of using the file system map provider in XAML.

<Window x:Class="Telerik.RadMap.WPF.MainWindow"
    xmlns:app="clr-namespace:Telerik.RadMap.WPF"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <telerik:RadMap x:Name="radMap"
            Center="48.5,2.25"
            ZoomLevel="13">
            <telerik:RadMap.Provider>
                <app:FileSystemProvider TileLocation="D:\Andrey\Telerik\OpenStreet Images\paris_13_cycle" />
            </telerik:RadMap.Provider>
        </telerik:RadMap>
    </Grid>
</Window>

Hope this will help.

All the best,
Ryan
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Boots
Top achievements
Rank 1
answered on 21 Apr 2011, 08:54 PM
Hi Ryan,

Is there a solution to this in Q1 2011 release? I tried this example earlier today with no luck.

Thanks Much,
~Boots
0
Andrey
Telerik team
answered on 26 Apr 2011, 08:40 AM
Hello Boots,

The architecture of the map providers has been changed since this post. With 2011 Q1 release it should look like the following:

/// <summary>
/// Tile source which read map tiles from the file system.
/// </summary>
public class FileSystemTileSource : TiledMapSource
{
    private string tilePathFormat;
    /// <summary>
    /// Initializes a new instance of the FileSystemTileSource class.
    /// </summary>
    /// <param name="tilePathFormat">Format string to access tiles in file system.</param>
    public FileSystemTileSource(string tilePathFormat)
        : base(1, 20, 256, 256)
    {
        this.tilePathFormat = tilePathFormat;
    }
    /// <summary>
    /// Initialize provider.
    /// </summary>
    public override void Initialize()
    {
        // Raise provider intialized event.
        this.RaiseIntializeCompleted();
    }
    /// <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 tileFileName = this.tilePathFormat.Replace("{zoom}", zoomLevel.ToString(CultureInfo.InvariantCulture));
        tileFileName = tileFileName.Replace("{x}", tilePositionX.ToString(CultureInfo.InvariantCulture));
        tileFileName = tileFileName.Replace("{y}", tilePositionY.ToString(CultureInfo.InvariantCulture));
        if (File.Exists(tileFileName))
        {
            return new Uri(tileFileName);
        }
        else
        {
            return null;
        }
    }
}

/// <summary>
/// Map provider which read map tiles from the file system.
/// </summary>
public class FileSystemProvider : TiledProvider
{
    /// <summary>
    /// Initializes a new instance of the MyMapProvider class.
    /// </summary>
    /// <param name="tilePathFormat">Format string to access tiles in file system.</param>
    public FileSystemProvider(string tilePathFormat)
        : base()
    {
        FileSystemTileSource source = new FileSystemTileSource(tilePathFormat);
        this.MapSources.Add(source.UniqueId, source);
    }
    /// <summary>
    /// Returns the SpatialReference for the map provider.
    /// </summary>
    public override ISpatialReference SpatialReference
    {
        get
        {
            return new MercatorProjection();
        }
    }
}

public MainWindow()
{
    InitializeComponent();
    this.radMap.Provider = new FileSystemProvider("Path to OpenStreet Images\\{zoom}\\{x}\\os_{x}_{y}_{zoom}.png");
}


Best wishes,
Andrey Murzov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Andreas
Top achievements
Rank 1
answered on 12 Jul 2011, 09:38 AM
Hello,

Is it possible to use Bing Maps instead of OpenStreet Maps?

Best,
0
Andrey
Telerik team
answered on 12 Jul 2011, 05:39 PM
Hello Thomas,

Download and usage of the Bing map tiles besides the Bing services is illegal. It is strongly prohibited by the Microsoft Bing license agreement and we would discourage you from proceeding with this approach any further.


All the best,
Andrey Murzov
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
John Zeweniuk
Top achievements
Rank 1
answered on 28 Aug 2011, 03:37 AM
I am creating a custom provider as in this example with my own Images for the tiles.  It is  working, but the images take a long time ( more than 10 seconds)  to appear in the map.  Can I make the tiles show up on the map faster when the url is a local file?  
0
Andrey
Telerik team
answered on 31 Aug 2011, 02:49 PM
Hi John Zeweniuk,

It is hard to say what are the reasons for the erroneous behavior of your code.
The first reason for this behavior could be in using geobounds in your custom map provider. When the tiled map provider uses geobounds then for high zoom levels it could have a huge image size which will require downloading a lots of tiles. I would recommend to restrict the zoom level for this type providers. As alternative way you can consider the variant of provider without using geobounds.

Best wishes,
Andrey Murzov
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

0
Anton
Top achievements
Rank 1
answered on 16 Sep 2011, 09:44 AM
Hi Andrey,

I was referred to this thread by Vesselin.  My question/requirement is as follow:
We need to use OpenStreetMaps offline, we have the OSM data loaded into postgres, and mapnik is also running on that machine.
I have used python generate a test tile and that worked, but not sure if that is the answer? 

We want the exact same functionality to be able to pan/zoom from our local server, where the tiles will reload with the higher resolution tiles.  As I understand, this will be extracted from the postgres database, by mapnik, and must somehow link up with the RadMap custom provider?  From the example below, it looks like the application uses downloaded png images and then displays one image? 

In essence I want to host an exact duplicate of OpenStreetMaps offline, and then use my own layers.

We want to be able to display co-ordinates, and use co-ordinates to plot and do calculations and drawings, geomapping etc, all this data is in the postgres database, which is loaded from the OSM files. 

We are using C# Silverlight.

Thanks
Anton
0
Andrey
Telerik team
answered on 21 Sep 2011, 11:01 AM
Hi Anton,

The map tile provider doesn't show 1 image. It provides RadMap with access to all necessary images. It is up to you how to implement it on "server" side: using postgre and mapnik, or just placing the images in the right folders on web-server. In both cases you have to implement custom map tile provider which will ask your "server" for map tiles by request from the RadMap control.   

The RadMap functionality which shows geographically positioned elements, map shapes and so on doesn't relate to the source of the map tiles (images), but just use projection provided by map tile provider (it should be Mercator projection when OSM images are used).

Kind regards,
Andrey Murzov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Anton
Top achievements
Rank 1
answered on 21 Sep 2011, 11:33 AM
Hi Andrey,

Thank you for the reply.  I now understand how to implement the serverside, and that my issue is with getting postgis and mapnik to generate the images for me on request.

I've setup a server using the map tiles in the folder structure and that works very nicely.

Thanks
Anton
0
Pedro
Top achievements
Rank 1
answered on 21 Oct 2011, 04:36 PM
Hi,

I already have a tiling system using "MapProviderBase" with MercatorProjection like Open Street Maps and google maps. Is possible to implement a tile system using other Projection? Or we just can do that with Spherical Mercator projection? I'm using the "GetTile" function:

public override Uri GetTile(int tileLevel, int tilePositionX, int tilePositionY)


Best Regards,
Gonçalo Martins
0
Andrey
Telerik team
answered on 26 Oct 2011, 08:20 AM
Hi Gonçalo,

Yes, the map control allows you to use your own custom projections. You can override the SpatialReference property in your custom provider for changing its projection.
The sample code is below.
public class CustomProvider : TiledProvider
{
    /// <summary>
    /// Initializes a new instance of the CustomProvider class.
    /// </summary>
    public CustomProvider()
        : base()
    {
        var source = new CustomSource();
        this.MapSources.Add(source.UniqueId, source);
    }
 
    /// <summary>
    /// Returns the SpatialReference for the map provider.
    /// </summary>
    public override ISpatialReference SpatialReference
    {
        get
        {
            return new CustomProjection();
        }
    }
}

Currently the map control contains the following projections:
- The Mercator projection EPSG:4326 (default) that refers to WGS84 as (latitude, longitude) pair coordinates in degrees
- The OSGB-1936 projection which also known as EPSG:27700
- The EPSG:900913 projection which also known as EPSG:3857 and Pseudo-Mercator projection that refers to WGS84 as (latitude, longitude) pair coordinates in meters

I would recommend you to download the source code(you can do it using your account). Please take a look at the SpatialReference, MercatorProjection, EPSG900913Projection and OSGB1936Projection classes of the DataVisualization_SL project.
You can find them at the following location:
\Controls\DataVisualization\Map\Providers\Map\SpatialReference.cs
\Controls\DataVisualization\Map\Layers\MercatorProjection.cs
\Controls\DataVisualization\Map\Projections\EPSG900913Projection.cs
\Controls\DataVisualization\Map\Projections\OSGB1936Projection.cs

I hope the source code of these methods helps you with understanding of the functionality of spatial reference.
The SpatialReference contains the GeographicToLogical and LogicalToGeographic methods. Actually they implement the Mercator projection. The EPSG900913Projection and OSGB1936Projection classes inherit the ProportionalProjection class which contains own implementation of these methods.
The map which is covered by tiles of map provider uses logical coordiantes (from 0 to 1). The GeographicToLogical and LogicalToGeographic methods implement the projection of any geographic coordinate to logical and vice versa.

Kind regards,
Andrey Murzov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Amy
Top achievements
Rank 1
answered on 25 Mar 2020, 06:51 PM

Hi, 

I have 6 .tiles files in a zip folder in a folder called resources (not properties.Resources.resx, just a folder titled resources).Is this the right way of storing them and what do I pass into FileSystemProvider?

0
Vladimir Stoyanov
Telerik team
answered on 30 Mar 2020, 09:39 AM

Hello Amy,

You can check out the following SDK example: ProvidersFileSystemMapProvider, which demonstrates a sample implementation of a FileSystemMapProvider.

I hope you find this helpful.

Regards,
Vladimir Stoyanov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
Amy
Top achievements
Rank 1
answered on 02 Apr 2020, 06:15 PM
Where do I download tiles in this format? I have tried downloading from OpenStreetMaps Downloader, but they do not organize them in the same folder format that you do in this example. 
0
Vladimir Stoyanov
Telerik team
answered on 07 Apr 2020, 12:50 PM

Hello Amy,

I don't think that you can download the files directly in the same format. You can either organize them manually in the format used in the example or update the logic to fit your scenario.

The folders in the referenced example are organized by zoom levels. Each folder contains tiles for the corresponding zoom level. The names of the tiles are in the following format "os_{x}_{y}_{zoom}.png". The important logic to check out is in the GetTile method of the FileSystemTileSource class. It is responsible for finding the correct tile based on the format that is provided in the MainWindow.xaml.cs file. 

Regards,
Vladimir Stoyanov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Tags
Map
Asked by
Rami Aouizerate
Top achievements
Rank 1
Answers by
Velin
Telerik team
Boots
Top achievements
Rank 1
Andrey
Telerik team
Andreas
Top achievements
Rank 1
John Zeweniuk
Top achievements
Rank 1
Anton
Top achievements
Rank 1
Pedro
Top achievements
Rank 1
Amy
Top achievements
Rank 1
Vladimir Stoyanov
Telerik team
Share this question
or