Routing
- 7 minutes to read
The Map control supports Microsoft’s Bing 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.
The Bing Route data provider provides the Map control’s routing functionality and is represented by the BingRouteDataProvider object. The sections below explain how to use the BingRouteDataProvider in the map control.
Important
Due to Bing canceling the SOAP service on July 30, 2017, the Map Control’s Bing Route provider does not work correctly in version 16.1 or earlier.
Enable Routing
Do the following to enable routing in the Map control:
Create an information layer and add it to the map.
The information provides vector elements that represent GIS data obtained from the Search service in the Map control. See Layers for more information.
- Create a BingRouteDataProvider instance and assign it to the InformationLayer.DataProvider property.
Specify the Bing Maps key using the BingMapDataProviderBase.BingKey property.
Note
Go to The Bing Maps Portal website to create a developer account.
Refer to How to: Get a Bing Maps Key to learn more about how to register a Bing Maps account and create a key for it.
The code snippet below shows how to do this.
<dxm:InformationLayer EnableHighlighting="False"
>
<dxm:InformationLayer.DataProvider>
<dxm:BingRouteDataProvider x:Name="routeProvider"
BingKey="{Binding Source={StaticResource YourBingKey}}"
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 Bing 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 BingRouteDataProvider.CalculateRoute method and pass the list of locations (waypoints) as its argument, as shown below.
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.
Calculate Routes from Major Roads
The Map control allows you to obtain different routes to a specified location (latitude and longitude coordinates) using major roads from the north, east, south, and west. If it cannot find major roads coming from these directions, the response may contain more than one route from the same direction or fewer than four routes.
For instance, an application UI contains two combo boxes named “cbMode” and “cbOptimize”, two text boxes named “tbLatitude” and “tbLongitude”, and a button named “calculateRoutes”.
To start a route calculation, click the Calculate Routes button. This calls the BingRouteDataProvider.CalculateRoutesFromMajorRoads method and a destination location (waypoint coordinates and description) and options are passed to its argument.
Private Sub calculateRoutes_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
routeProvider.CalculateRoutesFromMajorRoads(New RouteWaypoint(tbDestination.Text, location))
End Sub
The results for San Francisco (Latitude - “37.783333” and Longitude - “-122.416667”) are shown in the image below.
Routing Result
The RouteCalculationResult object that is provided by the BingRouteDataProvider.RouteCalculated event handler arguments’ BingRouteCalculatedEventArgs.CalculationResult stores the route calculation results from the Bing 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 BingRouteDataProvider.RouteCalculated event.
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.