Find a route

A Route task allows you to calculate point-to-point and multipoint routes using ArcGIS for Server network analysis services or your own offline network dataset and a local geodatabase.

A network analysis service contains one or more network analysis layers. ArcGIS provides different types of analysis layers, such as route, service area, closest facility, and so on, depending on the type of analysis to be performed. A Route task relies on a route analysis layer to compute routes. ArcGIS Online provides network analysis services based on street data for the world and you can create your own services with ArcGIS for Server.

Finding a route with a local geodatabase requires that the local geodatabase contains a route analysis layer.

Learn about creating network analysis services

Create a Route task

There are two types of Route tasks. Choosing the right type of RouteTask depends on your data availability and needs. The LocalRouteTask offers the benefits of increased performance and removes the need for network connectivity, but as a consequence, a significant amount of storage space may be needed on-device. An OnlineRouteTask allows you to take advantage of robust ArcGIS Online services and requires no additional data deployment, but network speeds and REST response size can negatively impact performance.

To instantiate an OnlineRouteTask, provide a URL to a REST resource that represents a route layer in a network analysis service. If the service is secured, provide the credentials that can be used to access the service. The following code snippet shows how to create an OnlineRouteTask for the Route layer in an ArcGIS Online routing service:

OnlineRouteTask {
        id: onlineRouteTask
        url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/NAServer/Route"
    }

To instantiate a LocalRouteTask for offline routing, provide the path to the local geodatabase and the name of the routing network in that geodatabase. The following code snippet shows how to create a LocalRouteTask for a streets network in a sample geodatabase provided with the ArcGIS Runtime API for Qt:

LocalRouteTask {
    id: localRouteTask
    network: "Streets_ND"
    database: "~/RuntimeSanFrancisco.geodatabase"
}

Route task input parameters

The OnlineRouteTask solves a routing problem using an instance of the OnlineRouteTaskParameters class as input.

Similarly, the LocalRouteTask accepts a LocalRouteTaskParameters object as input. You should create one by declaring the LocalRouteTaskParameters component.

The following sections describe some of the inputs you can provide to a Route task.

Impedance

Impedance specifies a cost that should be minimized in the resulting route. For example, impedance could be set to Time in order to calculate the fastest route or Length to calculate the shortest route.

Online service descriptions

For online services, impedances supported by the service are listed in the Services Directory under Network Dataset > Network Attributes with a Usage Type of esriNAUTCost.

Network attributes list

In the example shown above, Length and Time are supported impedances. The following code snippet sets the impedance to Length in order to calculate the shortest route.

OnlineRouteTaskParameters {
    id: taskParameters
    impedanceAttributeName: "Length"
}

Access service descriptions programmatically

For both online and local RouteTasks, available cost attributes can also be accessed through the NetworkDescription object. This object contains important network information such as supported languages for driving directions, cost attributes, and restriction attributes. This object is useful for displaying routing options on your user interface. The following snippet shows accessing the network description and setting the first cost attribute as the impedance for the solve operation.

// Create a parameters object
OnlineRouteTaskParameters {
    id: taskParameters
    json: {
        "outSpatialReference": {"wkid": map.spatialReference.wkid},
        "returnDirections": true,
        "returnRoutes": true, 
        "returnStops": true  
    }
}
// Assign the first cost attribute as the impedance
if (routeTask.networkDescription.costAttributes.length > 0)
    taskParams.impedanceAttributeName = routeTask.networkDescription.costAttributes[0].name;

Stops

Stops specify the locations that must be visited along the route. Your route can have many stops, but you need at least two stops to calculate a valid route.

Stops as features

You can create an array of graphics representing stop features. You can then assign these features to the parameter object using stops.

Graphic {
    id: startGraphic
    geometry: Point {
        x: -117.08
        y: 32.7
        spatialReference: map.spatialReference
    }
    
    symbol: SimpleMarkerSymbol {
        style: Enums.SimpleMarkerSymbolStyleSquare
        size: 11
        color: "blue"
    }
            
    Component.onCompleted: {
        graphicsLayer.addGraphic(startGraphic);
        stopGraphics.addFeature(startGraphic);
    }
}
        
Graphic {
    id: endGraphic
    geometry: Point {
        x: -118.24
        y: 34.05
        spatialReference: map.spatialReference
    }
        
    symbol: SimpleMarkerSymbol {
        style: Enums.SimpleMarkerSymbolStyleSquare
        size: 11
        color: "blue"
    }
            
    Component.onCompleted: {
        graphicsLayer.addGraphic(endGraphic);
        stopGraphics.addFeature(endGraphic);
    }
}
        
NAFeaturesAsFeature {
    id: stopGraphics
    spatialReference: map.spatialReference
            
    Component.onCompleted: {
        routeTaskParameters.stops(stopGraphics);
    }
 
    LocalRouteTaskParameters {
        id: routeTaskParameters
        task: localRouteTask
        returnDirections: true
        outSpatialReference: map.spatialReference
    }
}

The order of the objects in the array indicates, by default, the sequence in which stops are visited by the route. However, if you enable the findBestSequence property on RouteTaskParameters, the service attempts to reorder the stops to find the optimal route. You can also enable the preserveFirstStop and preserveLastStop properties on RouteTaskParameters if you do not want the origin and destination stops to be reordered.

If you enable time windows in your analysis, you can also assign each stop a start and end time specifying the time window during which the stop needs to be visited. If a stop's setStartTime property is set to 10:00 a.m. and the route arrives at the stop at 9:50 a.m., there is a wait time of 10 minutes that is added to the total time. If the setEndTime property is set to 11:00 a.m., and the earliest a route can reach the stop is 11:25 a.m., a violation of 25 minutes is noted.

A stop can have additional attributes depending on how the route layer in the Network Analyst service is configured. These attributes are listed in the Network Analysis Classes > Class Name: Stops section in the Services Directory.

Attributes of stops
Attributes of stops

Attributes can be of type input, output, or both. Input attributes are specified by the client and are taken into consideration by the service while performing the analysis, for example, the time window's start and end time and routeName.

Output attributes are returned by the service with the computed result when you enable returnStops on RouteTaskParameters. Output attributes provide additional information about the stop pertaining to the results, for example, the time of arrival and departure and which side of the vehicle the curb is on.

Some attributes can be both input and output. These attributes are specified by the client but can be modified or overridden by the service, for example, when the service finds a more optimal sequence than the one specified.

Learn more about attributes supported by stop features

Layer definition

As shown above, for online routing you can define stops by providing the actual locations for each stop. An alternative is to specify them using a layer definition. This is useful when you already have a set of well-known or commonly used stops stored along with the network analysis service. In such cases, the application does not need to know the actual details about each stop. All it needs to do is set up a layer definition specifying which stops should be included in the analysis.

A layer definition is represented by a property of the NAFeaturesAsLayer component. You can use SQL statements and spatial relationships to specify which stops should be used in the analysis. For example, the following code snippets set up a layer definition referencing features that fall within the City of Los Angeles and have a value of Overnight for the delivery_type attribute.

NAFeaturesAsLayer {
    id: naLayer
    where: "delivery_type='Overnight'"
    layerName: "<layer_in_service_containing_stops>"
}

OnlineRouteTaskParameters {
    id: taskParameters
}

function solveRoute() {
    taskParameters.stops = naLayer;
    routeTask.solve(taskParameters);
}

Using a layer definition is only supported when solving with an OnlineRouteTask. The stops for a LocalRouteTask must be specified by value using the NAFeaturesAsFeatures class.

Barriers

Barriers represent ad hoc restrictions that must be taken into consideration when calculating a route. A barrier can specify a set of roads or a region that must be completely avoided by the route, for example, a bridge that may be closed due to construction work. Some barriers may permit travel through them albeit at an added cost. For example, an accident on a freeway may temporarily slow down traffic. This can be represented by a barrier that allows travel along the freeway but increases the required travel time.

Barriers as features

You can create an array of NAFeaturesAsFeatures objects representing barrier features and populate each feature with a geometry representing the barrier's location and shape. The geometry can be a point, polyline, or polygon. You can then assign these barrier features to the parameter object using pointBarriers, polylineBarriers, or polygonBarriers depending on the feature's assigned geometry type.

Note:

Create separate arrays for point, polyline, and polygon barriers.

A barrier can also have additional attributes depending on how the route layer in the Network Analyst service is configured. These attributes are listed in the Network Analysis Components > Component Name: Barriers, PolylineBarriers, PolygonBarriers section in the Services Directory. Attributes can be of type input (specified by the client), output (returned by the server), or both.

Learn more about barriers and the attributes supported by point, polyline, and polygon barriers

Time windows

A time window specifies a period of time within which a stop should be visited by a route. For example, if you make appointments to meet several customers at different locations, enable time windows in the analysis and specify a time window for each location to get a route that allows you to keep your appointments.

Learn more about time windows

To enable time windows in your analysis, do the following:

  • Enable the useTimeWindows property on RouteTaskParameters.
  • Specify the departure time from the origin using the startTime property on RouteTaskParameters.
  • Assign a time window to each stop.

Drive directions

The Route task can also return turn-by-turn driving directions for the route if you enable returnDirections on RouteTaskParameters. Specify the distance units to use (miles, kilometers, and so on) through the directionsLengthUnit property and, depending on the languages supported by the service, specify which language to use through the directionsLanguage property.

Result options

Ignore invalid locations

Enabling the ignoreInvalidLocations property allows the Route task to return a route even if some stops are invalid, for example, if they're not reachable on the underlying transportation network. If this property is disabled, the Route task returns an error even if one stop is invalid.

See the RouteTaskParameters API reference for a complete list of inputs for the Route task.

Calculate routes

Once you set up the input parameters, calculate the route by invoking the solve method. The LocalRouteTask emits a solveStatusChanged signal. Use the onSolveStatusChanged signal handler to process the results. After solveStatusChanged indicated success, the operation's results are contained in the solveResult property.

LocalRouteTask {
    id: localRouteTask
    network: "Streets_ND"
    database: "~/RuntimeSanFrancisco.geodatabase"
        
    Component.onCompleted: {
        localRouteTask.solve(localRouteTaskParameters);
    }
// . . .

Retrieve results

A RoutingResult object contains an array of objects representing the calculated routes. Each RoutingResult object contains the following:

  • A graphic representing the route feature. The graphic's attributes provide information about route properties.
  • An array of graphics representing the stops that are visited by the route (if you enabled returnStops on RouteTaskParameters). Each graphic contains attributes that correspond to stop properties. These properties provide valuable information about the stop as it pertains to the computed route.
  • A set of turn-by-turn driving directions (if you enabled returnDirections on RouteTaskParameters).

The RoutingResult object also contains an array of messages providing information about warnings or errors encountered while calculating the route.

The following example retrieves the route, applies a symbol to it, adds it to a graphics layer, prints the directions to the console, and zooms the map to the graphic:

onSolveStatusChanged: {
    if (solveStatus === Enums.SolveStatusCompleted) {
        console.log("Route complete # " + solveResult.routes.length.toString());

        for (var index = 0; index < solveResult.routes.length; index++) {
            var route = solveResult.routes[index];
            var graphic = route.route;
            graphic.symbol = routeSymbol;

            routesLayer.addGraphic(graphic);

            var t = "";
            var dirs = route.routingDirections;
            for (var dir = 0; dir < dirs.length; dir++) {
                t += dirs[dir].text + "\r\n";
            }
            console.log (t);
        }
    }
    else if (solveStatus === Enums.SolveStatusErrored) {
        console.log("Route error:" + solveError.message);
    }
}
Related topics