Query the map

Starting at version 10.2 of ArcGIS Runtime SDK for Java, you can query to retrieve feature geometries and attributes from either an ArcGIS Server service, an on-premise server, a local service, or a table from a local geodatabase. The query can contain a Where clause with SQL syntax and can be a spatial query (for example, geometries intersecting an envelope). To query a service, use com.esri.core.tasks.query.QueryTask. To query a table in a local geodatabase, use the query methods on the GeodatabaseFeatureTable class.

When retrieving features, you have a few options on how the results can 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 example, if the queried data's spatial reference is different from the spatial reference of the map on which you want to display the features. For queries on services you can also choose the feature attributes to be included in the results so that information is not retrieved unnecessarily. Similarly, for a more efficient application, do not return the geometries from remote services unless you want to analyze or display them. Options that apply to all queries include sorting the results by field values (ascending or descending) and grouping the results by field values in order to calculate statistics.

Using related tables, you can also query for features in a table which are related to features or non-spatial records in your map or service - see Query related tables for more information.

Specify the query's input parameters

Define your query by setting a number of parameters on a QueryParameters class instance. This QueryParameters instance can then be used as input to either a QueryTask or a local GeodatabaseFeatureTable's query methods.

To create the QueryParameters, follow these basic guidelines:

  • To perform a spatial query, provide a Geometry using the setGeometry method.
  • To perform an attribute query, set the Where clause using the setWhere method.
  • To examine or display the resulting features' geometries, call setReturnGeometry(true). This setting applies to QueryTask used on services. A GeodatabaseFeatureTable always returns geometries.
  • Only return fields that you require by passing in the field names to the setOutFields method. This setting applies to QueryTask used on services. A GeodatabaseFeatureTable always returns all field values.

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

Use the QueryTask

Complete the following steps to perform a query on a layer using the QueryTask class:

  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 of the task as above.
  3. Execute the task synchronously or asynchronously.
  4. Listen for the completion of the task and process the results.

Obtain the URL to the service layer

Obtain the URL of the online or local map or feature service layer that will be queried. The URL for a local map service layer can be obtained from the ArcGISLocalDynamicMapServiceLayer instance once it has been created using the path to a map package.

Learn more about map packages

// code to obtain the URL to layer 0 in a map package.
ArcGISLocalDynamicMapServiceLayer localDynamicMapServiceLayer = 
    new ArcGISLocalDynamicMapServiceLayer("/path/to/map_package.mpk");
String layerURL = localDynamicMapServiceLayer.getURL() + "/0"
// URL to an online layer (layer 5 of the ESRI_Census_USA map server)
String layerURL = 
  "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/" +
  "Demographics/ESRI_Census_USA/MapServer/5";

Instantiate the QueryTask

Instantiate the QueryTaskclass, passing the map service layer's URL to the task's constructor.

QueryTask queryTask = new QueryTask(layerURL);

Execute the QueryTask asynchronously

Asynchronous execution of the QueryTask is performed using the executeAsync method using the previously defined QueryParameters class as input. You also need to define a callback listener into which the results will be passed as a FeatureResult. If you execute the task asynchronously, the application will remain responsive during the execution of the task. Asynchronous execution is the recommended method of execution for most queries. Conversely, if you execute the task synchronously, the application will be paused while the task is executing. Synchronous execution is only recommended if the query is reliably rapid and the resultant set of features is small.

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

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

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

    // Process each feature from the result 
    for (Object record : featureResult) {
      Feature feature = (Feature)record;
    }
});

Use GeodatabaseFeatureTable's query methods

Complete the following steps to perform a query on a GeodatabaseFeatureTable:

  1. Specify the input parameters of the task as above.
  2. Execute the query asynchronously.
  3. Listen for the completion of the task and process the results.

Query for features

A query on a GeodatabaseFeatureTable is always performed asynchronously. Pass the previously defined QueryParameters as input to the queryFeatures or queryIds methods.

GeodatabaseFeatureTable geodatabaseFeatureTable;
QueryParameters query = new QueryParameters();
query.setWhere("OBJECTID < 5");

geodatabaseFeatureTable.queryFeatures(query, new CallbackListener<FeatureResult>() {

  @Override
  public void onError(Throwable e) {
    // handle / show error as desired
  }
      
  @Override
  public void onCallback(FeatureResult featureResult) {
    for (Object record : featureResult) {
      Feature feature = (Feature) record;
      // process results further
    }        
  }
});

Process the results

The results from both the QueryTask for queries on services, and the queryFeatures method on a local geodatabase feature table are returned in a FeatureResult. A FeatureResult will typically contain Features. A FeatureResult will contain statistics and not features if you have called setOutStatistics() or setGroupByFieldsForStatistics() methods on your QueryParameters. The following code shows how to process a FeatureResult with features:

// process each feature from the result 
for (Object record : featureResult) {
  Feature feature = (Feature) record;
}

The following code shows how to process a FeatureResult with statistics and groups only:

for (Object record : featureResult) {
  Map<String, Object> statistics = (Map<String, Object>) record;
  String groupByValue = (String) statistics.get(GROUP_BY_FIELD);
  double statisticValue = (Double) statistics.get(OUT_STATISTIC_FIELD);
  ...
}

Query disconnected feature caches in a WebMap

Starting at version 10.2, you can search a WebMap layer that has a disconnected feature cache. Typically, this means that the web map displays a tiled layer that does not have search capability, so the WebMap instance also references a layer from a feature service that can be searched. Web maps achieve this by enabling pop-up windows on hosted tiled map services without feature data, as described in Enabling and removing pop-up windows. ArcGIS Runtime SDK for Java achieves this search capability by storing the URL of the feature layer to be queried within the ArcGISTiledMapServiceLayer created from the WebMap. Obtain this URL as in the code snippet below, then follow the same workflow as described in the steps for using the query task, above.

ArcGISTiledMapServiceLayer tiledLayerFromWebMap;
// Get the tiled layer from the WebMap
...

// Get the URL to a feature layer defined by sub-layer 0 of this tiled layer
String queryLayerURL = tiledLayerFromWebMap.getQueryLayerUrl(0);

Sample code

To view samples related to querying data, launch the ArcGIS Runtime SDK for Java sample viewer application installed with the SDK. Explore the interactive samples and their code in the Search section.