Run a geoprocessing task

This document describes how to run a geoprocessing task using the execute or submit job operations on both ArcGIS Server (online) and the ArcGIS Runtime local server (offline).

To run a geoprocessing task, you must have access to an online geoprocessing service or a local geoprocessing package .(gpk) that you can consume using the local server.

Task execution types

When working with geoprocessing services, developers must be aware of the execution type that the service was published with. This execution type can be found on the service's HTML task page. There are three execution types that geoprocessing tasks can run on a server:

  • Execute Task (esriExecutionTypeSynchronous defined in task page)

Synchronous execution is designed for fast running tasks where the client sends the request and then waits for the response. This means these types of services use less resources on the server. When developers interact with these services, they must use the API's executeor executeAsync methods of the Geoprocessor object.

  • Submit job (esriExecutionTypeAsynchronous defined in task page)

Asynchronous services are best suited for long running jobs. For asynchronous tasks, the server returns a job ID which the client uses to poll for the task status. When the status is completed, the results can be requested from the server using the job ID. Developers must use the API's submitJob and submitJobAsync methods to work with these services.

  • Submit job with map service results (esriExecutionTypeAsynchronous with a map server)

Geoprocessing services can be published with the result map service option enabled. The geoprocessing server (GPServer) creates an accompanying dynamic map server of the same name that visually represents each geodataset output parameter as a layer. This resulting dynamic map service or its service layers can then be added to your ArcGIS Runtime application as a dynamic map service. The map service's symbology is based on the symbology of the output layer that resulted from running the geoprocessing tool in ArcGIS Desktop during the publishing process. Refer to Defining output symbology for geoprocessing tasks for additional information on setting the symbology for a result map service.

Execute a geoprocessing task

To execute a geoprocessing task, the client must construct a request URL with the execute task URL and append name-value pairs of all the required input parameters. The name is the name of the task's input parameter and the value is the ASCII representation of the JSON value. The input parameter names and types can be found on the service's HTML task page. To construct this request URL, the developer can use the client API. The following example shows constructing a new Geoprocessor object, preparing a geoprocessing feature record set, adding the record set to a list of geoprocessing parameters, and executing the geoprocessing task.

String serviceURL = 
    "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Network/ESRI_DriveTime_US/GPServer";
String taskName = "CreateDriveTimePolygons";

// create Geoprocessor
Geoprocessor gp = new Geoprocessor(serviceURL + "/" + taskName);

// set up the parameters - see serviceURL for parameter info
GPFeatureRecordSetLayer gpFeatureRecordSetLayer = new GPFeatureRecordSetLayer("Input_Location");
gpFeatureRecordSetLayer.setGeometryType(Geometry.Type.POINT);
gpFeatureRecordSetLayer.addGraphic(point1);
gpFeatureRecordSetLayer.addGraphic(point2);
List<GPParameter> parameters = new ArrayList<GPParameter>();
parameters.add(gpFeatureRecordSetLayer);

// execute task - asynchronously in this case
gp.executeAsync(parameters, new CallbackListener<GPParameter[]>() {
  @Override
  public void onError(Throwable e) {
    ...
  }
  @Override
  public void onCallback(GPParameter[] objs) {
    // output results will be available on callback
    ...
  }
});

The final line of code in the code block above is responsible for asynchronously executing the geoprocessing task. It is recommended that tasks from remote servers are executed asynchronously to avoid blocking the calling application.

Handle task results

At the end of execution, if the task succeeds the server will construct a response with the values of the output parameter(s). If the task fails, the server will send an error response to the client.

The response is called a geoprocessing task result and will include either:

  • the output parameter values. The task result will have an array of output parameters. Each output parameter in the array will have a paramName, dataType, and its value. Output parameter names and types can be found by reading the service's HTML page.
  • an error response. An execute task operation may fail because of invalid parameters, inaccessible project data, or other geoprocessing tool failures. In such cases, the server will return a geoprocessing task error with a code number, the string "Unable to complete operation.", and details of the failure. The level of detail in the error response depends on the message level of the geoprocessing service. Based on the message level, the details property will include appropriate geoprocessing tool messages generated during execution. If the input parameters of the tool are invalid or if the message level property of the geoprocessing service is set to None, the details property of the error response will be empty.

Continuing the "Drive time polygons" example above, the following code locates a GPFeatureRecordSetLayer in the returned array of output GPParameter objects and examines the graphics contained in that layer. If the geometry of the graphic is a polygon the the graphic is added to the application's graphics layer.

@Override
public void onCallback(GPParameter[] objs) {
  GPFeatureRecordSetLayer gpResults = (GPFeatureRecordSetLayer)objs[0];
  for (Graphic graphic : gpResults.getGraphics()) {
    if (graphic.getGeometry().getType() == Geometry.Type.POLYGON) {
      SimpleFillSymbol simpleFillSymbol = new SimpleFillSymbol(Color.MAGENTA);
      Graphic driveTimePolygon = new Graphic(graphic.getGeometry(), simpleFillSymbol );
      graphicsLayer().addGraphic(driveTimePolygon );
    }
  }
}

Submit a job to a geoprocessing task

The figure below sums up the server/client communication of a submit job operation. Notice the periodic status requests sent by the client to determine the status of the job. When the server has successfully completed the execution of the job, it creates the results and inputs resources that can be accessed through the URL.

submitJob operation: server/client communication

The Geoprocessor is created in the same way as in the "Drive times polygons" execute example above. The following code uses a "Service Areas" example:

java submit job

String serviceURL = 
    "http://sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/GPServer";
String taskName = "Generate Service Areas";
Geoprocessor geoprocessor = new Geoprocessor(serviceURL + "\" + taskName);

Submit a job and get results

The most straightforward way to work asynchronously with a job is to call the submitJobAndGetResultsAsync() method. In one step you can submit the job with input parameters, specify the names of the output parameters you are interested in, and provide a callback to handle the results. This method is recommended if you will not need to cancel the job and you do not need feedback on the status of a job during its execution. Input parameter and output parameters (via the callback) can be handled in a similar way to the "Drive times polygons" execute example above.

java submit job and get results

geoprocessor.submitJobAndGetResultsAsync(
  parameters, 
  new String[] {"ServiceAreas"}, 
  null, 
  new GPJobResultCallbackListener() {
    @Override
    public void onError(Throwable e) {
      ...
    }
    @Override
    public void onCallback(GPJobResource jobResource, GPParameter[] outParameters) {
      ...
    }
});

Handle job results

Task results which were described above for an execute operation also apply to a submitJob operation. Those were the error response and output parameters.

If there is an error response, the status of the job will be updated to esriJobFailed, and the server will not create inputs and results resources such as a result map service.

Submit job operations also return an array of messages generated by the geoprocessing task during execution. Each element in the message array will have a type (esriJobMessageTypeInformative, esriJobMessageTypeWarning, or esriJobMessageTypeError) and a message description. The messages returned by the server depends on the message level of the geoprocessing service. If the message level is set to 'none', the server will not return any messages.

Messages can be iterated and output as follows:

java handle job results

if (jobResource.getJobStatus() != JobStatus.SUCCEEDED) {
  String allMsgs = "";
  GPMessage[] jobMsgs = jobResource.getMessages();
  for (int i = 0; i< jobMsgs.length; i++) {
    GPMessage msg = jobMsgs[i];
    allMsgs += (msg.getType() + ": " + msg.getDescription() + "\n");
  }
  System.out.println(allMsgs);
}

Submit a job

The API provides finely grained methods to work with submit job operations, interact with the task while it is executing, cancel the task, and receive status updates and messages. The following workflow is recommended:

  1. submit a job with input parameters. When the server receives a request for a submit job operation it creates a job resource with a unique ID known as jobId. The server response of the geoprocessing task submit job operation will have a unique job identifier (jobId) and the job status (jobStatus).
  2. poll the status of the job. The client can periodically send requests to determine the status of the job. The server response for job status request will include jobId, jobStatus, and geoprocessing tool messages depending on the message level of the geoprocessing service. The following code demonstrates how to poll:
while ((jobResource.getJobStatus() != JobStatus.SUCCEEDED)
				&& jobResource.getJobStatus() != JobStatus.FAILED
				&& i < MAX_ITERATIONS) {
		System.out.println("Not succeeded");
		jobResource = geoprocessor.getJobStatus();
		Thread.sleep(milliSeconds);
		i++;
}

Job statuses are described in the table below:

jobStatus codes

Description

esriJobWaiting

The server is busy with other requests.

esriJobSubmitted

The server has accepted the job request, input parameters have been validated.

esriJobExecuting

The server is executing the job.

esriJobSucceeded

The server has successfully completed the job and the output results are available.

esriJobFailed

The job has failed to execute because of invalid parameters or other geoprocessing tool failures.

esriJobCancelling

The server is cancelling the execution of the job based on the client's request.

esriJobCancelled

The request to run the job was cancelled by the client, and the server terminated the job execution.

Handle job results

When the job has succeeded (the job status is esriJobSucceeded) the server creates new resources for the input and output parameters. At the end of successful job completion, the client can send a request to retrieve each output parameter. The response from these resources will be the value of the parameter and it can be in any JSON/KML/AMF/HTML output format based on client requests. The following code shows how to get the first result parameter:

GPParameter result = null; 
GPJobParameter[] outputparameters = jobResource.getOutputParameters(); 
if (outputparameters.length > 0 && null != outputparameters[0]){
  result = geoprocessor.getResult(jobResource, outputparameters[0].getParamName(), false);
}

Cancel a job

The client may decide to discard the submit job operation anytime during the execution of the job and invoke a cancel operation on the job. When the server receives a cancel request, it modifies the job status to esriJobCancelling and attempts to terminate the execution of the job. The server returns a job status message (cancelling status) to the client. The client can continue to poll the status of the job and track the progress of job cancellation. Also, a client can request cancel only for jobs that are in esriJobWaiting, esriJobSubmitted, or esriJobExecuting status. If the cancel request is issued for jobs in esriJobSucceeded or esriJobFailed status, an error message will be returned by the server.

Submit a job to a geoprocessing task with map server results

If the geoprocessing service has been published with a map service enabled, the server creates a result map service for the output parameters at the end of the successful task execution. Each geodataset output parameter, such as a GPFeatureRecordSetLayer or a GPRasterDataLayer, will correspond to a layer in the dynamic map service. If the output of a GPString parameter references a geodataset, it will be added to the result map service as a layer. Each layer will be drawn based on the layer symbology defined in ArcGIS Desktop at the time of publishing. The order of the layers corresponds to the order of the output parameters.

To access this map service and add it to your map, create a new instance of an ArcGISDynamicMapServiceLayer and pass in the URL of the geoprocessing service and the GPJobResource, as shown below:

java add map layer result

ArcGISDynamicMapServiceLayer resultMapServiceLayer = 
    new ArcGISDynamicMapServiceLayer(gp.getUrl(), jobResource);
jMap.getLayers().add(resultMapServiceLayer);

If a job has failed, the server will not create result resources such as a result map service.

Consume a geoprocessing package with the local server

Working with local geoprocessing services is very similar to working with online geoprocessing service tasks. The difference is that the service is not currently running and the developer needs to start the service. Unlike online geoprocessing service tasks, where all the service parameters are predefined by the service publisher, developers must specify some of the parameters themselves based on how they want to interact with the service. These parameters include the execution type (execute, submit job, or submit job with map server result), and the maximum number of records that the service can return. Once the service is running, it is not possible to change the execution type.

Start a local geoprocessing service

Local geoprocessing services are started by creating a LocalGeoprocessingService instance using the path to the local geoprocessing package, then starting the service (synchronously or asynchronously). When the service is started, a URL to the geoprocessing service can be obtained from the LocalGeoprocessingService instance.

In the example below, a local geoprocessing service is started asynchronously using the geoprocessing package 'Route.gpk' which is included with the ArcGIS Runtime SDK installation. Although the start service method is called asynchronously, the execution type is EXECUTE which means the developer must use the execute or executeAsync methods in the Geoprocessor class.

LocalGeoprocessingService localGPRoutingService = new LocalGeoprocessingService("Route.gpk");
localGPRoutingService.setServiceType(GPServiceType.EXECUTE);
localGPRoutingService.setMaximumRecords(100000);
localGPRoutingService.addLocalServiceStartCompleteListener(
  new LocalServiceStartCompleteListener() {
    @Override
    public void localServiceStartComplete(LocalServiceStartCompleteEvent e){
      ...
    }
});
localGPRoutingService.startAsync();

Just as with online services, the service URL can also be placed in a browser to explore the geoprocessing service parameters. The developer can use the HTML service definition and task pages at this URL to discover how to code against the service. Additionally, each of the ArcGIS Runtime SDK sample viewer applications include a GPTaskInfo sample which uses the API to obtain the geoprocessing service parameter info.

Once the geoprocessing service is started, programming against the service is the same as programming against an online service. The developer must create the geoprocessing object, pass in the URL to the geoprocessing service plus the name of the geoprocessing task. The following code shows how to programmatically get the service URL and service tasks, then passing the URL and task name to the Geoprocessor:

String serviceURL = localGPRoutingService.getUrlGeoprocessingService();
GPServiceInfo serviceInfo = GPServiceInfo.fromUrl(localGpService.getUrlGeoprocessingService());
String taskName = serviceInfo.getTasks()[0];
Geoprocessor gp = new Geoprocessor(serviceURL + ”/” + taskName);

Maximum number of records

By default the maximum number of records a local geoprocessing service will return is 1000. If the service exceeds this number, no records will be returned. The reason for this is to protect the server from large requests which could take a long time to process. If 0 results are returned but the job completes successfully, it is recommended that you always check the result and job messages to determine whether the maximum records limit was reached. This value is specified when creating the local geoprocessing service and cannot be changed once the local service is running.

Execution types in detail

In the API, execution types of a local geoprocessing service are exactly the same as those of an ArcGIS Server service. Here we revisit those execution types and provide information on the processes running on the client machine.

  • Execute (esriExecutionTypeSynchronous)

    Starting a local geoprocessing service with the execution type set to 'execute' will result in a single local server process and is designed for working with quick executing geoprocessing tasks. This geoprocessing service type will not provide any feedback on the execution of the task. It will execute and either return a success or failure when the task has finished. Just as with the online geoprocessing service, the developer must use the execute or executeAsync methods on the Geoprocessor class to work with local geoprocessing services which have been started with the 'execute' type.

  • SubmitJob (esriExecutionTypeAsynchronous)

    The 'submit job' mode will start two local server processes: one to do the processing and the other to monitor the processing. This allows the monitoring process to be polled by the application to get back execution messages and the status of the task. Additionally, the task can be cancelled if necessary. Once the task completes, the data can be requested from the service. Just as with the online geoprocessing service, the developer must use the submitJob, submitJobAsync, or submitJobAndGetResultsAsync methods.

  • SubmitJobWithMapServerResult (esriExecutionTypeAsynchronous with a map server)

    The third type of execution is treated the same as the 'submit job' type except that an additional local server process is started which is used to host the result of the geoprocessing task in a local map service. This is particularly useful if your task outputs a large number of features that the client application has to symbolize and draw or if your task outputs a data type that is not supported for adding directly to the map control via the API, such as raster data. The default symbology of this map service is determined when the geoprocessing package is shared in ArcMap.