Back to Devexpress

How to: Implement a Custom Route Provider

wpf-118764-controls-and-libraries-map-control-examples-gis-data-routing-how-to-implement-a-custom-route-provider.md

latest8.7 KB
Original Source

How to: Implement a Custom Route Provider

  • Jun 07, 2019
  • 4 minutes to read

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.

vb
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
xaml
<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>
csharp
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);
        }
    }
}