Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for .NET

Routing

Download Samples Repository

Description

Demonstrates simple point to point routing between two input locations with either OnlineLocatorTask or LocalLocatorTask.

"Desktop" "Store" "Phone" Available for Desktop, Store, Phone

Sample Code

<UserControl x:Class="ArcGISRuntime.Samples.Desktop.Routing"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013">
    <Grid>
        <Grid.Resources>
            <esri:SimpleLineSymbol x:Key="RouteSymbol" Color="#990000FF" Style="Solid" Width="3" />
            <esri:SimpleRenderer x:Key="RouteLayerRenderer" Symbol="{StaticResource RouteSymbol}" />
        </Grid.Resources>
        
        <esri:MapView x:Name="MyMapView" 
					  MapViewTapped="MyMapView_MapViewTapped">
			<esri:Map InitialViewpoint="-13044000, 3855000, -13040000, 3858000">
                <esri:ArcGISTiledMapServiceLayer
                    ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />

            </esri:Map>
			
			<esri:MapView.GraphicsOverlays>
				<esri:GraphicsOverlay ID="ExtentGraphicsOverlay" Renderer="{StaticResource RouteLayerRenderer}" />
				<esri:GraphicsOverlay ID="RouteGraphicsOverlay" Renderer="{StaticResource RouteLayerRenderer}" />
				<esri:GraphicsOverlay ID="StopsGraphicsOverlay" />
			</esri:MapView.GraphicsOverlays>
        </esri:MapView>

		<Border Background="White" BorderBrush="Black" BorderThickness="1"
				HorizontalAlignment="Right" VerticalAlignment="Top"
				Margin="30" Padding="20">
			<Border.Effect>
				<DropShadowEffect/>
			</Border.Effect>
			<StackPanel>
                <TextBlock Text="Tap stop points on the map to see a calculated route between the points." 
                           TextWrapping="Wrap" />

                <CheckBox x:Name="chkOnline" Content="Use Online Route Task" IsChecked="True" 
                          HorizontalAlignment="Center" Margin="0,12,0,0" Click="chkOnline_Click" />
                
                <StackPanel x:Name="panelRouteInfo" Margin="12" HorizontalAlignment="Center" Visibility="Collapsed">
                    <TextBlock>
                        <Run Text="Total Distance: " />
                        <Run x:Name="txtDistance" />
                    </TextBlock>
                </StackPanel>

                <Button Content="Restart" Click="ClearButton_Click" HorizontalAlignment="Center" Padding="20,4" Margin="0,12,0,0"/>

                <ProgressBar x:Name="progress" IsIndeterminate="True" Visibility="Collapsed" Margin="12" />
            </StackPanel>
        </Border>
    </Grid>
</UserControl>
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Layers;
using Esri.ArcGISRuntime.Symbology;
using Esri.ArcGISRuntime.Tasks.NetworkAnalyst;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace ArcGISRuntime.Samples.Desktop
{
    /// <summary>
    /// Demonstrates simple point to point routing between two input locations with either OnlineLocatorTask or LocalLocatorTask.
    /// </summary>
    /// <title>Routing</title>
    /// <category>Tasks</category>
    /// <subcategory>Network Analyst</subcategory>
    public partial class Routing : UserControl
    {
        private const string OnlineRoutingService = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/NAServer/Route";
        private const string LocalRoutingDatabase = @"..\..\..\samples-data\networks\san-diego\san-diego-network.geodatabase";
        private const string LocalNetworkName = "Streets_ND";

        private GraphicsOverlay _extentGraphicsOverlay;
		private GraphicsOverlay _routeGraphicsOverlay;
		private GraphicsOverlay _stopsGraphicsOverlay;
        private RouteTask _routeTask;

        public Routing()
        {
            InitializeComponent();

			_extentGraphicsOverlay = MyMapView.GraphicsOverlays["ExtentGraphicsOverlay"];
			_routeGraphicsOverlay = MyMapView.GraphicsOverlays["RouteGraphicsOverlay"];
			_stopsGraphicsOverlay = MyMapView.GraphicsOverlays["StopsGraphicsOverlay"];

            var extent = new Envelope(-117.2595, 32.5345, -116.9004, 32.8005, SpatialReferences.Wgs84);
            _extentGraphicsOverlay.Graphics.Add(new Graphic(GeometryEngine.Project(extent, SpatialReferences.WebMercator)));

            _routeTask = new OnlineRouteTask(new Uri(OnlineRoutingService));
        }

        private async void MyMapView_MapViewTapped(object sender, Esri.ArcGISRuntime.Controls.MapViewInputEventArgs e)
        {
            try
            {
                var graphicIdx = _stopsGraphicsOverlay.Graphics.Count + 1;
                _stopsGraphicsOverlay.Graphics.Add(CreateStopGraphic(e.Location, graphicIdx));

                if (graphicIdx > 1)
                {
                    await CalculateRouteAsync();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Sample Error");
            }
        }

        private async void chkOnline_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _routeGraphicsOverlay.Graphics.Clear();
                _stopsGraphicsOverlay.Graphics.Clear();
                panelRouteInfo.Visibility = Visibility.Collapsed;

                if (((CheckBox)sender).IsChecked == true)
                    _routeTask = await Task.Run<RouteTask>(() => new OnlineRouteTask(new Uri(OnlineRoutingService)));
                else
                    _routeTask = await Task.Run<RouteTask>(() => new LocalRouteTask(LocalRoutingDatabase, LocalNetworkName));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Sample Error");
            }
        }

        private void ClearButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _routeGraphicsOverlay.Graphics.Clear();
                _stopsGraphicsOverlay.Graphics.Clear();
                panelRouteInfo.Visibility = Visibility.Collapsed;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Sample Error");
            }
        }

        private Graphic CreateStopGraphic(MapPoint location, int id)
        {
            var symbol = new CompositeSymbol();
            symbol.Symbols.Add(new SimpleMarkerSymbol() { Style = SimpleMarkerStyle.Circle, Color = Colors.Blue, Size = 16 });
            symbol.Symbols.Add(new TextSymbol()
            {
                Text = id.ToString(),
                Color = Colors.White,
                VerticalTextAlignment = VerticalTextAlignment.Middle,
                HorizontalTextAlignment = HorizontalTextAlignment.Center,
                YOffset = -1
            });

            var graphic = new Graphic()
            {
                Geometry = location,
                Symbol = symbol
            };

            return graphic;
        }

        private async Task CalculateRouteAsync()
        {
            try
            {
                progress.Visibility = Visibility.Visible;

                RouteParameters routeParams = await _routeTask.GetDefaultParametersAsync();

                routeParams.OutSpatialReference = MyMapView.SpatialReference;
                routeParams.ReturnDirections = false;

                routeParams.SetStops(_stopsGraphicsOverlay.Graphics);

                RouteResult routeResult = await _routeTask.SolveAsync(routeParams);

                if (routeResult.Routes.Count > 0)
                {
                    _routeGraphicsOverlay.Graphics.Clear();

                    var route = routeResult.Routes.First().RouteFeature;
                    _routeGraphicsOverlay.Graphics.Add(new Graphic(route.Geometry));

                    var meters = GeometryEngine.GeodesicLength(route.Geometry, GeodeticCurveType.Geodesic);
                    txtDistance.Text = string.Format("{0:0.00} miles", LinearUnits.Miles.ConvertFromMeters(meters));

                    panelRouteInfo.Visibility = Visibility.Visible;
                }
            }
            catch (AggregateException ex)
            {
                var innermostExceptions = ex.Flatten().InnerExceptions;
                if (innermostExceptions != null && innermostExceptions.Count > 0)
                    MessageBox.Show(innermostExceptions[0].Message);
                else
                    MessageBox.Show(ex.Message);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }
            finally
            {
                progress.Visibility = Visibility.Collapsed;
            }
        }
    }
}
Feedback on this topic?