Generate service areas

You can do the following using the ArcGIS Runtime SDK service area task:

  • Find all roads that can be reached within a given distance or time from a specific location
  • Request multiple service areas cutoffs for one or more locations
  • Specify how service areas from multiple locations are constructed
  • Use different travel modes to model various transportation scenarios

This topic describes how to generate service areas from an online network service. For an overview of networks and network analysis, see What is a network dataset in the ArcGIS Desktop documentation.

Choosing a data source

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

Use an online network service

To model service area boundaries for a set of 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.

Note:

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

The most important criterion for choosing a service is the geographic extent that it covers. You cannot find service areas using a service that does not encompass the street network used by the facilities. 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 service area service on your own portal or on ArcGIS Online. Or, you can use a service area service created by someone else that suits your needs, such as the Esri World Service Area 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 generate service areas for 7:00 a.m. and compare them with those you generate for 8:00 a.m.

Accessing a service area service may require authorization, which is also true for accessing map and feature services. You can authorize by providing valid credentials when you create the service area task object or by adding a token to the AuthenticationManager.

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

Note:

A service area geoprocessing service can also be published and consumed. For more information on publishing, see Generate Service Areas tool and Publishing a geoprocessing service. For more information about consuming geoprocessing services from Runtime, see Geoprocessing.

Use local data

You can find service areas 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 service are. You have a couple of options for provisioning your device with a local transportation network: mobile geodatabases or mobile map packages. Either may be deployed with your app on the device.

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 map packages see create a mobile map package with ArcGIS Pro.

Generate service areas

The basic steps for finding service areas are outlined below.

  1. Create and load service area task
  2. Specify service area task parameters
  3. Execute the service area task
  4. Process results

Create and load the service area task

The service area task is an object that refers to a service or local transportation network, accepts service area task parameters, is executed to find the service area, and returns results.

The following creates a service area task from a public service:

String SanDiegoRegion =
  "http://sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/NAServer/ServiceArea";
ServiceAreaTask serviceAreaTask = new ServiceAreaTask(SanDiegoRegion);
serviceAreaTask.loadAsync();

The following creates a service area task from a portal's default service:

// 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 service area service
    String url = portal.getPortalInfo().getHelperServices().getSyncServiceAreaService();


    // create a service area task from the url
    ServiceAreaTask serviceAreaTask = new ServiceAreaTask(url);
    serviceAreaTask.setCredential(portal.getCredential());
    serviceAreaTask.loadAsync();
  }
});

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

Specify service area task parameters

Service area task parameters specify how the analysis should be performed. There are many parameters that let you customize how the service area is determined. Parameters include facilities, barriers, travel mode, impedance cutoffs, polygon detail, and so on.

You can get the default set of service area task parameters from the service area task object. These default parameters are determined by properties of the service and the underlying transportation network dataset. Often, different services 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 the individual parameter values you want to change.

The following example gets the default ServiceAreaParameters and changes some of the parameter values.

final ListenableFuture<ServiceAreaParameters> parameters = serviceAreaTask.createDefaultParametersAsync();
parameters.addDoneListener(() -> {
  try {
    // gets the default parameters set by the service area task
    ServiceAreaParameters serviceAreaParameters = parameters.get();
    // once task is solved, polylines and polygons showing created service areas will be returned
    serviceAreaParameters.setReturnPolylines(true);
    serviceAreaParameters.setReturnPolygons(true);
    // service area will be display with high detail
    serviceAreaParameters.setPolygonDetail(ServiceAreaPolygonDetail.HIGH);
  } catch (InterruptedException | ExecutionException e) {
    // ... deal with exception
  }
});

Your app might allow users to choose some parameters, such as cost attributes to accumulate or the polygon buffer distance. Your app would get these choices from the user and set the corresponding values on the parameter object.

Specify facilities and barriers

Facilities are points features. They can be created either explicitly from MapPoint 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.

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 service areas but when relevant, can make your results more accurate.

Facilities and barriers on the map

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

The following example creates facilities and barriers and uses them to set properties on the service area parameters:

// create a facility from a location and assign to parameters
Point hospitalLocation = new Point(-13032763.24, 3860880.60, SpatialReferences.getWebMercator());
ServiceAreaFacility hospital = new ServiceAreaFacility(hospitalLocation);
serviceAreaParameters.setFacilities(Arrays.asList(hospital));


// create a barrier to avoid and add to parameters
Point accidentLocation = new Point(-13033331.71, 3859368.54, SpatialReferences.getWebMercator());
PointBarrier barrier = new PointBarrier(accidentLocation);
serviceAreaParameters.setPointBarriers(Arrays.asList(barrier));

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

// open a service table of facilities
String facilityTableUrl =
  "http://sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiegoInputs/MapServer/3";
ServiceFeatureTable facilityServiceTable = new ServiceFeatureTable(facilityTableUrl);
facilityServiceTable.loadAsync();


// create query parameters to select all facilities
QueryParameters facilityQueryParams = new QueryParameters();
facilityQueryParams.setWhereClause("1=1");


// set facilities to parameters using the table and the query parameters
serviceAreaParameters.setFacilities(facilityServiceTable, facilityQueryParams);

The following example uses a local table to define facilities:

// load geodatabase storing facility data
final Geodatabase geodatabase = new Geodatabase("path/to/file/.geodatabase");
geodatabase.loadAsync();


geodatabase.addDoneLoadingListener(() -> {
  // pass in name of table that holds facility data
  ArcGISFeatureTable facilityTable = geodatabase.getGeodatabaseFeatureTable("FacilityTableName");


  // can create query to filter for certain facilities
  QueryParameters facilityQueryParams = new QueryParameters();
  // example query for hospital and fire station facilities 
  facilityQueryParams.setWhereClause("Type='Hospital' or Type='Fire Station'");
  // set the parameters facilities using the local table from geodatabase and query
  serviceAreaParameters.setFacilities(facilityTable, facilityQueryParams);
});

Note:

The input table's field values can be used to populate properties for facilities and barriers. For local geodatabases, this is based on a naming convention. For details, see Service area analysis. When publishing a service area service, the default names can be altered. For details, see Loading Network Analysis Objects in ArcMap

Other service area parameters properties

The following are the properties that can be set on the parameter's object to further refine how service areas are determined:

  • Default impedance cutoffs—This property specifies the values used to calculate the extent of the service areas. The inputs are in the units of the impedance cost attribute defined for the network travel mode being used.

    The default impedance cutoffs can be overridden on specific facilities by specifying the impedance cutoffs on a facility. The exception to this is when the geometry at overlap parameter is set to dissolve, in which case, the facilities cutoffs are ignored and the default impedance cutoff is used. This is to ensure all facilities have the same cutoff values, and the service areas polygons can be dissolved. This behavior is applied even if only a single facility is specified and service area overlap geometry dissolve is specified.

  • Polygon buffer distance—This property specifies the distance, in meters, by which the outer service area polygons will be trimmed. This is useful if the network is sparse and you don't want the service area to cover large areas where there are no network features.
  • Service area polygon detail—The level of detail of the output polygon geometry can be specified by setting this property. The higher the requested detail, the more accurate the output but the longer it will take to generate. The following list describes the available values for this property.
    • Generalized
      • Generated quickly
      • Fairly accurate (deteriorates near service area polygon boarders)
      • Polygons are simplified
      • May result in islands of unreached elements being included in the service area
      • Hierarchical solve used
      • Polygons cannot be trimmed
      • Polylines cannot be returned
    • Standard
      • Generated fairly quickly
      • Polygons are simplified
      • Hierarchical solve not used
      • Polygons can be trimmed using the polygon buffer distance parameter
      • Polylines can be returned
    • High
      • Longer to generate
      • More accurate
      • Polygons are more detailed
      • Hierarchical solve not used
      • Polygons can be trimmed using the polygon buffer distance parameter
      • Polylines can be returned
  • Geometry at overlap—This property controls how the overlapping polygons are constructed when multiple facilities are specified. The three options are as follows:
    • Dissolve—Overlapping polygons with the same cutoff values are merged
    • Overlap—Polygons are created for each facility independently and may overlap
    • Split—Overlaps between polygons are assigned to a single facility based on the lowest impedance
  • Geometry at cutoffs—Controls how the output polygons are constructed. If geometry at cutoffs is set to Rings, the output polygons will not include the area of smaller inner cutoffs. If geometry at cutoffs is set to Disks, the output polygons will include the area of smaller inner cutoffs.
  • Return polylines—Lines will only be returned when polygon detail is set to Standard or High. The polylines will be split at the cutoff boundaries.

Execute the service area task

Execute the service area task's solve method, providing the service area parameters.

// Solve for service areas
ListenableFuture<ServiceAreaResult> solveResult = serviceAreaTask.solveServiceAreaAsync(serviceAreaParameters);
solveResult.addDoneListener(() -> {
  try {
    ServiceAreaResult serviceAreaResult = solveResult.get();
    // ... process results
  } catch (Exception e) {
    // ... deal with exception
  }
});

Process results

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

The outputs can include polygons, polylines, facilities, and barriers depending on the service area parameter settings. The output facilities and barriers are copies of the corresponding inputs and have information such as location status or distance to network location populated by the solve process.

Service area result polygons

Service area polygons

To access the resulting service area polygons, you can iterate through the returned facilities and get a list of service area polygons for each facility. The shape and size of these polygons are affected by the service area parameter values passed in to the solve operation.

// for displaying service areas
SimpleFillSymbol serviceAreaSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, 0xFF00FF00, null);
// loop through all facilities in the result
for (int facilityIndex = 0; facilityIndex < serviceAreaResult.getFacilities().size(); facilityIndex++) {
  // get the result polygons (service areas) for this facility
  List<ServiceAreaPolygon> serviceAreas = serviceAreaResult.getResultPolygons(facilityIndex);
  // loop through all service areas for this facility
  serviceAreas.forEach(serviceArea -> {
    // add a new graphic to display the service area (in a graphics overlay)
    graphicsOverlay.getGraphics().add(new Graphic(serviceArea.getGeometry(), serviceAreaSymbol));
  });

Service area polylines

To access the polylines, iterate through the returned facilities and retrieve the list of the network polylines that are within each facility's service areas. The cumulative from and to costs can be retrieved from each polyline.

// for displaying service areas
SimpleLineSymbol serviceAreaSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, 0xFFFF0000, 3);
// loop through all facilities in the result
for (int facilityIndex = 0; facilityIndex < serviceAreaResult.getFacilities().size(); facilityIndex++) {
  // get the result polylines (service areas) for this facility
  List<ServiceAreaPolyline> serviceAreas = serviceAreaResult.getResultPolylines(facilityIndex);
  // loop through all service areas for this facility
  serviceAreas.forEach(serviceArea -> {
    graphicsOverlay.getGraphics().add(new Graphic(serviceArea.getGeometry(), serviceAreaSymbol));


    // get the cost of traveling this line from starting location using parameters' travel mode
    double toCost =
      serviceArea.getToCumulativeCost(serviceAreaParameters.getTravelMode().getImpedanceAttributeName());
    System.out.println("Cost to line: " + toCost);
  });
}