Routing

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 incoporate routing functionality into your ArcGIS Runtime for Java applications in a connected (online) scenario, make use of the API's Route task. To perform routing operations in a disconnected scenario (offline), use local data including a local geoprocessing service based on geoprocessing packages containing Network Analyst tools. Routing in a disconnected scenario is covered in the topics How to author and publish a geoprocessing model and How to develop a point-to-point routing application. What follows is a walk-through of how to use the online routing capabilities via the Route task.

Route task

The Route task allows you to easily add routing capabilities to your GIS applications. With the Route task, you can retrieve routes and directions between a set of input features, such as points (x, y coordinates) representing locations to visit. Since the Route task is built on the advanced capabilities of ArcGIS for Server's network analysis services, it offers many options and can take many parameters into account when solving a route. For instance, routes can be solved such that the stops are visited in the optimal order (as opposed to 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.

Initializing a Route task

To initialize a Route task, declare a RoutingTask object, instantiate it with the new keyword, and pass the 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 ArcGIS Network Analyst extension, then publishing that dataset to ArcGIS for Server.

RoutingTask task = new RoutingTask("http://tasks.arcgisonline.com/ArcGIS/rest/services/" + 
           "NetworkAnalysis/ESRI_Route_NA/NAServer/Route");

Specifying a Route task's input parameters

The Route task's execution method, solveAsync, takes a RoutingTaskParameters object as input. At a minimum, you will need to specify the Stops parameter, as this determines the locations between which a route will be calculated. Stops may be defined as a list of Graphics, a list of StopGraphics, a URL which defines a map service query that returns Points or a Layer from the network analysis service's corresponding map service. Often, 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 optmized 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.

Below is an example of initializing a RoutingTaskParameters 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 solveAsync method will return both geometry and directions for the calculated route. Note that the ReturnRoute property is not explicitly specified because it has a default value of true.

// get stop graphics from graphics layer
		List<Graphic> stopLocations = new ArrayList<Graphic>();
		int[] graphicIds = stopsGraphicsLayer.getGraphicIDs();
		for (int i = 0; i < graphicIds.length; i++) {
			stopLocations.add(stopsGraphicsLayer.getGraphic(graphicIds[i]));
		}

		// create parameters
		RoutingTaskParameters routeParameters = new RoutingTaskParameters();
		routeParameters.setStops(new NAFeaturesAsFeature(stopLocations));
		routeParameters.setReturnDirections(true);
		routeParameters.setFindBestSequence(true);
		routeParameters.setPreserveFirstStop(true);

Executing a routing task and handling results

Once you have initialized a RoutingTaskParameters object with the desired input, calculating the route simply requires a call to the solveAsync method. The Route task passes its results to the onCallback method, which is called whenever a route operation completes successfuly. The operation's results are contained in a RoutingResults object. The route's geometry is returned as a Graphic in the Route field of RoutingResults. The code below builds on the callback above to retrieve the route, apply a symbol to it and add it to a graphics layer:

task.solveAsync(routeParameters, new CallbackListener<RoutingResult>() {
				
				@Override
				public void onError(Throwable e) {
					e.printStackTrace();
				}
				
				@Override
				public void onCallback(RoutingResult objs) {
					//check result and display route and directions
if (objs.getRoutes().size() > 0){
		Geometry route = objs.getRoutes().get(0).getRoute().getGeometry();
		Graphic routeGraphic = new Graphic(route, new SimpleLineSymbol(Color.BLUE, 2.0f));
		graphicsLayer.addGraphic(routeGraphic);
		}
				}
			});

Directions are returned as a list in the RoutingDirections field. Each RoutingDirection contained within this list represents one step in the directions. The RoutingDirection'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. The code below steps through the directions, retrieving and formatting the description, distance, and travel time of each. Note that, to keep the example simple, the formatting used is very basic and null checks are omitted.

String directions = "";
	    // Loop through each step of the directions
	    for (RoutingDirection direction : result.getRoutes().get(0).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.getTime());	    	
	    	directions += direction.getText() + ". " + length + " miles. " + time + " minutes.\n";
	    }

Examples of using the Route, Service Area and Closest Facility tasks can be found in the ArcGIS Runtime for Java Sample application.

2/7/2013