Implement Routing Functionality with the Azure Maps Services
Environment
| Product Version | 2025.1.211 |
| Product | RadMap for WPF |
Description
Implementing routing functionality using the Azure Maps services.
Solution
To achieve routing functionality using the Azure Maps services, you can create a new helper class. It will create a URL request for the Microsoft's routing and geocoding APIs and use the response to display the route on the RadMap control. In order to receive valid responses from the routing and geocoding APIs, you will need to pass a valid location and subscription key to the request URL string.
Implementing a helper class for retrieving the route
internal class AzureRoutingHelper
{
private static HttpClient httpClient = new HttpClient();
internal static async Task<RouteInfo> GetRouteDirections(string startAddress, string endAddress)
{
var start = await GetGeoCode(startAddress);
var end = await GetGeoCode(endAddress);
return await GetRouteDirections(start, end);
}
internal static async Task<RouteInfo> GetRouteDirections(Location start, Location end)
{
var requestUrl = $"https://atlas.microsoft.com/route/directions/json?api-version=1.0&query={start}:{end}&instructionsType=text& subscription-key={Your Subscription Key}";
var response = await httpClient.GetAsync(requestUrl);
response.EnsureSuccessStatusCode();
var jsonContent = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true
};
var routeData = JsonSerializer.Deserialize<RouteResponse>(jsonContent, options);
var firstLeg = routeData.Routes[0].Legs[0];
var routeInfo = new RouteInfo() { Points = firstLeg.Points.Select(p => new Location(p.Latitude, p.Longitude)).ToList() };
return routeInfo;
}
internal async static Task<Location> GetGeoCode(string location)
{
var requestUrl = $"https://atlas.microsoft.com/geocode?api-version=2025-01-01&query={location}&subscription-key={Your Subscription Key}";
var response = await httpClient.GetAsync(requestUrl);
response.EnsureSuccessStatusCode();
var jsonContent = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true
};
var featureCollection = JsonSerializer.Deserialize<FeatureCollection>(jsonContent, options);
var firstCoordinates = featureCollection.Features.First().Geometry.Coordinates;
return new Location(firstCoordinates[1], firstCoordinates[0]);
}
}
public class FeatureCollection
{
public List<Feature> Features { get; set; }
}
public class Feature
{
public Geometry Geometry { get; set; }
}
public class Geometry
{
public List<double> Coordinates { get; set; }
}
public class RouteInfo
{
public List<Location> Points { get; set; }
}
public class RouteResponse
{
public List<Route> Routes { get; set; }
}
public class Route
{
public List<RouteLeg> Legs { get; set; }
}
public class RouteLeg
{
public List<RoutePoint> Points { get; set; }
}
public class RoutePoint
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}Additionally, you can follow the next example, which showcases how to utilize the created AzureRoutingHelper class and its logic.
Defining the RadMap and the UI elements for the routing logic
<Grid x:Name="LayoutRoot" Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.ColumnSpan="2" Margin="0 0 0 15">
<TextBlock Text="From" FontWeight="SemiBold" VerticalAlignment="Center"/>
<telerik:RadWatermarkTextBox x:Name="SourceTextBox"
Text="Sofia"
Width="210"
Margin="10 0 0 0"/>
<TextBlock Text="To" FontWeight="SemiBold" VerticalAlignment="Center" Margin="10 0 0 0"/>
<telerik:RadWatermarkTextBox x:Name="DestinationTextBox"
Text="Varna"
Width="210"
Margin="10 0 0 0"/>
<telerik:RadButton Content="Calculate"
Width="100"
Margin="15 0 0 0"
Click="CalculateRouteButtonClicked"/>
</StackPanel>
<telerik:RadMap x:Name="RadMap" Grid.Row="1" Grid.Column="1" MinZoomLevel="3" Margin="15 0 0 0">
<telerik:RadMap.Provider>
<telerik:AzureMapProvider SubscriptionKey="Your Subscription Key"/>
</telerik:RadMap.Provider>
<telerik:VisualizationLayer x:Name="RouteLayer" />
</telerik:RadMap>
</Grid>
Utilizing the AzureRoutingHelper class
public partial class MainWindow : Window
{
public MainWindow()
{
StyleManager.ApplicationTheme = new Windows11Theme();
InitializeComponent();
}
private void CalculateRouteButtonClicked(object sender, RoutedEventArgs e)
{
this.FindRoute();
}
private async void FindRoute()
{
this.RouteLayer.Items.Clear();
var start = this.SourceTextBox.Text;
var end = this.DestinationTextBox.Text;
RouteInfo routeInfo = null;
try
{
routeInfo = await AzureRoutingHelper.GetRouteDirections(start, end);
}
catch (Exception ex)
{
MessageBox.Show("Please, update the start or end location!", "Route calculation error.", MessageBoxButton.OK);
return;
}
if (routeInfo != null)
{
PolylineData routeLine = this.CreateNewPolyline(routeInfo.Points, Colors.Red, 3);
this.RouteLayer.Items.Clear();
this.RouteLayer.Items.Add(routeInfo.Points[0]);
this.RouteLayer.Items.Add(routeInfo.Points[routeInfo.Points.Count - 1]);
this.RouteLayer.Items.Add(routeLine);
}
var bestView = this.RouteLayer.GetBestView(this.RouteLayer.Items as IEnumerable<object>);
this.RadMap.SetView(bestView);
}
private PolylineData CreateNewPolyline(IEnumerable<Location> directionPoints, Color color, double thickness)
{
PolylineData routeLine = new PolylineData()
{
ShapeFill = new MapShapeFill()
{
Stroke = new SolidColorBrush(color),
StrokeThickness = thickness
},
Points = new LocationCollection(),
};
foreach (var point in directionPoints)
{
routeLine.Points.Add(point);
}
return routeLine;
}
}RadMap with AzureMapProvider and routing functionality

For a more in-depth example of an Azure Maps services routing, check the Routing demo from our Demos application.