Skip To Content ArcGIS for Developers Sign In Dashboard

Route to closest location

You can do the following using the ArcGIS Runtime SDK closest facilities task:

  • Find the nearest facilities to incidents based on network travel time
  • Set a maximum impedance (distance or time for example) to search for facilities
  • Set the number of facilities to find for each incident
  • Avoid restricted areas and maneuvers
  • Specify different travel modes to model various transportation scenarios

A closest facilities task is a network analysis operation that is executed asynchronously. It returns results with details regarding the closest facilities to incidents and the routes to travel for a given transportation network. This operation is sometimes referred to as "solving for closest facilities" or "finding closest facilities".

Transportation network datasets are modeled from features (lines and points) that represent roads, bridges, tunnels, bike paths, train tracks, junctions, and other elements in the network. The geometric intersections of features help to define connectivity between the network elements they represent. The connectivity of the transportation network is analyzed to find the best routes between incidents and facilities.


To learn more, see What is a network dataset? in the ArcGIS Desktop documentation.

Choose a data source

The closest facilities task supports using online services or a local mobile geodatabase as its data source for a network.

Use an online network service

To model travel between incidents and facilities, you can use a transportation network exposed as an online ArcGIS service (an ArcGIS network analysis service). Network Analysis services are hosted in Esri's cloud platform, ArcGIS Online, or can be published on your own ArcGIS servers. These services provide a REST API for clients such as mobile and web applications. For more information about publishing a service, see Tutorial: Publishing a network analysis service.


Some geoprocessing functionality is also available locally using Local Server and geoprocessing packages.

The most important criterion for choosing a service is the area that it covers. You cannot find the closest facilities using a service that does not encompass all the incidents, facilities, and barriers that your user will specify. In addition, services offer differing levels of capability and specialization, which are determined by the service properties and the underlying transportation network dataset.

You can build a transportation network dataset from your own data, or use a dataset provided by someone else, such as Esri's World Street Map data. Then, you can publish the data as a closest facility service on your own portal or on ArcGIS Online. Or, you could use a closest facility service created by someone else that suits your needs, such as the Esri World Closest Facility Service, which references data that covers much of the world. Since the ArcGIS Online data also includes traffic for many areas, analysis can account for dynamic traffic conditions. For instance, you can find the closest facility for a departure time of 7:00 a.m. and compare that route with one you generate for 8:00 a.m.

Accessing a closest facility service may require credentials, which is also true for accessing map and feature services. You provide these credentials when you create the closest facilities task object or by adding a token to the AuthenticationManager.

When using ArcGIS Enterprise portal, default utility services may be configured, such as a closest facilities service. ArcGIS Runtime API provides methods to obtain the default services' URLs for a given portal. Setting a default service on a portal is optional, however, so they may not always be set.


A closest facilities geoprocessing service can also be published and consumed. For more information on publishing, see the Find Closest Facilities tool and the Publishing a geoprocessing service help topics. For consuming geoprocessing services from Runtime, see Geoprocessing.

Use local data

You can find closest facilities using a transportation network stored on your device, meaning that your device does not need a network connection to a communication network to find a route. You have a few options for provisioning your device with a local transportation network: mobile geodatabases, mobile map packages or mobile scene packages.

If you'd like a ready-to-use and regularly updated network dataset (and locator) for your area of interest, you can license StreetMap Premium data (in mobile map package format). For details, see Add StreetMap Premium data.

To learn more about mobile geodatabases see Creating ArcGIS Runtime content.

To learn more about mobile packages see Create a mobile map packagewith ArcGIS Pro, or Create a mobile scene package with ArcGIS Pro.

Find the closest facilities

The basic steps for finding the closest facilities are outlined below.

  1. Create and load the closest facilities task
  2. Specify closest facility task parameters
  3. Execute the closest facilities task
  4. Process results

Create and load the closest facilities task

The closest facilities task is an object that references a closest facilities service or local transportation network and accepts parameters that define how closest facilities should be found on the network. When executed, it returns routes to the closest facilities as results.

The following example creates a closest facilities task from a public service:

String url =
ClosestFacilityTask closestFacilityTask = new ClosestFacilityTask(url);

You can create a closest facilities task from a portal's default service (if one is defined) as follows:

// log on to your portal using credentials
Portal portal = new Portal("http://" + yourPortalURL, true);
portal.setCredential(new UserCredential("username", "password"));
portal.addDoneLoadingListener(() -> {
  // check that portal has loaded properly 
  if (portal.getLoadStatus() == LoadStatus.LOADED) {
    // get the url for the default closest facility service
    String url = portal.getPortalInfo().getHelperServices().getSyncClosestFacilityService();

    // create a closest facility task from the url
    ClosestFacilityTask closestFacilityTask = new ClosestFacilityTask(url);

You can also create a closest facilities task from a mobile map package or mobile geodatabase stored on the device.

Specify closest facility task parameters

Closest facility task parameters specify how the analysis should be performed. A variety of parameters are available that let you customize how the closest facilities are determined, such as incident locations, facility locations, barriers to network travel, travel mode, target facility count, output spatial reference, and so on.

You can get the default set of closest facility task parameters from the closest facility task object. These default parameters are determined by properties of the service and the underlying transportation network dataset. Different services will most likely have different defaults. Rather than building task parameters from scratch, it's recommended to start with the default parameters for the service and to then modify individual parameter values you want to change.

The following example gets the default ClosestFacilityParameters and changes some of the parameter values:

final ListenableFuture<ClosestFacilityParameters> parameters = closestFacilityTask.createDefaultParametersAsync();
parameters.addDoneListener(() -> {
  try {
    // gets the default parameters set by the closest facility task
    ClosestFacilityParameters closestFacilityParameters = parameters.get();
    // once task is solved, return settings below
    // returns route between closest facility and incident
    // returns turn by turn directions between facility and incident
    // spatial reference set to returned routes
  } catch (InterruptedException | ExecutionException e) {
    // ... deal with exception

Your app might allow users to choose some parameters directly, such as cost attributes to accumulate or the number of facilities to find. Your app would get these choices from the user and set the corresponding values on the parameter object.

Specify incidents, facilities, and barriers

Incidents and facilities are points features. They can be created either explicitly from Point objects or by specifying a feature table (local or online) with a geometry of type point. When using a feature table, you can optionally set a where clause to filter which features to use. When specifying an online feature table, the table will not be queried until solve is called.

Properties on Facility and Incident classes can be used to model, and to accurately locate, moving features used as these inputs. You don't need to provide values for these properties if using stationary facilities or incidents.

  • Speed—how fast the input is moving (meters per second). Speed is usually obtained from the GPS receiver and updated as the location changes
  • Bearing—the direction in which a point is moving (degrees measured clockwise from true north). Bearing is usually obtained from the GPS receiver and updated as the location changes
  • Bearing tolerance—a range of acceptable bearing values when locating moving points on an edge, using the specified bearing
  • Latency—indicates how much time is expected to elapse from the moment GPS information is sent from a moving vehicle to a server and the moment the processed route is received by the vehicle's navigation device

Barriers are locations along the network that either restrict travel completely (a road closure for example), or add to the cost of travel when traversed (road work or increased traffic for example).

Barriers can be points, polylines, or polygons, and you can define barriers in various ways. Your users might draw barrier graphics interactively, your app might load graphics from a feature table, and so on. For example, you may have a feature table with areas affected by a forest fire that must be avoided. Barriers are optional when solving for closest facilities, but when relevant, can make your results more accurate.

The solve operation projects input features to the spatial reference of the transportation network dataset used by the service. The spatial reference of the incidents, facilities, and barriers must be defined but can be different than the transportation network dataset's spatial reference.

The following example creates incidents, facilities, and barriers objects and uses them to set properties on the closest facility parameters:

SpatialReference webMercator = SpatialReferences.getWebMercator();
// create an incident from a location and set to parameters
Point incidentLocation = new Point(-13034379.71, 3858390.14, webMercator);
Incident incident = new Incident(incidentLocation);

// create a facility from a location and set to parameters
Point facilityLocation = new Point(-13032763.24, 3860880.60, webMercator);
Facility facility = new Facility(facilityLocation);

// create a barrier to avoid and add to parameters
Point barrierLocation = new Point(-13033331.71, 3859368.54, webMercator);
PointBarrier barrier = new PointBarrier(barrierLocation);

You can also use online tables to define facilities and incidents as follows:

// open a service table of facilities and incidents
ServiceFeatureTable facilityServiceTable =
  new ServiceFeatureTable(
ServiceFeatureTable incidentServiceTable =
  new ServiceFeatureTable(

// create query parameters to select all features within table 
QueryParameters queryParameters = new QueryParameters();

// set facilities and incidents to parameters using table and query
closestFacilityParameters.setFacilities(facilityServiceTable, queryParameters);
closestFacilityParameters.setIncidents(incidentServiceTable, queryParameters);

The following example uses a local table to define facilities:

// load geodatabase with tables storing facility and incident data
final Geodatabase geodatabase = new Geodatabase("path/to/file/.geodatabase");
geodatabase.addDoneLoadingListener(() -> {
  // can create query to filter for certain facilities and incidents
  QueryParameters queryParameters = new QueryParameters();

  // pass in name of table that holds facility data
  ArcGISFeatureTable facilityTable = geodatabase.getGeodatabaseFeatureTable("FacilityTableName");
  // example query for hospital and fire station facilities 
  queryParameters.setWhereClause("Type='Hospital' or Type='Fire Station'");
  // set the parameters facilities using the local table from geodatabase and query
  closestFacilityParameters.setFacilities(facilityTable, queryParameters);

  // pass in name of table that holds incident data
  ArcGISFeatureTable incidentTable = geodatabase.getGeodatabaseFeatureTable("IncidentTableName");
  // create a query parameters that gets all incidents
  // set the parameters incidents using the local table from geodatabase and query
  closestFacilityParameters.setIncidents(incidentTable, queryParameters);


The input table's field values can be used to populate properties for incidents, facilities, and barriers. For local geodatabases, this is based on a naming convention. For details, see Closest facility analysis. When publishing a closest facility service, the default names can be altered. For details, see Loading network analysis objects in ArcMap.

Other closest facility parameters

Additional properties on the closest facility parameters object allow you to refine how travel across the network is modeled, to place thresholds on the solve, and to restrict the results that are returned. The parameters are as follows:

  • Accumulate attribute names—A list of cost attributes to accumulate. Cost attributes for a particular service can be obtained from ClosestFacilityTaskInfo.CostAttributes.
  • Travel mode—The type of travel used when solving for closest facilities. Travel modes on a network dataset define how a pedestrian, car, truck, or other medium of transportation moves through the network. A list of travel modes for a particular service can be returned using ClosestFacilityTaskInfo.TravelModes.
  • Default target facility count—The maximum number of facilities to be found for each incident. This value must be at least 1 or more. Individual incidents can override the default value by specifying target facility count.
  • Default impedance cutoff—An impedance value after which the solve will stop searching for facilities. Any facilities beyond this value will not be include in the results.
  • Start time—The date and time used for solving for closest facilities. This can affect the solve result if the network data source incorporates historic or live traffic.
  • Start time usage—Indicates whether the start time represents the departure or arrival along the closest facility routes.
  • Travel direction—Indicates whether the direction of travel is from incidents to facilities or from facilities to incidents. On a network with one-way restrictions and traffic data, changing the travel direction can produce different results. The direction you choose depends on the nature of your analysis.

Execute the closest facilities task

// solve for routes between closest facilities and incidents
ListenableFuture<ClosestFacilityResult> solveResult =
solveResult.addDoneListener(() -> {
  try {
    ClosestFacilityResult closestFacilityResult = solveResult.get();
    // ... process results
  } catch (Exception e) {
    // ... deal with exception

An example map scene showing incidents and routes to closest facilities.

Process results

When the closest facility task completes, results are available as a ClosestFacilityResult object. Depending on the success of the task, the property on the ClosestFacilityResult object may be populated. These messages contain information about how the task was solved.

Output incidents, facilities, or barriers

If the task parameters are set to return incidents, facilities, or barriers, properties of the closest facility result for these outputs are populated. These output features are copies of the corresponding inputs with additional properties such as and . The location of output incidents and facilities may also differ slightly from the input locations since output incidents and facilities are snapped to the closest non-restricted network element.

Incident to facility routes

Depending on the input parameters, an incident may be routed to multiple facilities. To retrieve each of these routes from the results, use the corresponding facility and incident indices. To help with this, returns the output facilities indices in order. The following example shows how to retrieve the routes in order:

// for displaying route between facility and incident
SimpleLineSymbol routeSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.DASH, 0xFF0000FF, 3);
// loop through all incidents that were returned in result
for (int incidentIndex = 0; incidentIndex < closestFacilityResult.getIncidents().size(); incidentIndex++) {
  // get the rankings of the facilities for this incident (an ordered list of the returned facilities indexes)
  // --Example: if the facility ranking is [2,0,1,3] then closestFacilityResult.getFacilities().get(2) is the closest.
  List<Integer> rankedFacilitiesIndexes = closestFacilityResult.getRankedFacilityIndexes(incidentIndex);
  // loop through closest facilities to this incident and display route between them to the view
  for (int facilityIndex : rankedFacilitiesIndexes) {
    ClosestFacilityRoute closestFacilityRoute = closestFacilityResult.getRoute(facilityIndex, incidentIndex);
    // display route to view
    graphicsOverlay.getGraphics().add(new Graphic(closestFacilityRoute.getRouteGeometry(), routeSymbol));

Each closest facility route in the results contains the polyline between an incident and facility, as well as the time spent traveling the route and the total time (travel time plus wait time if any).


Directions are returned for each route in the results if requested in the task parameters. Depending on the service configuration, directions can be returned in more than one language. Supported languages for a service are available in the closest facility task info.

Directions are composed of direction maneuvers. Each maneuver contains properties such as the direction text, which contains instructions that describe travel through a section of a route. A direction maneuver is further broken down into maneuver messages that give details about a specific maneuver.

Driving directions from an incident to the closest facility.

If defined in the transportation network, directions may also include direction events, which are notifications that do not require any action when traversing the route, for example, crossing over a time zone boundary.

Direction maneuver’s can include from level and to level values to define things like floor levels inside a building. For example, a user may want to see just one level of a walking route that spans multiple floors.

In order to return from level and to level values for a route:

  • The route’s directions style must be Campus
  • The network dataset must be configured to support levels as described in the Setting directions topic in the desktop help. This applies to both local data and the underlying network used by a routing service
  • The ArcGIS Server version hosting the service must be 10.6 or higher (when using online routing services)