Back to Devexpress

Routing

wpf-17465-controls-and-libraries-map-control-gis-data-routing.md

latest14.7 KB
Original Source

Routing

  • Jul 08, 2025
  • 7 minutes to read

The Map control supports Microsoft’s Azure Route service. This service provides the most optimal route, either from major roads in four directions, or calculated between two or more locations on a map.

AzureRouteDataProvider provide the Map control’s routing functionality. The sections below explain how to use the AzureRouteDataProvider in the map control.

Important

On May 21, 2024, Microsoft announced that Bing Maps for Enterprise and its API will be discontinued. Azure Maps will be a single unified enterprise mapping platform available from Microsoft.

To obtain and display map data from Azure Maps, we implemented the following providers:

For information on how to migrate your app from Bing Maps to Azure Maps, see the following help topic: DevExpress Map Control for WPF: Migrate from Bing Maps to Azure Maps.

If you already have a Bing Maps for Enterprise license, you can keep using the current API. You must transition to the new API by June 30, 2025 (for free/basic licenses) or June 30, 2028 (for enterprise licenses). New licenses will no longer be available after June 30, 2025. Bing Maps will not work with our map controls without a license after that date.

Enable Routing

Do the following to enable routing in the Map control:

  • Create an information layer and add it to the map.

  • Create a AzureRouteDataProvider instance and assign it to the InformationLayer.DataProvider property.

  • Specify the Azure key using the AzureKey property.

The code snippet below shows how to do this.

xaml
<dxm:InformationLayer EnableHighlighting="False"
                      >
    <dxm:InformationLayer.DataProvider>
        <dxm:AzureRouteDataProvider x:Name="routeProvider" 
                                    AzureKey="{Binding Source={StaticResource YourAzureKey}}"
                                    LayerItemsGenerating="routeProvider_LayerItemsGenerating"/>
    </dxm:InformationLayer.DataProvider>
</dxm:InformationLayer>

There are two ways to use the map routing feature in your application, depending on your task:

  • Calculate a route between two or more locations on a map;
  • Get a route from major roads to the specified destination.

The sections below describe each approach.

Calculate a Route between Locations

When the Map control is connected to the Azure Route service (see the section above for details), you can calculate a route between two or more locations on a map. To accomplish this, call the AzureRouteDataProvider.CalculateRoute method and pass the list of locations (waypoints) as its argument, as shown below.

csharp
public MainWindow() {
    InitializeComponent();

    // Create three waypoints and add them to a route waypoints list. 
    List<RouteWaypoint> waypoints = new List<RouteWaypoint>();
    waypoints.Add(new RouteWaypoint("New York", new GeoPoint(41.145556, -73.995)));
    waypoints.Add(new RouteWaypoint("Oklahoma", new GeoPoint(36.131389, -95.937222)));
    waypoints.Add(new RouteWaypoint("Las Vegas", new GeoPoint(36.175, -115.136389)));

    routeProvider.CalculateRoute(waypoints);
}

private void routeProvider_LayerItemsGenerating(object sender, LayerItemsGeneratingEventArgs args) {
    char letter = 'A';

    foreach (MapItem item in args.Items) {
        MapPushpin pushpin = item as MapPushpin;
        if (pushpin != null)
            pushpin.Text = letter++.ToString();
    }
}
vb
Public Sub New()
    InitializeComponent()

    ' Create three waypoints and add them to a route waypoints list. 
    Dim waypoints As New List(Of RouteWaypoint)()
    waypoints.Add(New RouteWaypoint("New York", New GeoPoint(41.145556, -73.995)))
    waypoints.Add(New RouteWaypoint("Oklahoma", New GeoPoint(36.131389, -95.937222)))
    waypoints.Add(New RouteWaypoint("Las Vegas", New GeoPoint(36.175, -115.136389)))

    routeProvider.CalculateRoute(waypoints)
End Sub

Private Sub routeProvider_LayerItemsGenerating(ByVal sender As Object, ByVal args As LayerItemsGeneratingEventArgs)
    Dim letter As Char = "A"c

    For Each item As MapItem In args.Items
        Dim pushpin As MapPushpin = TryCast(item, MapPushpin)
        If pushpin IsNot Nothing Then
            pushpin.Text = letter.ToString()
            letter = ChrW(AscW(letter) + 1)
        End If
    Next item
End Sub

The image below shows the calculated route between the specified locations on the map.

Routing Result

The RouteCalculationResult object that is provided by the AzureRouteDataProvider.RouteCalculated event handler arguments’ AzureRouteCalculatedEventArgs.CalculationResult stores the route calculation results from the Azure Route service.

For instance, you can access a route path between locations calculated in the Calculate a Route between Locations section of this document.

To accomplish this, handle the AzureRouteDataProvider.RouteCalculated event.

csharp
private void routeDataProvider_RouteCalculated(object sender, BingRouteCalculatedEventArgs e) {
    RouteCalculationResult result = e.CalculationResult;

    StringBuilder resultList = new StringBuilder();
    resultList.Append(String.Format("Status: {0}\n", result.ResultCode));
    resultList.Append(String.Format("Fault reason: {0}\n", result.FaultReason));
    resultList.Append(ProcessIntermediatePoints(result.IntermediatePoints));
    resultList.Append(ProcessRouteResults(result.RouteResults));

    tbResults.Text = resultList.ToString();
}
string ProcessIntermediatePoints(List<RouteWaypoint> points) {
    if (points == null) return "";

    StringBuilder sb = new StringBuilder("Intermediate Points:\n"); 
    sb.Append(String.Format(" _________________________ \n"));
    for (int i = 0; i < points.Count; ++i)
            sb.Append(String.Format(
                "Intermediate point {0}: {1} ({2})\n", 
                i+1,
                points[i].Description, 
                points[i].Location
            ));
    return sb.ToString();
}
string ProcessRouteResults(List<BingRouteResult> results) {
    if (results == null) return "";

    StringBuilder sb = new StringBuilder("RouteResults:\n");
    for (int i = 0; i < results.Count; i++) {
        sb.Append(String.Format(" _________________________ \n"));
        sb.Append(String.Format("Path {0}:\n", i+1));
        sb.Append(String.Format("Distance: {0}\n", results[i].Distance));
        sb.Append(String.Format("Time: {0}\n", results[i].Time));
        sb.Append(ProcessLegs(results[i].Legs));
    }
    return sb.ToString();
}
string ProcessLegs(List<BingRouteLeg> legs) {
    if (legs == null) return "";

    StringBuilder sb = new StringBuilder("Legs:\n");    
    for (int i = 0; i < legs.Count; i++) {
        sb.Append(String.Format("\tLeg {0}:\n", i+1));
        sb.Append(String.Format("\tStart: {0}\n", legs[i].StartPoint));
        sb.Append(String.Format("\tEnd: {0}\n", legs[i].EndPoint));
        sb.Append(String.Format("\tDistance: {0}\n", legs[i].Distance));
        sb.Append(String.Format("\tTime: {0}\n", legs[i].Time));
        sb.Append(ProcessItinerary(legs[i].Itinerary));
    }
    return sb.ToString();
}
string ProcessItinerary(List<BingItineraryItem> items) {
    if (items == null) return "";

    StringBuilder sb = new StringBuilder("\tInternary Items:\n");
    for (int i = 0; i < items.Count; i++) {
        sb.Append(String.Format("\t\tItinerary {0}:\n", i+1));
        sb.Append(String.Format("\t\tManeuver: {0}\n", items[i].Maneuver));
        sb.Append(String.Format("\t\tLocation: {0}\n", items[i].Location));
        sb.Append(String.Format("\t\tInstructions: {0}\n", items[i].ManeuverInstruction));
        sb.Append(ProcessWarnings(items[i].Warnings));
    }
    return sb.ToString();
}
string ProcessWarnings(List<BingItineraryItemWarning> warnings) {
    if (warnings == null) return "";

    StringBuilder sb = new StringBuilder("\t\tWarnings:\n");
    for (int i = 0; i < warnings.Count; i++) {
        sb.Append(String.Format("\t\t\tWarning {0}:\n", i + 1));
        sb.Append(String.Format("\t\t\tType: {0}\n", warnings[i].Type));
        sb.Append(String.Format("\t\t\tText: {0}\n", warnings[i].Text));

    }
    return sb.ToString();
}
vb
Private Sub routeDataProvider_RouteCalculated(ByVal sender As Object, ByVal e As BingRouteCalculatedEventArgs)
    Dim result As RouteCalculationResult = e.CalculationResult

    Dim resultList As New StringBuilder()
    resultList.Append(String.Format("Status: {0}" & ControlChars.Lf, result.ResultCode))
    resultList.Append(String.Format("Fault reason: {0}" & ControlChars.Lf, result.FaultReason))
    resultList.Append(ProcessIntermediatePoints(result.IntermediatePoints))
    resultList.Append(ProcessRouteResults(result.RouteResults))

    tbResults.Text = resultList.ToString()
End Sub
Private Function ProcessIntermediatePoints(ByVal points As List(Of RouteWaypoint)) As String
    If points Is Nothing Then
        Return ""
    End If

    Dim sb As New StringBuilder("Intermediate Points:" & ControlChars.Lf)
    sb.Append(String.Format(" _________________________" & ControlChars.Lf))
    For i As Integer = 0 To points.Count - 1
            sb.Append(String.Format("Intermediate point {0}: {1} ({2})" & ControlChars.Lf, i+1, points(i).Description, points(i).Location))
    Next i
    Return sb.ToString()
End Function
Private Function ProcessRouteResults(ByVal results As List(Of BingRouteResult)) As String
    If results Is Nothing Then
        Return ""
    End If

    Dim sb As New StringBuilder("RouteResults:" & ControlChars.Lf)
    For i As Integer = 0 To results.Count - 1
        sb.Append(String.Format(" _________________________" & ControlChars.Lf))
        sb.Append(String.Format("Path {0}:" & ControlChars.Lf, i+1))
        sb.Append(String.Format("Distance: {0}" & ControlChars.Lf, results(i).Distance))
        sb.Append(String.Format("Time: {0}" & ControlChars.Lf, results(i).Time))
        sb.Append(ProcessLegs(results(i).Legs))
    Next i
    Return sb.ToString()
End Function
Private Function ProcessLegs(ByVal legs As List(Of BingRouteLeg)) As String
    If legs Is Nothing Then
        Return ""
    End If

    Dim sb As New StringBuilder("Legs:" & ControlChars.Lf)
    For i As Integer = 0 To legs.Count - 1
        sb.Append(String.Format(ControlChars.Tab & "Leg {0}:" & ControlChars.Lf, i+1))
        sb.Append(String.Format(ControlChars.Tab & "Start: {0}" & ControlChars.Lf, legs(i).StartPoint))
        sb.Append(String.Format(ControlChars.Tab & "End: {0}" & ControlChars.Lf, legs(i).EndPoint))
        sb.Append(String.Format(ControlChars.Tab & "Distance: {0}" & ControlChars.Lf, legs(i).Distance))
        sb.Append(String.Format(ControlChars.Tab & "Time: {0}" & ControlChars.Lf, legs(i).Time))
        sb.Append(ProcessItinerary(legs(i).Itinerary))
    Next i
    Return sb.ToString()
End Function
Private Function ProcessItinerary(ByVal items As List(Of BingItineraryItem)) As String
    If items Is Nothing Then
        Return ""
    End If

    Dim sb As New StringBuilder(ControlChars.Tab & "Internary Items:" & ControlChars.Lf)
    For i As Integer = 0 To items.Count - 1
        sb.Append(String.Format(ControlChars.Tab & ControlChars.Tab & "Itinerary {0}:" & ControlChars.Lf, i+1))
        sb.Append(String.Format(ControlChars.Tab & ControlChars.Tab & "Maneuver: {0}" & ControlChars.Lf, items(i).Maneuver))
        sb.Append(String.Format(ControlChars.Tab & ControlChars.Tab & "Location: {0}" & ControlChars.Lf, items(i).Location))
        sb.Append(String.Format(ControlChars.Tab & ControlChars.Tab & "Instructions: {0}" & ControlChars.Lf, items(i).ManeuverInstruction))
        sb.Append(ProcessWarnings(items(i).Warnings))
    Next i
    Return sb.ToString()
End Function
Private Function ProcessWarnings(ByVal warnings As List(Of BingItineraryItemWarning)) As String
    If warnings Is Nothing Then
        Return ""
    End If

    Dim sb As New StringBuilder(ControlChars.Tab & ControlChars.Tab & "Warnings:" & ControlChars.Lf)
    For i As Integer = 0 To warnings.Count - 1
        sb.Append(String.Format(ControlChars.Tab & ControlChars.Tab & ControlChars.Tab & "Warning {0}:" & ControlChars.Lf, i + 1))
        sb.Append(String.Format(ControlChars.Tab & ControlChars.Tab & ControlChars.Tab & "Type: {0}" & ControlChars.Lf, warnings(i).Type))
        sb.Append(String.Format(ControlChars.Tab & ControlChars.Tab & ControlChars.Tab & "Text: {0}" & ControlChars.Lf, warnings(i).Text))

    Next i
    Return sb.ToString()
End Function

The result is shown in the image below.

See Also

WPF Map Control: Examples

Search

Geocode

DevExpress Map Control for WPF: Migrate from Bing Maps to Azure Maps