Offline Map Server

13 posts, 0 answers
  1. Rami Aouizerate
    Rami Aouizerate avatar
    1 posts
    Member since:
    May 2009

    Posted 18 Aug 2010 Link to this post

    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.
  2. Velin
    Admin
    Velin avatar
    391 posts

    Posted 23 Aug 2010 Link to this post

    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
  3. UI for WPF is Visual Studio 2017 Ready
  4. Boots
    Boots avatar
    81 posts
    Member since:
    Dec 2008

    Posted 21 Apr 2011 Link to this post

    Hi Ryan,

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

    Thanks Much,
    ~Boots
  5. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 26 Apr 2011 Link to this post

    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
  6. Thomas Roithmeier
    Thomas Roithmeier avatar
    17 posts
    Member since:
    Jul 2010

    Posted 12 Jul 2011 Link to this post

    Hello,

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

    Best,
  7. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 12 Jul 2011 Link to this post

    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!

  8. John Zeweniuk
    John Zeweniuk avatar
    3 posts
    Member since:
    Jul 2009

    Posted 27 Aug 2011 Link to this post

    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?  
  9. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 31 Aug 2011 Link to this post

    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 >>

  10. Anton
    Anton avatar
    3 posts
    Member since:
    Sep 2011

    Posted 16 Sep 2011 Link to this post

    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
  11. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 21 Sep 2011 Link to this post

    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 >>

  12. Anton
    Anton avatar
    3 posts
    Member since:
    Sep 2011

    Posted 21 Sep 2011 Link to this post

    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
  13. Pedro
    Pedro avatar
    25 posts
    Member since:
    Aug 2010

    Posted 21 Oct 2011 Link to this post

    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
  14. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 26 Oct 2011 Link to this post

    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 >>

Back to Top
UI for WPF is Visual Studio 2017 Ready