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
Open the JavaScript Starter App on CodePen.
In CodePen, click Fork and save the pen as
ArcGIS JavaScript Tutorials: Get a route and directions
.
Change the basemap and position
In the main
function
, update the existing code to use thestreets-navigation-vector
basemap. Set thezoom
level to12
, and thecenter
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
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) {
At the end of the code in the main
function
, create aRouteTask
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.
In the main
function
, create aclick
handler and aaddGraphic
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 thegetRoute
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); }
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.
Write a new
getRoute
function to create the RouteParameters and pass in the stops graphics collected eariler. Also setreturnDirections
totrue
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); }); }); }
Update the
click
handler code to call thegetRoute
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); }
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.
Go to the Set up authenticated services tutorial and create a proxy to access the ArcGIS World Routing Service and Directions Service.
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" });
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");
});
}