Learn how to find a route and directions with the route service A routing service is a service that uses network analysis and streets data to calculate the most effective path and turn-by-turn directions on a street network, optimize fleet routing and deliveries, find the closest facilities, calculate service areas, and more. It is hosted by Esri as the ArcGIS Routing service and can also be hosted in ArcGIS Enterprise. Learn more .

find a route and directions

Routing is the process of finding the path from an origin An origin is a point that defines the start of a route. Learn more to a destination A destination is a point that defines the final stop in a route. Learn more in a street network. You can use the Routing service A routing service is a service that uses network analysis and streets data to calculate the most effective path and turn-by-turn directions on a street network, optimize fleet routing and deliveries, find the closest facilities, calculate service areas, and more. It is hosted by Esri as the ArcGIS Routing service and can also be hosted in ArcGIS Enterprise. Learn more to find routes A route is a polyline that defines the best path between two or more points in a street network. Learn more , get driving directions, calculate drive times, and solve complicated, multiple vehicle routing problems. To create a route, you typically define a set of stops (origin and one or more destinations) and use the service to find a route with directions. You can also use a number of additional parameters such as barriers and mode of travel to refine the results.

In this tutorial, you define an origin and destination by clicking on the map. These values are used to get a route and directions from the route service. The directions are also displayed on the map.

Prerequisites

Before starting this tutorial:

  1. You need an ArcGIS Location Platform or ArcGIS Online account.

  2. Confirm that your system meets the minimum system requirements.

  3. An IDE for Java.

Steps

Get an access token

You need an access token An access token is an authorization string that provides access to secure ArcGIS content, data, and services. Its capabilities are determined by the privileges it supports. It is obtained by implementing API key authentication, User authentication, or App authentication. Learn more to use the location services ArcGIS Location Services, also referred to as Location Services, are services hosted by Esri that provide geospatial functionality for developing mapping applications. They include the ArcGIS Basemap Styles service, ArcGIS Static Basemap Tiles service, ArcGIS Places service, ArcGIS Geocoding service, ArcGIS Routing service, ArcGIS GeoEnrichment service, and ArcGIS Elevation service. An ArcGIS Location Platform or ArcGIS Online account is required to use the services. Learn more used in this tutorial.

  1. Go to the Create an API key tutorial to obtain an access token An access token is an authorization string that provides access to secure ArcGIS content, data, and services. Its capabilities are determined by the privileges it supports. It is obtained by implementing API key authentication, User authentication, or App authentication. Learn more using your ArcGIS Location Platform An ArcGIS Location Platform account, formerly known as an ArcGIS Developer account, is an identity associated with an ArcGIS Location Platform subscription. Learn more or ArcGIS Online An ArcGIS Online account, also known as an ArcGIS Organization account, is an identity associated with an ArcGIS Online subscription. It can be used to access ArcGIS tools and develop applications with ArcGIS location services for an organization. Learn more account.

  2. Ensure that the following privileges Privileges are a set of permissions assigned to ArcGIS accounts, developer credentials, and applications that grant access to secure resources and functionality in ArcGIS. Learn more are enabled: Location services > Basemaps > Basemap styles service and Location services > Routing.

  3. Copy the access token as it will be used in the next step.

To learn more about other ways to get an access token, go to Types of authentication.

Open a Java project with Gradle

  1. To start this tutorial, complete the Display a map tutorial, or download and unzip the Display a map solution into a new folder.

  2. Open the build.gradle file as a project in IntelliJ IDEA.

  3. In IntelliJ IDEA’s Project tool window, open src/main/java/com.example.app and double-click App.

  4. In the start() method, set the API key property on the ArcGISRuntimeEnvironment with your access token An access token is an authorization string that provides access to secure ArcGIS content, data, and services. Its capabilities are determined by the privileges it supports. It is obtained by implementing API key authentication, User authentication, or App authentication. Learn more . Replace YOUR_ACCESS_TOKEN with your copied access token. Be sure to surround your access token with double quotes as it is a string.

    App.java
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");

Add import statements and variable declarations

Add import statements and variable declarations to reference the packages and classes required for this tutorial.

  1. In IntelliJ IDEA’s Project tool window, open src/main/java/com.example.app and double-click App.

  2. Add the following imports above the existing imports:

    App.java
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
  3. Within the App class, add the following member variables to easily reference them from other parts of the application:

    App.java
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();

Update the map

A streets basemap layer A basemap layer is the layer in a map or scene that displays basemap data. The data source for a basemap layer is typically a basemap service. Learn more is typically used in routing applications. Update the basemap to use the ARCGIS_STREETS basemap style, and change the position of the map to center on Los Angeles.

  1. Update the BasemapStyle from ARCGIS_TOPOGRAPHIC to ARCGIS_STREETS.

  2. Update the latitude and longitude coordinates to center on Los Angeles.

    App.java
    81 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    14 collapsed lines
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }

Add a UI to display driving directions

To display the turn-by-turn directions from the route, a UI element is required.

  1. In the start() method, set the maximum size of the directionsList (a JavaFX ListView which will display a vertical list of directions), and then add it to the stackPane.

    App.java
    85 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    14 collapsed lines
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }

Add a graphics overlay

A graphics overlay A graphics overlay is a client-side, temporary container of graphics to display on a map view or scene view. Learn more is a container for graphics A graphic is a visual element composed of a geometry, symbol, and attributes that is displayed on a map or scene. Learn more . Graphics will be added later in this tutorial as a visual means to display the route stops and route result on the map A map is a collection of layers that are displayed in 2D. It is typically composed of a basemap layer and data layers. Learn more .

  1. Create a new GraphicsOverlay and add it to the mapView.

    App.java
    92 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mapView.getGraphicsOverlays().add(graphicsOverlay);
    14 collapsed lines
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }

Create a route task and route parameters

A task makes a request to a service A service, also known as an ArcGIS service, is software that supports an ArcGIS REST API and provides geospatial functionality or data. A service can be hosted by Esri or in ArcGIS Enterprise. Learn more and returns the results. Use the RouteTask class to access a routing service A routing service is a service that uses network analysis and streets data to calculate the most effective path and turn-by-turn directions on a street network, optimize fleet routing and deliveries, find the closest facilities, calculate service areas, and more. It is hosted by Esri as the ArcGIS Routing service and can also be hosted in ArcGIS Enterprise. Learn more . A routing service with global coverage is part of ArcGIS location services. You can also publish custom routing services using ArcGIS Enterprise.

  1. Create a RouteTask(java.lang.String) with a string URL to reference the routing service.

    App.java
    96 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mapView.getGraphicsOverlays().add(graphicsOverlay);
    routeTask = new RouteTask("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World");
    13 collapsed lines
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }
  2. Get default RouteParameters objects from the routeTask and set the return directions property to true. This specifies that the route results should include turn-by-turn directions. Add a UI text prompt.

    App.java
    99 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mapView.getGraphicsOverlays().add(graphicsOverlay);
    routeTask = new RouteTask("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World");
    ListenableFuture<RouteParameters> routeParametersFuture = routeTask.createDefaultParametersAsync();
    routeParametersFuture.addDoneListener(() -> {
    try {
    routeParameters = routeParametersFuture.get();
    routeParameters.setReturnDirections(true);
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    } catch (Exception e) {
    Alert alert = new Alert(Alert.AlertType.ERROR, e.toString());
    alert.show();
    e.printStackTrace();
    }
    });
    14 collapsed lines
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }

Create origin and destination stops

A RouteTask requires at least a single origin An origin is a point that defines the start of a route. Learn more and destination A destination is a point that defines the final stop in a route. Learn more stop to find a route A route is a polyline that defines the best path between two or more points in a street network. Learn more . Use a click handler on the mapView to add stops and display them as graphics when the map is clicked.

  1. Create a new addStopsOnMouseClicked() method which adds a setOnMouseClicked() listener to the mapView. Convert the clicked JavaFX Point2D to a location Point. Use the point to create a new Stop and add it to the routeStops list.

    App.java
    115 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mapView.getGraphicsOverlays().add(graphicsOverlay);
    routeTask = new RouteTask("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World");
    ListenableFuture<RouteParameters> routeParametersFuture = routeTask.createDefaultParametersAsync();
    routeParametersFuture.addDoneListener(() -> {
    try {
    routeParameters = routeParametersFuture.get();
    routeParameters.setReturnDirections(true);
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    } catch (Exception e) {
    Alert alert = new Alert(Alert.AlertType.ERROR, e.toString());
    alert.show();
    e.printStackTrace();
    }
    });
    }
    private void addStopsOnMouseClicked() {
    mapView.setOnMouseClicked(event -> {
    if (event.isStillSincePress() && event.getButton() == MouseButton.PRIMARY) {
    Point2D mapPoint = new Point2D(event.getX(), event.getY());
    routeStops.add(new Stop(mapView.screenToLocation(mapPoint)));
    }
    });
    }
    12 collapsed lines
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }
  2. Call addStopsOnMouseClicked() in the start() method.

    App.java
    108 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mapView.getGraphicsOverlays().add(graphicsOverlay);
    routeTask = new RouteTask("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World");
    ListenableFuture<RouteParameters> routeParametersFuture = routeTask.createDefaultParametersAsync();
    routeParametersFuture.addDoneListener(() -> {
    try {
    routeParameters = routeParametersFuture.get();
    routeParameters.setReturnDirections(true);
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    } catch (Exception e) {
    Alert alert = new Alert(Alert.AlertType.ERROR, e.toString());
    alert.show();
    e.printStackTrace();
    }
    });
    addStopsOnMouseClicked();
    23 collapsed lines
    }
    private void addStopsOnMouseClicked() {
    mapView.setOnMouseClicked(event -> {
    if (event.isStillSincePress() && event.getButton() == MouseButton.PRIMARY) {
    Point2D mapPoint = new Point2D(event.getX(), event.getY());
    routeStops.add(new Stop(mapView.screenToLocation(mapPoint)));
    }
    });
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }
  3. To display the stops on the map as they are added, add a listener to the routeStops ObservableList and create a new SimpleMarkerSymbol for each Stop. Use the stop’s geometry to create a new Graphic and add it to the graphicsOverlay.

    App.java
    115 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mapView.getGraphicsOverlays().add(graphicsOverlay);
    routeTask = new RouteTask("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World");
    ListenableFuture<RouteParameters> routeParametersFuture = routeTask.createDefaultParametersAsync();
    routeParametersFuture.addDoneListener(() -> {
    try {
    routeParameters = routeParametersFuture.get();
    routeParameters.setReturnDirections(true);
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    } catch (Exception e) {
    Alert alert = new Alert(Alert.AlertType.ERROR, e.toString());
    alert.show();
    e.printStackTrace();
    }
    });
    addStopsOnMouseClicked();
    routeStops.addListener((ListChangeListener<Stop>) e -> {
    // tracks the number of stops added to the map, and use it to create graphic geometry and symbol text
    int routeStopsSize = routeStops.size();
    // handle user interaction
    if (routeStopsSize == 0) {
    return;
    } else if (routeStopsSize == 1) {
    graphicsOverlay.getGraphics().clear();
    if (!directionsList.getItems().isEmpty())
    directionsList.getItems().clear();
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    }
    // create a blue circle symbol for the stop
    SimpleMarkerSymbol stopMarker = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.BLUE, 20);
    // get the stop's geometry
    Geometry routeStopGeometry = routeStops.get(routeStopsSize-1).getGeometry();
    graphicsOverlay.getGraphics().add(new Graphic(routeStopGeometry, stopMarker));
    });
    23 collapsed lines
    }
    private void addStopsOnMouseClicked() {
    mapView.setOnMouseClicked(event -> {
    if (event.isStillSincePress() && event.getButton() == MouseButton.PRIMARY) {
    Point2D mapPoint = new Point2D(event.getX(), event.getY());
    routeStops.add(new Stop(mapView.screenToLocation(mapPoint)));
    }
    });
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }

Find and display the route

To find the route A route is a polyline that defines the best path between two or more points in a street network. Learn more between the origin An origin is a point that defines the start of a route. Learn more and destination A destination is a point that defines the final stop in a route. Learn more , set the stops A stop is a single point along a route: it can be the origin, an intermediate stop, or destination. Learn more on the route parameters and solve the route using the RouteTask. Display the route result on the map as a graphic.

  1. When an origin and destination stop have been created, set them on the routeParameters.

    App.java
    134 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mapView.getGraphicsOverlays().add(graphicsOverlay);
    routeTask = new RouteTask("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World");
    ListenableFuture<RouteParameters> routeParametersFuture = routeTask.createDefaultParametersAsync();
    routeParametersFuture.addDoneListener(() -> {
    try {
    routeParameters = routeParametersFuture.get();
    routeParameters.setReturnDirections(true);
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    } catch (Exception e) {
    Alert alert = new Alert(Alert.AlertType.ERROR, e.toString());
    alert.show();
    e.printStackTrace();
    }
    });
    addStopsOnMouseClicked();
    routeStops.addListener((ListChangeListener<Stop>) e -> {
    // tracks the number of stops added to the map, and use it to create graphic geometry and symbol text
    int routeStopsSize = routeStops.size();
    // handle user interaction
    if (routeStopsSize == 0) {
    return;
    } else if (routeStopsSize == 1) {
    graphicsOverlay.getGraphics().clear();
    if (!directionsList.getItems().isEmpty())
    directionsList.getItems().clear();
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    }
    // create a blue circle symbol for the stop
    SimpleMarkerSymbol stopMarker = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.BLUE, 20);
    // get the stop's geometry
    Geometry routeStopGeometry = routeStops.get(routeStopsSize-1).getGeometry();
    graphicsOverlay.getGraphics().add(new Graphic(routeStopGeometry, stopMarker));
    if (routeStopsSize == 2) {
    // remove the mouse clicked event if two stops have been added
    mapView.setOnMouseClicked(null);
    routeParameters.setStops(routeStops);
    }
    25 collapsed lines
    });
    }
    private void addStopsOnMouseClicked() {
    mapView.setOnMouseClicked(event -> {
    if (event.isStillSincePress() && event.getButton() == MouseButton.PRIMARY) {
    Point2D mapPoint = new Point2D(event.getX(), event.getY());
    routeStops.add(new Stop(mapView.screenToLocation(mapPoint)));
    }
    });
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }
  2. Solve (find) the route based on the provided route parameters to obtain a RouteResult. The result is a collection of computed routes. Then, get the list of Route objects from the result. Each element represents an independent route with its own driving directions. The routing service only returns the optimal route.

    App.java
    136 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mapView.getGraphicsOverlays().add(graphicsOverlay);
    routeTask = new RouteTask("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World");
    ListenableFuture<RouteParameters> routeParametersFuture = routeTask.createDefaultParametersAsync();
    routeParametersFuture.addDoneListener(() -> {
    try {
    routeParameters = routeParametersFuture.get();
    routeParameters.setReturnDirections(true);
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    } catch (Exception e) {
    Alert alert = new Alert(Alert.AlertType.ERROR, e.toString());
    alert.show();
    e.printStackTrace();
    }
    });
    addStopsOnMouseClicked();
    routeStops.addListener((ListChangeListener<Stop>) e -> {
    // tracks the number of stops added to the map, and use it to create graphic geometry and symbol text
    int routeStopsSize = routeStops.size();
    // handle user interaction
    if (routeStopsSize == 0) {
    return;
    } else if (routeStopsSize == 1) {
    graphicsOverlay.getGraphics().clear();
    if (!directionsList.getItems().isEmpty())
    directionsList.getItems().clear();
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    }
    // create a blue circle symbol for the stop
    SimpleMarkerSymbol stopMarker = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.BLUE, 20);
    // get the stop's geometry
    Geometry routeStopGeometry = routeStops.get(routeStopsSize-1).getGeometry();
    graphicsOverlay.getGraphics().add(new Graphic(routeStopGeometry, stopMarker));
    if (routeStopsSize == 2) {
    // remove the mouse clicked event if two stops have been added
    mapView.setOnMouseClicked(null);
    routeParameters.setStops(routeStops);
    // get the route and display it
    ListenableFuture<RouteResult> routeResultFuture = routeTask.solveRouteAsync(routeParameters);
    routeResultFuture.addDoneListener(() -> {
    try {
    RouteResult result = routeResultFuture.get();
    List<Route> routes = result.getRoutes();
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    });
    }
    25 collapsed lines
    });
    }
    private void addStopsOnMouseClicked() {
    mapView.setOnMouseClicked(event -> {
    if (event.isStillSincePress() && event.getButton() == MouseButton.PRIMARY) {
    Point2D mapPoint = new Point2D(event.getX(), event.getY());
    routeStops.add(new Stop(mapView.screenToLocation(mapPoint)));
    }
    });
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }
  3. Check that a route was returned, and retrieve the first one. Display this route to the map by creating a new Graphic using the route’s Geometry and a SimpleLineSymbol, and add it to the graphicsOverlay.

    App.java
    141 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mapView.getGraphicsOverlays().add(graphicsOverlay);
    routeTask = new RouteTask("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World");
    ListenableFuture<RouteParameters> routeParametersFuture = routeTask.createDefaultParametersAsync();
    routeParametersFuture.addDoneListener(() -> {
    try {
    routeParameters = routeParametersFuture.get();
    routeParameters.setReturnDirections(true);
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    } catch (Exception e) {
    Alert alert = new Alert(Alert.AlertType.ERROR, e.toString());
    alert.show();
    e.printStackTrace();
    }
    });
    addStopsOnMouseClicked();
    routeStops.addListener((ListChangeListener<Stop>) e -> {
    // tracks the number of stops added to the map, and use it to create graphic geometry and symbol text
    int routeStopsSize = routeStops.size();
    // handle user interaction
    if (routeStopsSize == 0) {
    return;
    } else if (routeStopsSize == 1) {
    graphicsOverlay.getGraphics().clear();
    if (!directionsList.getItems().isEmpty())
    directionsList.getItems().clear();
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    }
    // create a blue circle symbol for the stop
    SimpleMarkerSymbol stopMarker = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.BLUE, 20);
    // get the stop's geometry
    Geometry routeStopGeometry = routeStops.get(routeStopsSize-1).getGeometry();
    graphicsOverlay.getGraphics().add(new Graphic(routeStopGeometry, stopMarker));
    if (routeStopsSize == 2) {
    // remove the mouse clicked event if two stops have been added
    mapView.setOnMouseClicked(null);
    routeParameters.setStops(routeStops);
    // get the route and display it
    ListenableFuture<RouteResult> routeResultFuture = routeTask.solveRouteAsync(routeParameters);
    routeResultFuture.addDoneListener(() -> {
    try {
    RouteResult result = routeResultFuture.get();
    List<Route> routes = result.getRoutes();
    if (!routes.isEmpty()) {
    Route route = routes.get(0);
    Geometry shape = route.getRouteGeometry();
    routeGraphic = new Graphic(shape, new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLUE, 2));
    graphicsOverlay.getGraphics().add(routeGraphic);
    }
    32 collapsed lines
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    });
    }
    });
    }
    private void addStopsOnMouseClicked() {
    mapView.setOnMouseClicked(event -> {
    if (event.isStillSincePress() && event.getButton() == MouseButton.PRIMARY) {
    Point2D mapPoint = new Point2D(event.getX(), event.getY());
    routeStops.add(new Stop(mapView.screenToLocation(mapPoint)));
    }
    });
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }

Get directions

You can get driving directions from the route service A routing service is a service that uses network analysis and streets data to calculate the most effective path and turn-by-turn directions on a street network, optimize fleet routing and deliveries, find the closest facilities, calculate service areas, and more. It is hosted by Esri as the ArcGIS Routing service and can also be hosted in ArcGIS Enterprise. Learn more with the setReturnDirections() method on RouteParameters. This property was set to true in the Create a route task and route parameters section of this tutorial.

  1. To display the driving directions, get each DirectionManeuver from the route, and add them to the directionsList.

    App.java
    148 collapsed lines
    // Copyright 2020 Esri
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    // http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    package com.example.app;
    import com.esri.arcgisruntime.concurrent.ListenableFuture;
    import com.esri.arcgisruntime.geometry.Geometry;
    import com.esri.arcgisruntime.mapping.view.Graphic;
    import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
    import com.esri.arcgisruntime.tasks.networkanalysis.Route;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
    import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
    import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.geometry.Point2D;
    import javafx.geometry.Pos;
    import javafx.scene.paint.Color;
    import javafx.scene.control.Alert;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseButton;
    import java.util.List;
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    public class App extends Application {
    private MapView mapView;
    private Graphic routeGraphic;
    private RouteTask routeTask;
    private RouteParameters routeParameters;
    private final ObservableList<Stop> routeStops = FXCollections.observableArrayList();
    private final ListView<String> directionsList = new ListView<>();
    public static void main(String[] args) {
    Application.launch(args);
    }
    @Override
    public void start(Stage stage) {
    // set the title and size of the stage and show it
    stage.setTitle("Find a route and directions tutorial");
    stage.setWidth(800);
    stage.setHeight(700);
    stage.show();
    // create a JavaFX scene with a stack pane as the root node
    // and add it to the scene
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);
    stage.setScene(scene);
    ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN");
    // create a MapView to display the map and add it to the stack pane
    mapView = new MapView();
    stackPane.getChildren().add(mapView);
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
    // set the map on the map view
    mapView.setMap(map);
    mapView.setViewpoint(new Viewpoint(34.05398, -118.24532, 144447.638572));
    directionsList.setMaxSize(400, 250);
    stackPane.getChildren().add(directionsList);
    StackPane.setAlignment(directionsList, Pos.TOP_LEFT);
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mapView.getGraphicsOverlays().add(graphicsOverlay);
    routeTask = new RouteTask("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World");
    ListenableFuture<RouteParameters> routeParametersFuture = routeTask.createDefaultParametersAsync();
    routeParametersFuture.addDoneListener(() -> {
    try {
    routeParameters = routeParametersFuture.get();
    routeParameters.setReturnDirections(true);
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    } catch (Exception e) {
    Alert alert = new Alert(Alert.AlertType.ERROR, e.toString());
    alert.show();
    e.printStackTrace();
    }
    });
    addStopsOnMouseClicked();
    routeStops.addListener((ListChangeListener<Stop>) e -> {
    // tracks the number of stops added to the map, and use it to create graphic geometry and symbol text
    int routeStopsSize = routeStops.size();
    // handle user interaction
    if (routeStopsSize == 0) {
    return;
    } else if (routeStopsSize == 1) {
    graphicsOverlay.getGraphics().clear();
    if (!directionsList.getItems().isEmpty())
    directionsList.getItems().clear();
    directionsList.getItems().add("Click to add two points to the map to find a route.");
    }
    // create a blue circle symbol for the stop
    SimpleMarkerSymbol stopMarker = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.BLUE, 20);
    // get the stop's geometry
    Geometry routeStopGeometry = routeStops.get(routeStopsSize-1).getGeometry();
    graphicsOverlay.getGraphics().add(new Graphic(routeStopGeometry, stopMarker));
    if (routeStopsSize == 2) {
    // remove the mouse clicked event if two stops have been added
    mapView.setOnMouseClicked(null);
    routeParameters.setStops(routeStops);
    // get the route and display it
    ListenableFuture<RouteResult> routeResultFuture = routeTask.solveRouteAsync(routeParameters);
    routeResultFuture.addDoneListener(() -> {
    try {
    RouteResult result = routeResultFuture.get();
    List<Route> routes = result.getRoutes();
    if (!routes.isEmpty()) {
    Route route = routes.get(0);
    Geometry shape = route.getRouteGeometry();
    routeGraphic = new Graphic(shape, new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLUE, 2));
    graphicsOverlay.getGraphics().add(routeGraphic);
    // get the direction text for each maneuver and display it as a list in the UI
    route.getDirectionManeuvers().forEach(step -> directionsList.getItems().add(step.getDirectionText()));
    // reset stops and re-enable mapview interactions once the route task has completed
    routeStops.clear();
    addStopsOnMouseClicked();
    34 collapsed lines
    }
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    });
    }
    });
    }
    private void addStopsOnMouseClicked() {
    mapView.setOnMouseClicked(event -> {
    if (event.isStillSincePress() && event.getButton() == MouseButton.PRIMARY) {
    Point2D mapPoint = new Point2D(event.getX(), event.getY());
    routeStops.add(new Stop(mapView.screenToLocation(mapPoint)));
    }
    });
    }
    /**
    * Stops and releases all resources used in application.
    */
    @Override
    public void stop() {
    if (mapView != null) {
    mapView.dispose();
    }
    }
    }
  2. Run the app. Ensure to run the app as a Gradle task and not as an application in your IDE. In the Gradle tool window, under Tasks > application, double-click run.

The map should support two clicks to create an origin and destination point and then use the route service A routing service is a service that uses network analysis and streets data to calculate the most effective path and turn-by-turn directions on a street network, optimize fleet routing and deliveries, find the closest facilities, calculate service areas, and more. It is hosted by Esri as the ArcGIS Routing service and can also be hosted in ArcGIS Enterprise. Learn more to display the resulting route and turn-by-turn directions.

What’s next?

Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials: