Skip to content

Using geoprocessing services

Geoprocessing (GP) is one of the fundamental frameworks that powers the ArcGIS System. Many of the tools and APIs available in ArcGIS Online, ArcGIS Enterprise, and ArcGIS Location Platform are exposed using the Geoprocessing Service Framework.

Geoprocessing services are used as the backbone of analysis services, routing, and can even be used to deploy custom tools in a scalable and asynchronous manner.

{arcgisutils} provides a structured and unified interface to interacting with GP Services directly from R.

Geoprocessing Jobs

We interact with geoprocessing services through a GP job represented by the arc_gp_job R6 class. A new geoprocessing job can be created with arc_gp_job$new() with the following structure:

library(arcgisutils)

arc_gp_job$new(
  base_url = "https://your-service-url.com",
  params = list(),
  result_fn = NULL
)
#> <arc_gp_job>
#> Job ID: not initiated
#> Status: not started
#> Resource: /your-service-url.com
#> Params:

Custom packages

If you are creating a new package or wrapper for a specific service it is recommended to create a new class for it with R6::R6Class("myclass", inherit = arc_gp_job).

An arc_gp_job has the following methods:

  • new(): creates a new job from the given url and parameters
  • start(): starts the job by submitting to the /submitJob endpoint
  • cancel(): cancels the running job by submitting to the /cancel endpoint

In addition to the above methods, the following active bindings are provided:

  • params: returns the input parameters as an arc_form_params S7 object (access the underlying list with job$params@params)
  • status: returns the status of the job as an arc_job_status S7 object
  • results: fetches the results of the job and applies the result_fn to the results by calling the /results endpoint

Parameters

The geoprocessing framework has service data types that can be provided to a geoprocessing job. Most geoprocessing parameters can be created and parsed using arcgisutils.

Parameter Type Write Read
GPFeatureRecordSetLayer as_esri_featureset() parse_gp_feature_record_set()
GPRecordSet as_record_set() parse_gp_record_set()
GPRasterDataLayer as_gp_raster_layer() yyjsonr::read_json_str()
Field as_fields() creates a list of fields. Convert to json with yyjsonr::write_json_str(x, auto_unbox = TRUE). yyjsonr::read_json_str()
GPBoolean, GPDouble, GPLong, GPString yyjsonr::write_json_str(x, auto_unbox = TRUE) yyjsonr::read_json_str()
GPLinearUnit as_gp_linear_unit() parse_gp_linear_unit()
GPArealUnit as_gp_areal_unit() parse_gp_areal_unit()
GPDate as_gp_date() parse_gp_date()
GPSpatialReference as_spatial_reference() parse_spatial_reference()

Many geoprocessing services require a feature set which can be created with as_esri_featureset().

Unsupported parameter types ❌

The following parameter types are not yet supported.

  • GPValueTable
  • GPComposite
  • GPMultiValue
  • GPDataFile
  • GPEnvelope
  • GPCoordinateSystem
  • GPStringHidden
  • GPSQLExpression

Please create an issue if you have a use case for an unsupported parameter type.

Processing Outputs

An arc_gp_job has a result_fn which is applied to the raw json string that that is returned from the $result active binding.

In many cases, the result from a GP service is a feature set output. To convert that into an {sf} object use the parse_gp_feature_record_set() function. Otherwise, the result is parsed using RcppSimdJson::fparse() to convert the result into a list.

Example: Trace Downstream service

As a complete example we will call the Trace Downstream elevation service. This example will return a linestring of the downstream flowpath from the provided point.

Here we create a single point as an sfc object which will be provided to the InputPoints parameter as a FeatureSet.

library(sf)

# create input points
input_points <- st_sfc(
  st_point(c(-159.548936, 21.955888)),
  crs = 4326
)
library(arcgisutils)

# authenticate
set_arc_token(auth_user())

# store the service url
service_url <- "https://hydro.arcgis.com/arcgis/rest/services/Tools/Hydrology/GPServer/TraceDownstream"

# create a new job
downstream_job <- arc_gp_job$new(
  base_url = service_url,
  params = list(InputPoints = as_esri_featureset(input_points), f = "json"),
  # the result is a GPRecordFeatureSet
  result_fn = parse_gp_feature_record_set,
  token = arc_token(),
)

# print the job
downstream_job
#> <arc_gp_job>
#> Job ID: not initiated
#> Status: not started
#> Resource: /TraceDownstream
#> Params:
#> • InputPoints
#> • f

This creates a new arc_gp_job object. The object stores the logic of the job but it has not yet been instantiated. To start the job we need to explicitly call $start().

downstream_job$start()
#> <arc_gp_job>
#> Job ID: j06b4ece5616a49e88c99b2cd91c9d6e6
#> Status: not started
#> Resource: /TraceDownstream
#> Params:
#> • InputPoints
#> • f

This starts the job asynchronously. You can let this job run to completion without having to worry about it. Or, if you want to wait for it to complete and bring the result in to memory, use the $await() method on the job.

downstream_job$await()
#> $param_name
#> [1] "OutputTraceLine"
#> 
#> $data_type
#> [1] "GPFeatureRecordSetLayer"
#> 
#> $geometry
#> Simple feature collection with 1 feature and 6 fields
#> Geometry type: MULTILINESTRING
#> Dimension:     XY
#> Bounding box:  xmin: 438895 ymin: 2422310 xmax: 443325 ymax: 2428045
#> Projected CRS: NAD83 / UTM zone 4N + Unknown VCS
#>   OBJECTID PourPtID
#> 1        1        1
#>                 Description
#> 1 NED 10m processed by Esri
#>   DataResolution LengthKm Shape_Length
#> 1           10.0 9.489823     9489.823
#>                         geometry
#> 1 MULTILINESTRING ((443325 24...

This returns a GPFeatureRecordSetLayer result which is a list containing the parameter name, data type, and the geometry associated with the result.

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.