This example illustrates how to implement a custom map data provider class inherited from the MapDataProviderBase type. In the example, a custom MapTileSourceBase class is implemented to supply tile URLs from the OpenStreetMap source.
MainWindow.xaml.vb |
Imports System
Imports System.Globalization
Imports System.Windows
Imports DevExpress.Xpf.Map
Namespace CustomMapDataProviderApp
Partial Public Class MainWindow
Inherits Window
Public Sub New()
InitializeComponent()
imageLayer.DataProvider = New CustomMapDataProvider()
End Sub
End Class
Public Class CustomMapDataProvider
Inherits MapDataProviderBase
Private ReadOnly projection_Renamed As New SphericalMercatorProjection()
Public Overrides ReadOnly Property Projection() As ProjectionBase
Get
Return projection_Renamed
End Get
End Property
Public Sub New()
SetTileSource(New CustomTileSource())
End Sub
Protected Overrides Function CreateObject() As MapDependencyObject
Return New CustomMapDataProvider()
End Function
Public Overrides Function GetMapSizeInPixels(ByVal zoomLevel As Double) As Size
Return New Size(Math.Pow(2.0, zoomLevel) * OpenStreetMapTileSource.tileSize, Math.Pow(2.0, zoomLevel) * OpenStreetMapTileSource.tileSize)
End Function
End Class
Public Class CustomTileSource
Inherits MapTileSourceBase
Private Const roadUrlTemplate As String = "http://{subdomain}.tile.openstreetmap.org/{tileLevel}/{tileX}/{tileY}.png"
Public Const maxZoomLevel As Integer = 20
Public Const tileSize As Integer = 256
Private Shared imageWidth As Integer = CInt((Math.Pow(2.0, maxZoomLevel))) * tileSize
Private Shared imageHeight As Integer = CInt((Math.Pow(2.0, maxZoomLevel))) * tileSize
Private Shared subdomains() As String = { "a", "b", "c" }
Public Sub New()
MyBase.New(imageWidth, imageHeight, tileSize, tileSize)
End Sub
Public Overrides Function GetTileByZoomLevel(ByVal zoomLevel As Integer, ByVal tilePositionX As Long, ByVal tilePositionY As Long) As Uri
Dim url As String = roadUrlTemplate
url = url.Replace("{tileX}", tilePositionX.ToString(CultureInfo.InvariantCulture))
url = url.Replace("{tileY}", tilePositionY.ToString(CultureInfo.InvariantCulture))
url = url.Replace("{tileLevel}", zoomLevel.ToString(CultureInfo.InvariantCulture))
url = url.Replace("{subdomain}", subdomains(GetSubdomainIndex(subdomains.Length)))
Return New Uri(url)
End Function
End Class
End Namespace
|
Application.xaml.vb |
Imports System
Imports System.Collections.Generic
Imports System.Configuration
Imports System.Data
Imports System.Linq
Imports System.Windows
Namespace CustomMapDataProviderApp
''' <summary>
''' Interaction logic for App.xaml
''' </summary>
Partial Public Class App
Inherits Application
End Class
End Namespace
|
Application.xaml |
<Application x:Class="CustomMapDataProviderApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
|
MainWindow.xaml |
<Window x:Class="CustomMapDataProviderApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/map"
Title="MainWindow" Height="350" Width="525">
<Grid>
<dxc:MapControl>
<dxc:ImageLayer x:Name="imageLayer"/>
</dxc:MapControl>
</Grid>
</Window>
|
MainWindow.xaml.cs |
using System;
using System.Globalization;
using System.Windows;
using DevExpress.Xpf.Map;
namespace CustomMapDataProviderApp {
public partial class MainWindow : Window {
public MainWindow () {
InitializeComponent();
imageLayer.DataProvider = new CustomMapDataProvider();
}
}
public class CustomMapDataProvider : MapDataProviderBase {
readonly SphericalMercatorProjection projection = new SphericalMercatorProjection();
public override ProjectionBase Projection { get { return projection; } }
public CustomMapDataProvider () {
SetTileSource(new CustomTileSource());
}
protected override MapDependencyObject CreateObject () {
return new CustomMapDataProvider();
}
public override Size GetMapSizeInPixels (double zoomLevel) {
return new Size(Math.Pow(2.0, zoomLevel) * OpenStreetMapTileSource.tileSize,
Math.Pow(2.0, zoomLevel) * OpenStreetMapTileSource.tileSize);
}
}
public class CustomTileSource : MapTileSourceBase {
const string roadUrlTemplate =
@"http://{subdomain}.tile.openstreetmap.org/{tileLevel}/{tileX}/{tileY}.png";
public const int maxZoomLevel = 20;
public const int tileSize = 256;
static int imageWidth = (int)Math.Pow(2.0, maxZoomLevel) * tileSize;
static int imageHeight = (int)Math.Pow(2.0, maxZoomLevel) * tileSize;
static string[] subdomains = new string[] { "a", "b", "c" };
public CustomTileSource ()
: base(imageWidth, imageHeight, tileSize, tileSize) {
}
public override Uri GetTileByZoomLevel (int zoomLevel, long tilePositionX, long tilePositionY) {
string url = roadUrlTemplate;
url = url.Replace("{tileX}", tilePositionX.ToString(CultureInfo.InvariantCulture));
url = url.Replace("{tileY}", tilePositionY.ToString(CultureInfo.InvariantCulture));
url = url.Replace("{tileLevel}", zoomLevel.ToString(CultureInfo.InvariantCulture));
url = url.Replace("{subdomain}", subdomains[GetSubdomainIndex(subdomains.Length)]);
return new Uri(url);
}
}
}
|