Click or drag to resize
Code Example - RoutingWithDirections

Interaction logic for RoutingWithDirections.xaml

Code Example
Routing With Directions

This section contains selected code files from a Visual Studio project that emphasize specific ArcGIS Runtime SDK (Windows Desktop) features. For example: some code examples may accomplish the bulk of the work as a configuration property in the .xaml file and hence only the .xaml file will be shown in detail below. In other code examples, the .xaml is used to define the configuration of graphical elements for the application but the application logic is performed in the code behind, hence you may see both the .xaml and .cs/.vb files shown in detail below.

XAML
<Window x:Class="RoutingWithDirections.MainWindow"
             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>

        <esri:MapView x:Name="MapView1">
            <esri:Map x:Name="MyMap">
                <esri:ArcGISTiledMapServiceLayer
            ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />
            </esri:Map>
        </esri:MapView>

        <Border HorizontalAlignment="Right" VerticalAlignment="Top" Margin="10" Padding="5" Background="White" 
                BorderBrush="Black" BorderThickness="1">
            <Border.Effect>
                <DropShadowEffect />
            </Border.Effect>
            <StackPanel Orientation="Vertical">
                <TextBlock Text="Click the button then define two locations on the Map to calculate a simple route."></TextBlock>
                <Button Content="Add Start / End Locations" IsEnabled="{Binding Path=IsMapReady}" x:Name="SolveRouteButton" Margin="5" Click="SolveRouteButton_Click"
                        HorizontalAlignment="Center" Width="150" Height="25" />
                <StackPanel Orientation="Horizontal">
                    <TextBlock Margin="5" Width="50" Text="Start:"></TextBlock>
                    <TextBox x:Name="StartLocationTextBox" Margin="5" Width="250" Text="{Binding Path=StartLocationText}" />
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Margin="5" Width="50" Text="End:"></TextBlock>
                    <TextBox x:Name="EndLocationTextBox" Margin="5" Width="250" Text="{Binding Path=EndLocationText}" />
                </StackPanel>

                <TextBlock x:Name="DirectionsText" Text="Directions:" FontWeight="Bold" TextWrapping="Wrap"  Margin="5,5,5,0" Foreground="Black"/>
                <ScrollViewer HorizontalScrollBarVisibility="Auto" Width="400" Height="100" VerticalScrollBarVisibility="Auto" Name="Scroller">
                    <TextBlock x:Name="DirectionsResults" Text="{Binding Path=Directions}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="100" Width="{Binding ElementName=Scroller, Path=ViewportWidth}"  ></TextBlock>
                </ScrollViewer>

                <CheckBox IsChecked="{Binding Path=IsOnline, Mode=TwoWay}" Margin="10,5,5,5">Online?</CheckBox>
            </StackPanel>
        </Border>
    </Grid>
</Window>

SPECIAL NOTE: The XAML displayed above comes from a C# project. If you are a VB.NET developer, you will need to modify the text for the x:Class namespace from "RoutingWithDirections.MainWindow" to be just "MainWindow".

using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Layers;
using Esri.ArcGISRuntime.Symbology;
using Esri.ArcGISRuntime.Tasks.NetworkAnalyst;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

/// <summary>
/// Interaction logic for RoutingWithDirections.xaml
/// </summary>
namespace RoutingWithDirections
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged 
    {

        public event PropertyChangedEventHandler PropertyChanged;


        private bool _isOnline = true;

        /// <summary>
        /// Gets or sets a value indicating whether this instance is online.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is online; otherwise, <c>false</c>.
        /// </value>
        public bool IsOnline
        {
            get
            {
                return _isOnline;
            }
            set
            {
                _isOnline = value;

                var _x = SetupRouteTask();

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("IsOnline"));
                }
            }
        }



        private bool _isMapReady = false;

        /// <summary>
        /// Gets or sets a value indicating whether the map is initialized.
        /// </summary>
        /// <value>
        /// <c>true</c> if the map is initialized; otherwise, <c>false</c>.
        /// </value>
        public bool IsMapReady
        {
            get
            {
                return _isMapReady;
            }
            set
            {
                _isMapReady= value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("IsMapReady"));
                }
            }
        }


        private string _startLocationText = "";
        /// <summary>
        /// Gets or sets the start location text.
        /// </summary>
        /// <value>
        /// The start location text.
        /// </value>
        public string StartLocationText
        {
            get
            {
                return _startLocationText;
            }
            set
            {
                _startLocationText = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("StartLocationText"));
                }
            }
        }

        private string _endLocationText = "";

        /// <summary>
        /// Gets or sets the end location text.
        /// </summary>
        /// <value>
        /// The end location text.
        /// </value>
        public string EndLocationText
        {
            get
            {
                return _endLocationText;
            }
            set
            {
                _endLocationText = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("EndLocationText"));
                }
            }
        }


        private string _directions = "";

        /// <summary>
        /// Gets or sets the directions text.
        /// </summary>
        /// <value>
        /// The directions.
        /// </value>
        public string Directions
        {
            get
            {
                return _directions;
            }
            set
            {
                _directions = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Directions"));
                }
            }
        }


        GraphicsLayer _routeGraphicsLayer;
        GraphicsLayer _stopsGraphicsLayer;
        RouteTask _routeTask;
        string _onlineRoutingService = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/NAServer/Route";
          string _localRoutingDatabase = @"..\..\..\..\..\samples-data\networks\san-diego\san-diego-network.geodatabase";
        string _networkName = "Streets_ND";

        private async Task SetupRouteTask()
        {
            if (!IsOnline)
            {
                _routeTask = new LocalRouteTask(_localRoutingDatabase, _networkName);
            }
            else
            {
                _routeTask = new OnlineRouteTask(new Uri(_onlineRoutingService));
            }
        }

        public MainWindow()
        {
            InitializeComponent();

            Esri.ArcGISRuntime.Geometry.SpatialReference mySpatialReference = new Esri.ArcGISRuntime.Geometry.SpatialReference(102100);
            Esri.ArcGISRuntime.Geometry.Geometry myGeometry = new Esri.ArcGISRuntime.Geometry.Envelope(-13044000, 3855000, -13040000, 3858000, mySpatialReference);
            MapView1.Map.InitialViewpoint = new Esri.ArcGISRuntime.Controls.Viewpoint(myGeometry);

            DataContext = this;

            var _x = SetupRouteTask();

            _routeGraphicsLayer = new GraphicsLayer();
            _routeGraphicsLayer.Renderer = new SimpleRenderer()
            {
                Symbol = new SimpleLineSymbol() 
                {
                    Color = Colors.Blue,
                    Style = SimpleLineStyle.Dot,
                    Width = 2
                }
            };
            MapView1.Map.Layers.Add(_routeGraphicsLayer);

            _stopsGraphicsLayer = new GraphicsLayer();
            _stopsGraphicsLayer.Renderer = new SimpleRenderer()
            {
                Symbol = new SimpleMarkerSymbol()
                {
                    Color = Colors.Green,
                    Size = 12,
                    Style = SimpleMarkerStyle.Circle
                }
            };
            MapView1.Map.Layers.Add(_stopsGraphicsLayer);

             HandleLayersInitialized();
        }

        private async void HandleLayersInitialized()
        {
            try
            {
                await Task.WhenAll(MapView1.Map.Layers.Select(layer => layer.InitializeAsync()).ToArray());
                IsMapReady = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }

          private async Task CalculateRoute() 
          {
              StartLocationText = string.Empty;
              EndLocationText = string.Empty;
              Directions = string.Empty;
            _routeGraphicsLayer.Graphics.Clear();
            _stopsGraphicsLayer.Graphics.Clear();

            try
            {
                // Mouseclick 1:
                MapPoint startLocation = await MapView1.Editor.RequestPointAsync();    
                _stopsGraphicsLayer.Graphics.Add(new Graphic() { Geometry = startLocation }) ;

                StartLocationText = " X: " + Math.Round(startLocation.X, 0).ToString() + " Y: " + Math.Round(startLocation.Y, 0).ToString();

                // Mouseclick 2:
                MapPoint endLocation = await MapView1.Editor.RequestPointAsync();
                _stopsGraphicsLayer.Graphics.Add(new Graphic() { Geometry = endLocation});

                EndLocationText = " X: " + Math.Round(endLocation.X, 0).ToString() + " Y: " + Math.Round(endLocation.Y, 0).ToString();

                Esri.ArcGISRuntime.Tasks.NetworkAnalyst.RouteParameters routeParams = await _routeTask.GetDefaultParametersAsync();

                routeParams.OutSpatialReference = MapView1.SpatialReference;
                routeParams.ReturnDirections = true;
                routeParams.DirectionsLengthUnit = Esri.ArcGISRuntime.Geometry.LinearUnits.Kilometers;
                routeParams.DirectionsLanguage = new System.Globalization.CultureInfo("en");
                List<Graphic> graphicsStops = new List<Graphic>();


                graphicsStops.Add(new Graphic(startLocation));
                graphicsStops.Add(new Graphic(endLocation));

                // Set the stops for the Route.
                routeParams.SetStops(graphicsStops);

                RouteResult routeResult = await _routeTask.SolveAsync(routeParams);
                if (routeResult.Routes.Count > 0)
                {
                Graphic graphic = new Graphic(routeResult.Routes[0].RouteFeature.Geometry);
                _routeGraphicsLayer.Graphics.Add(graphic);

                List<string> directions = new List<string>();
                foreach (var item in routeResult.Routes[0].RouteDirections)
                {
                    directions.Add(" " + item.Text + "\r\n");
                }

                Directions = String.Join<string>(String.Empty, directions);
                }
            }
            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);
            }
        }

        private void SolveRouteButton_Click(object sender, RoutedEventArgs e)
        {
            var _x = CalculateRoute();
        }


    }
}