wpf-118764-controls-and-libraries-map-control-examples-gis-data-routing-how-to-implement-a-custom-route-provider.md
This example demonstrates how to implement a custom route provider and use it to calculate a route between two geographical points.
To do this, design a class inheriting the InformationDataProviderBase abstract class and implement its CreateData method. Then, design a class inheriting the IInformationData interface and override its IInformationData.OnDataResponse event. Implement the CalculateRouteCore method to provide custom route calculations.
Imports DevExpress.Xpf.Map
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Threading.Tasks
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Data
Imports System.Windows.Documents
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Imaging
Imports System.Windows.Navigation
Imports System.Windows.Shapes
Namespace CustomRouteProvider
''' <summary>
''' Interaction logic for MainWindow.xaml
''' </summary>
Partial Public Class MainWindow
Inherits Window
Public Sub New()
InitializeComponent()
Dim provider As New RouteProvider()
infoLayer.DataProvider = provider
provider.CalculateRoute(New GeoPoint(70, 60), New GeoPoint(-60, -70))
End Sub
End Class
Public Class RouteProvider
Inherits InformationDataProviderBase
Protected Shadows ReadOnly Property Data() As RouteData
Get
Return CType(MyBase.Data, RouteData)
End Get
End Property
Public ReadOnly Property Route() As IEnumerable(Of GeoPoint)
Get
Return Data.Route
End Get
End Property
Public Overrides ReadOnly Property IsBusy() As Boolean
Get
Return False
End Get
End Property
Protected Overrides Function CreateData() As IInformationData
Return New RouteData()
End Function
Public Sub CalculateRoute(ByVal point1 As GeoPoint, ByVal point2 As GeoPoint)
Data.CalculateRoute(point1, point2)
End Sub
Public Overrides Sub Cancel()
Throw New NotImplementedException()
End Sub
Protected Overrides Function CreateObject() As MapDependencyObject
Return New RouteProvider()
End Function
End Class
Public Class RouteData
Implements IInformationData
Private ReadOnly route_Renamed As New List(Of GeoPoint)()
Public ReadOnly Property Route() As List(Of GeoPoint)
Get
Return route_Renamed
End Get
End Property
Public Event OnDataResponse As EventHandler(Of RequestCompletedEventArgs) Implements IInformationData.OnDataResponse
Private Function CreateEventArgs() As RequestCompletedEventArgs
Dim items(2) As MapItem
items(1) = New MapPushpin() With { _
.Location = route_Renamed(0), _
.Text = "A", _
.Information = route_Renamed(0).ToString() _
}
items(2) = New MapPushpin() With { _
.Location = route_Renamed(route_Renamed.Count - 1), _
.Text = "B", _
.Information = route_Renamed(route_Renamed.Count - 1).ToString() _
}
Dim polyline As New MapPolyline() With { _
.IsGeodesic = True, _
.Stroke = New SolidColorBrush() With {.Color = Colors.Red}, _
.StrokeStyle = New StrokeStyle() With {.Thickness = 4} _
}
For i As Integer = 0 To route_Renamed.Count - 1
polyline.Points.Add(route_Renamed(i))
Next i
items(0) = polyline
Return New RequestCompletedEventArgs(items, Nothing, False, Nothing)
End Function
Protected Sub RaiseChanged()
RaiseEvent OnDataResponse(Me, CreateEventArgs())
End Sub
Public Sub CalculateRoute(ByVal point1 As GeoPoint, ByVal point2 As GeoPoint)
CalculateRouteCore(point1, point2)
RaiseChanged()
End Sub
Private Sub CalculateRouteCore(ByVal point1 As GeoPoint, ByVal point2 As GeoPoint)
Me.route_Renamed.Clear()
route_Renamed.Add(point1)
route_Renamed.Add(point2)
End Sub
End Class
End Namespace
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CustomRouteProvider"
xmlns:dxm="http://schemas.devexpress.com/winfx/2008/xaml/map" x:Class="CustomRouteProvider.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="526" Width="517">
<Grid>
<dxm:MapControl>
<dxm:ImageLayer>
<dxm:OpenStreetMapDataProvider/>
</dxm:ImageLayer>
<dxm:InformationLayer x:Name="infoLayer"/>
</dxm:MapControl>
</Grid>
</Window>
using DevExpress.Xpf.Map;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace CustomRouteProvider {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
RouteProvider provider = new RouteProvider();
infoLayer.DataProvider = provider;
provider.CalculateRoute(new GeoPoint(70, 60), new GeoPoint(-60, -70));
}
}
public class RouteProvider : InformationDataProviderBase {
protected new RouteData Data { get { return (RouteData)base.Data; } }
public IEnumerable<GeoPoint> Route { get { return Data.Route; } }
public override bool IsBusy {
get {
return false;
}
}
protected override IInformationData CreateData() {
return new RouteData();
}
public void CalculateRoute(GeoPoint point1, GeoPoint point2) {
Data.CalculateRoute(point1, point2);
}
public override void Cancel() {
throw new NotImplementedException();
}
protected override MapDependencyObject CreateObject() {
return new RouteProvider();
}
}
public class RouteData : IInformationData {
readonly List<GeoPoint> route = new List<GeoPoint>();
public List<GeoPoint> Route { get { return route; } }
public event EventHandler<RequestCompletedEventArgs> OnDataResponse;
RequestCompletedEventArgs CreateEventArgs() {
MapItem[] items = new MapItem[3];
items[1] = new MapPushpin() { Location = route[0], Text = "A", Information = route[0].ToString() };
items[2] = new MapPushpin() { Location = route[route.Count - 1], Text = "B", Information = route[route.Count - 1].ToString() };
MapPolyline polyline = new MapPolyline() {
IsGeodesic = true,
Stroke = new SolidColorBrush() { Color = Colors.Red },
StrokeStyle = new StrokeStyle() { Thickness = 4 }
};
for (int i = 0; i < route.Count; i++)
polyline.Points.Add(route[i]);
items[0] = polyline;
return new RequestCompletedEventArgs(items, null, false, null);
}
protected void RaiseChanged() {
if (OnDataResponse != null)
OnDataResponse(this, CreateEventArgs());
}
public void CalculateRoute(GeoPoint point1, GeoPoint point2) {
CalculateRouteCore(point1, point2);
RaiseChanged();
}
void CalculateRouteCore(GeoPoint point1, GeoPoint point2) {
this.route.Clear();
route.Add(point1);
route.Add(point2);
}
}
}