Overview

You will learn: how to build an app to find the optimal route and directions for multiple stops with the ArcGIS Route service.

Applications can use the ArcGIS Routing and Network Analytics Services to find routes, get driving directions, calculate drive times, and solve complicated multiple vehicle routing problems. To create an application that can access the service directly to find driving directions and create an optimized route, you can use ArcGIS World Routing Service and the RouteTask class. To create a route, you provide stop locations, and optionally barriers and the mode of transportation, and the service will return a route with directions. Once you have the results you can add the route to a map, display turn-by-turn directions, or integrate them further into your application. The ArcGIS World Routing Service is a premium service and requires requests to be authenticated. To access the service without signing in, visit the Set up authenticated services tutorial. To learn more about the capabilities of the underlying service, visit the REST documentation.

In this tutorial, you will learn how to use the RouteTask and the ArcGIS World Routing Service to calculate an optimal route between two places. The start and finish points will be created by clicking on the map.

Click on the map twice to create a route.

Steps

Create a starter app

  1. Open the JavaScript Starter App on CodePen.

  2. In CodePen, click Fork and save the pen as ArcGIS JavaScript Tutorials: Get a route and directions.

Change the basemap and position

  1. In the main function, update the existing code to use the streets-navigation-vector basemap. Set the zoom level to 12, and the center to [-118.24532,34.05398] (Los Angeles).

          var map = new Map({
            //*** UPDATE ***//
            basemap: "streets-navigation-vector"
          });
    
          var view = new MapView({
            container: "viewDiv",
            map: map,
            //*** UPDATE ***//
            center: [-118.24532,34.05398],
            zoom: 12
          });
    

Create the route task

  1. In the require statement, add the RouteTask, RouteParameters, FeatureSet and Graphic modules.

        require([
          "esri/Map",
          "esri/views/MapView",
          "esri/tasks/RouteTask",
          "esri/tasks/support/RouteParameters",
          "esri/tasks/support/FeatureSet",
          "esri/Graphic"
        ], function(Map, MapView, RouteTask, RouteParameters, FeatureSet, Graphic) {
    
  2. At the end of the code in the main function, create a RouteTask and reference the ArcGIS World Routing Service.

          var routeTask = new RouteTask({
             url: "https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World"
          });
    

Get a start and finish point

Before you can execute the route task you need to assemble the input parameters. There are a number of parameters you can provide such as stops, barriers and the preferred order, but at a minimum you need to provide the start and finish location.

  1. In the main function, create a click handler and a addGraphic function to add graphics when the view is clicked. Create a simple white marker for the start and a black marker for the finish location. After two graphics have been created, call the getRoute function to execute the route task. This will be completed in the next step.

          view.on("click", function(event){
            if (view.graphics.length === 0) {
              addGraphic("start", event.mapPoint);
            } else if (view.graphics.length === 1) {
              addGraphic("finish", event.mapPoint);
            } else {
              view.graphics.removeAll();
              addGraphic("start",event.mapPoint);
            }
          });
    
          function addGraphic(type, point) {
            var graphic = new Graphic({
              symbol: {
                type: "simple-marker",
                color: (type === "start") ? "white" : "black",
                size: "8px"
              },
              geometry: point
            });
            view.graphics.add(graphic);
          }
    
  2. Run the app and click on two locations to ensure the graphics are created.

Execute the route task

The last step is to call the service and add the route to the map.

  1. Write a new getRoute function to create the RouteParameters and pass in the stops graphics collected eariler. Also set returnDirections to true to ensure the text directions are returned as well (see challenge). Call the solve method and when the task returns, extract the route from the RouteResult and add the route to the map with a blue symbol.

          function getRoute() {
            // Setup the route parameters
            var routeParams = new RouteParameters({
              stops: new FeatureSet({
                features: view.graphics.toArray() // Pass the array of graphics
              }),
              returnDirections: true
            });
            // Get the route
            routeTask.solve(routeParams).then(function(data) {
              // Display the route
              data.routeResults.forEach(function(result) {
                result.route.symbol = {
                  type: "simple-line",
                  color: [5, 150, 255],
                  width: 3
                };
                view.graphics.add(result.route);
              });
            });
          }
    
  2. Update the click handler code to call the getRoute function when the second graphic (finish) is passed in.

          view.on("click", function(event){
            if (view.graphics.length === 0) {
              addGraphic("start", event.mapPoint);
            } else if (view.graphics.length === 1) {
              addGraphic("finish", event.mapPoint);
              //*** ADD ***//
              getRoute();
            } else {
              view.graphics.removeAll();
              addGraphic("start",event.mapPoint);
            }
          });
    
          function addGraphic(type, point) {
            var graphic = new Graphic({
              symbol: {
                type: "simple-marker",
                color: (type === "start") ? "white" : "black",
                size: "8px"
              },
              geometry: point
            });
            view.graphics.add(graphic);
          }
    
  3. Run the app and click on two locations to generate a route.

NOTE: If you would like to prevent the authentication dialog from appearing, try the challenge step below.

Congratulations, you're done!

Your app should look something like this.

Challenge

Prevent the authentication dialog from appearing

If you want to access the ArcGIS World Routing Service directly and prevent the application from prompting the user for authentication, you can use a service proxy.

  1. Go to the Set up authenticated services tutorial and create a proxy to access the ArcGIS World Routing Service and Directions Service.

  2. In the dashboard , copy the Routing and Directions proxy URL and update the application code.

         var routeTask = new RouteTask({
           //*** ADD ***//
           url: "https://utility.arcgis.com/usrsvcs/appservices/<your-id>/rest/services/World/Route/NAServer/Route_World/solve"
         });
    
  3. Run the application again and it shouldn't prompt the user to sign in.

Show the directions

Display the directions for the route by adding the turn-by-turn directions and distance in miles to the map after the route draws.

NOTE: This is a just simple implementation to get you started, but if you want to see a more interactive application that has interactive route segments, directions and arrows, try the Driving directions tutorial.

      function getRoute() {
        // Setup the route parameters
        var routeParams = new RouteParameters({
          stops: new FeatureSet({
            features: view.graphics.toArray() // Pass the array of graphics
          }),
          returnDirections: true
        });
        // Get the route
        routeTask.solve(routeParams).then(function(data) {
          // Display the route
          data.routeResults.forEach(function(result) {
            result.route.symbol = {
              type: "simple-line",
              color: [5, 150, 255],
              width: 3
            };
            view.graphics.add(result.route);
          });

          //*** ADD ***//

          // Display the directions
          var directions = document.createElement("ol");
          directions.classList = "esri-widget esri-widget--panel esri-directions__scroller";
          directions.style.marginTop = 0;
          directions.style.paddingTop = "15px";

          // Show the directions
          var features = data.routeResults[0].directions.features;
          features.forEach(function(result,i){
            var direction = document.createElement("li");
            direction.innerHTML = result.attributes.text + " (" + result.attributes.length.toFixed(2) + " miles)";
            directions.appendChild(direction);
          });

          // Add directions to the view
          view.ui.empty("top-right");
          view.ui.add(directions, "top-right");
        });
      }
Content