Find a route

Routing is the process of finding paths through a network, such as a path to get from a starting location to a destination in a transportation network. To incorporate online or offline routing functionality into your ArcGIS Runtime SDK for Java applications, use the API's RouteTask class. From version 10.2.3, you can route offline using a local network dataset. This allows for highly performant routing to be carried out without any network connectivity.

Route task

The route task is built on the advanced capabilities of the network analysis services of ArcGIS for Server and allows you to add basic and advanced routing capabilities to your geographic information system (GIS) applications. In a basic scenario, you can retrieve routes and directions between a set of input features, such as points (x, y coordinates) representing locations to visit. The route task can also take many additional parameters into account to add more advanced functionality when finding a route. For instance, an optimal route can be found where the stops are visited in the optimal order (as opposed to in the order defined); barriers can be defined that must be routed around; and impedance attributes (for example, speed limit, traffic, pipe diameter, and so on) can be taken into account.

Initialize a route task

Whether you are performing online or offline routing, you start by initializing a RouteTask object.

Online

Create an online RouteTask object by using the static method createOnlineRouteTask, passing the uniform resource locator (URL) of a network analysis service REST endpoint to the constructor. To find such a URL, you can use the ArcGIS Services Directory. See the Discovering services topic for more information. This example uses the Route layer of the ESRI_Route_NA service, which can be used without charge up to 5,000 times per year for non-commercial purposes, or by subscription for commercial purposes or for more than 5,000 annual uses. You can also publish such a service by creating a network dataset using the Network Analyst extension, then publishing that dataset to ArcGIS for Server.

RouteTask task = RouteTask.createOnlineRouteTask(
  "http://tasks.arcgisonline.com/ArcGIS/rest/services/" + 
  "NetworkAnalysis/ESRI_Route_NA/NAServer/Route",
  userCredentials); // or 'null' for an unsecured service

Offline

Create a local RouteTask object by using the static method createLocalRouteTask, passing the path to the '.geodatabase' file of your local network dataset, and the name of the network.

RouteTask task = RouteTask.createLocalRouteTask(
  "path/to/routingGdb.geodatabase",
  "Routing_Network");

Specify a route task's input parameters

The route task's execution method, solve, takes a RouteParameters object as input. At a minimum, you need to specify the Stops parameter, as this determines the locations between which a route will be calculated. Stops can be defined as a list of Graphics, a list of StopGraphics, a URL that defines a map service query that returns points, or a layer from the network analysis service's corresponding map service. You may also want to define the Barriers parameter, which defines locations that the route must avoid. This parameter is of the same type as Stops. Other commonly used boolean parameters include ReturnRoutes, which specifies whether route geometry is returned, ReturnDirections, which specifies whether directions are returned, and FindBestSequence, which determines whether to visit stops in the order specified (false) or that optimizes the route (true). When specifying optimized route calculation (FindBestSequence = true), you can exclude the first and last stops from being re-ordered by setting the PreserveFirstStop and PreserveLastStop parameters to true.

The following code sample is an example of initializing a RouteParameters object with stops from a GraphicsLayer. Properties are specified such that the route will be optimized, the first and last stops will be preserved, and the solve method will return both geometry and directions for the calculated route.

// create a graphics layer with some sample stops
final GraphicsLayer stopsGraphicsLayer = new GraphicsLayer();
map.getLayers().add(stopsGraphicsLayer);
SimpleMarkerSymbol marker = new SimpleMarkerSymbol(Color.red, 10, Style.CIRCLE);
Point startPt = new Point(-1.3043365102698399E7,3859531.610440667);
Graphic startGraphic = new Graphic(startPt, marker);
Point endPt = new Point(-1.3035912488439895E7,3856053.7237866987);
Graphic endGraphic = new Graphic(endPt, marker);
stopsGraphicsLayer.addGraphic(startGraphic);
stopsGraphicsLayer.addGraphic(endGraphic);

// create a set of stops for the route parameters
NAFeaturesAsFeature stops = new NAFeaturesAsFeature();
stops.setSpatialReference(map.getSpatialReference());
stops.addFeature(startGraphic);
stops.addFeature(endGraphic);

// create parameters
RouteParameters routeParameters = task.retrieveDefaultRouteTaskParameters();
routeParameters.setStops(stops);
routeParameters.setOutSpatialReference(map.getSpatialReference());
routeParameters.setReturnDirections(true);
routeParameters.setFindBestSequence(true);
routeParameters.setPreserveFirstStop(true);

Solve a route task and handle results

Once you've initialized a RouteParameters object with the desired input, calculating the route simply requires a call to the solve method. It is recommended that you use the solve overload method which takes a CallbackListener. This method will run the task asynchronously meaning your application is not blocked and the users can pan and zoom the map while waiting on the task's result. The route task passes its results to the onCallbackmethod, which is called whenever a route operation completes successfully. The operation's results are contained in a RoutingResults object. The route's geometry is obtained from the graphic object returned by calling getRoute() on a Route instance. The following code sample builds on the previous callback to retrieve the route, apply a symbol to it, and add it to a graphics layer:

// solve the route with an asynchronous callback 
task.solve(routeParameters, new CallbackListener<RouteResult>() {

  @Override
  public void onCallback(RouteResult result) {
    if (result != null && result.getRoutes().size() > 0) {
      // display the top route on the map as a graphic
      Route topRoute = result.getRoutes().get(0);
      Graphic routeGraphic = new Graphic(
        topRoute.getRouteGraphic().getGeometry(),
        new SimpleLineSymbol(Color.BLUE, 2.0f));
      stopsGraphicsLayer.addGraphic(routeGraphic);                          
    } else {
      System.out.println("no route found");
    }
  }

  @Override
  public void onError(Throwable e) {
    // handle the error as desired
  }
});

Directions for each Route are returned as a list of RouteDirections by calling getRoutingDirections. Each RouteDirection represents one step in the directions. The RouteDirection's geometry field is the segment of the route covered by the step, while the text, length, and time fields store the step's description, distance, and estimated travel time, respectively. The following sample code steps through the directions, retrieving and formatting the description, distance, and travel time of each.

Note:

To keep the example simple, the formatting used is very basic and null checks are omitted.

String directions = "";
Route topRoute = result.getRoutes().get(0);
// loop through each step of the directions
for (RouteDirection direction : topRoute.getRoutingDirections()){
  // get the current step's description and format it
  // (e.g. "Turn right at High Street. 3 miles. 5 minutes.")
  String length = String.format("%.2f", direction.getLength());
  String time = String.format("%.2f",  direction.getMinutes());        
  directions += direction.getText() + ". " + length 
                + " miles. " + time + " minutes.\n";
}

Sample code

Examples of using the Route, Service Area, and Closest Facility tasks can be found in the ArcGIS Runtime SDK for Java sample viewer application which gets installed with the SDK, and in the sample code pages online.

Related topics