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 parametersstart()
: starts the job by submitting to the/submitJob
endpointcancel()
: 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 anarc_form_params
S7 object (access the underlying list withjob$params@params
)status
: returns the status of the job as anarc_job_status
S7 objectresults
: fetches the results of the job and applies theresult_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.