Querying the map

Performing a query operation on the map is one of the fundamental aspects of a geographical information system. In the ArcGIS Runtime SDK for Java the Query task allows you to retrieve feature geometries and attributes from a local or online service in response to a query containing a WHERE clause and/or spatial query.

When retrieving features, you have a few options on how you want the results to be returned. You can specify an output spatial reference if you want the features to be projected into a different coordinate system. This is useful, for instance, if the service's spatial reference is different from the spatial reference of the map on which you want to display the features. You can also choose which feature attributes should be included in the results so that information is not retrieved unnecessarily. Similarly, do not return the geometries unless you wish to analyze or display them. Other options include sorting the result by field values (ascending or descending) and grouping the results by field values in order to calculate statistics.

Using the Query task

Follow these 4 key steps to perform a query on a layer using the Query task:

  1. Instantiate the QueryTask class and provide the URL of the online or local service or layer to the task's constructor.
  2. Specify the input parameters to the task.
  3. Execute the task synchronously or asynchronously.
  4. Listen for the completion of the task and process the results.

Obtain the URL to the map service layer

Firstly, obtain the URL of the online or local map service layer that will be queried. The URL for a local map service layer can be obtained from the ArcGISDynamicMapServiceLayer once it has been created using the path to a map package. Please go to this location for more information on map packages.

Here is the code to obtain the URL to layer(0) in a map package.

ArcGISLocalDynamicMapServiceLayer theLocalDynamicMapServiceLayer = 
                   new ArcGISLocalDynamicMapServiceLayer("Path to map package (.mpk)");
string theLayerURL = theLocalDynamicMapServiceLayer.getURL() + "/0"

Here is the URL to an online layer. In this case layer(5) of the ESRI_Census_USA map server.

string theLayerURL = 
"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5";

Instantiate the Query Task

Secondly, instantiate the QueryTask class passing the map service layer's URL to the task's constructor.

Instantiate the QueryTask passing in the local or online URL of the layer to be queried.

QueryTask queryTask = new QueryTask(theLayerURL);

Specify the Input Parameters of the Query class.

You can then define your query by setting a number of parameters on a Query class. This Query class will then be used as input to the Query Task when it is executed. So create the Query and set it's parameters. Here are some basic guidelines:

Query query = new Query(); 
query.setGeometry(geometry); 
query.setInSpatialReference(map.getSpatialReference()); 
query.setOutFields(new String[] { "STATE_NAME", "POP2000" });
query.setWhere("STATE_NAME='" + newStateName + "'"); 
query.setReturnGeometry(true);

Execute the task asynchronously

Asynchronous execution of the Query task is performed using the executeAsync method using the previously defined Query class as input. You also need to define a CallbackListener into which the results will be passed as a FeatureSet. If you execute the task asynchronously the application will remain responsive during the execution of the task. You will need to setup a call back listener to respond when the task completes or error. This is the recommended method of execution for most queries.

queryTask.executeAsync(query, new CallbackListener<FeatureSet>(){

  @Override 
  public void onError(Throwable e){ 
    e.printStackTrace(); 
  } 

  @Override 
  public void onCallback(FeatureSet featureSet) { 
    // Check the results
    if (featureSet.getGraphics().length < 1){
      System.err.println("Problem! There are no records returned");  
      return; 
    } 

    // Process the graphic of each resulting record 
    for (Graphic graphic : featureSet.getGraphics()){ 
					 //...
    } 
  } 
});

Execute the task synchronously

Synchronous execution of the Query task is performed using the execute method using the previously defined Query class as input. If you execute the task synchronously the application will be paused whilst the task is executing. The results of the query will be returned to a FeatureSet and then can be examined by the application. This method of execution is only recommended if the Query is reliably rapid and the resultant FeatureSet is small.

FeatureSet featureSet = queryTask.execute(query); 
 
// Check the results
if (featureSet.getGraphics().length > 1) { 
  System.err.println("Error! There cannot be more than 1 record returned."); 
  return; 
}

//Process the graphic of the resulting record
Graphic graphic = featureSet.getGraphics()[0];

Process the results

The results of the Query task are returned in a FeatureSet containing either attributes and/or geometries. If you have specified that there will be no geometry returned (setReturnGeometry(false)) then there will be no Geometry field. By setting the setOutFields property you defined which field values will be returned in the FeatureSet. All that remains is for you to process the contents of the FeatureSet.

// Process the graphic of each resulting record 
for (Graphic graphic : featureSet.getGraphics()){ 
.....
}

Sample code

To view any samples related to searching data, please launch the ArcGIS Runtime for Java sample application, that was installed with the ArcGIS Runtime SDK for Java, and explore the interactive samples and their code in the Search section.

2/7/2013