Query for layers and features

The QueryTask allows you to retrieve features from a single layer or table in an ArcGIS for Server map service or feature service. The task also allows you to query metadata of an ArcGIS for Server image service that is based on a mosaic dataset.

A layer in a map or feature service can be one of two types: a vector layer, also known as a feature layer, or a raster layer. A vector layer stores geographic data in the form of shapes or vectors. A raster layer stores data in the form of imagery. The QueryTask works with vector layers, not raster layers. In some cases, a vector layer may not store any geographic data and may only contain attribute data. In such cases, the layer can be considered a table. The QueryTask also works with tables. When a vector layer is queried, the results are features that contain geometry information. When a table is queried, the results are features without geometry information.

ArcGIS for Server map, feature, and image services are accessible on the web as SOAP and REST web services. These services provide the operations that the QueryTask relies on. For example, a layer in a map service provides Query and Query Related Records operations. While publishing a service, the administrator can disable some operations. Verify that the REST resource you intend to use supports the necessary operations.

You can use the ArcGIS Server Services Directory to find details about the service you want to use, and you can determine which query operations are supported.

Query operations

If you're familiar with the ArcGIS Server REST API, you can invoke query operations directly from a browser using the Services Directory.

Use the QueryTask in your application

To instantiate a QueryTask, provide a URL to REST resources that support query operations. If the service is secured, provide the credentials that can be used to access the service.

ServiceREST resource supporting query operationsURL example

Map service

Vector layer or table


Feature service

Vector layer or table


Image service

Image service


The QueryTask does not specify the user interface; therefore, you need to implement the functionality to allow users to define the user input and display the geometries and attributes of the results in the application. There are numerous ways that the user can provide inputs to the process with the user interface of your application. The user might select features on a map, type a value in a text box, or select a value from a list box. The results can be displayed in various ways, such as in a DataGrid, through MapTips, populating a list box, or displaying as graphics in a graphics layer.

Use the QueryTask with online data

To use the QueryTask with online data, you must pass the URL of a service, or of a layer in a service. To find the URL, you can use the ArcGIS Services Directory. The following code snippet shows how to create a QueryTask for the states layer in the ESRI_Census_USA map service on ArcGIS Online:

// Construct the QueryTask to an online service
m_queryTask = new EsriRuntimeQt::QueryTask(
    "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5", this);

Use the QueryTask with local server data

Create a new ArcGISLocalMapService with the path to an ArcGIS map package.

// Construct a LocalMapService using a local map package file
QString dataPath = pathSampleData + "mpks" + QDir::separator() + "USCitiesStates.mpk";
m_localMapService = EsriRuntimeQt::LocalMapService(dataPath);

// Connect the service creation success and failure signals
connect(&m_localMapService, SIGNAL(serviceCreationSuccess(QString,QString)),
        this, SLOT(onServiceCreationSuccess(QString,QString)));
connect(&m_localMapService, SIGNAL(serviceCreationFailure(QString)),
        this, SLOT(onServiceCreationFailure(QString)));

// Asynchronously Start the LocalMapService

Implement a slot to process the onServiceCreationSuccess signal.

// Slot for successful start signal for LocalMapService
void TestQuery::onServiceCreationSuccess(const QString& url, const QString& name)

  // Create the ArcGISDynamicMapServiceLayer using the LocalMapService's URL
  if (name.compare("USCitiesStates.mpk", Qt::CaseSensitive) == 0)
    m_dynamicServiceLayer = new EsriRuntimeQt::ArcGISDynamicMapServiceLayer(m_localMapService.urlMapService(), this);

Also implement a slot for the onServiceCreationFailure signal.

// Slot for failed start signal for LocalMapService
void TestQuery::onServiceCreationFailure(const QString& name)
		// Produce simple warning
  qWarning() << name + " failed to start";
  qWarning() << m_localMapService.error().what();

Set the map service layer that the task will query by passing the map service's URL and the layer ID to the task's constructor (or by setting the Url property).

// Construct a QueryTask using the layer's URL, and execute a query with it
  m_queryTask = new EsriRuntimeQt::QueryTask(m_dynamicServiceLayer->url() + "/2");

  // Connect signals to slots (see QueryTask API doc)
  // ...

  // Execute the query

Input parameters

Before using one of the QueryTask's operations, you need to define the input parameters. Input parameters vary depending on the operation. The Query object is used to define the execution parameters for QueryTasks. The following is an example of initializing a Query class .

Declare a Query object. Set the geometry and spatial reference properties.

// Construct a Query and set its geometry
  EsriRuntimeQt::Query query;
To draw the query results on the map, specify that the query should return geometry with the results.
// This query should return feature geometry
Define the fields to return with the results. Here you specify that the query should return the city name and population fields. Only the fields required by your application should be returned so that network traffic is minimized.
// Define a list of attribute fields to return
query.setOutFields(QStringList() << "STATE_NAME" << "POP2000");
Specify the SQL WHERE clause for the query. The WHERE clause defines the conditions that features must satisfy to be returned in the query results. For example: where=POP2000 > 350000
// Define the WHERE clause
query.setWhere("POP2000 > 350000");


To access the results of an asynchronous query operation, connect the queryTaskComplete signal to the onQueryTaskComplete slot. This slot is invoked when a query operation is complete. A FeatureSet containing the features that satisfy the query is passed to the slot for processing.

// Connect the signal and slot...
connect(m_queryTask, SIGNAL(queryTaskComplete(const EsriRuntimeQt::FeatureSet&)), 
        this, SLOT(onQueryTaskComplete(const EsriRuntimeQt::FeatureSet&)));

// . . .

// Slot to handle queryTaskComplete signal
void TestQuery::onQueryTaskComplete(const EsriRuntimeQt::FeatureSet* featureSet)
  static const QStringList attrNames = QStringList() << "STATE_NAME" << "SUB_REGION" << "STATE_FIPS" << "STATE_ABBR" << "POP2000" << "POP2007";

  // If there are no records in the result, then return.
  if (!featureSet || featureSet->graphics().length() < 1)
    m_table->setRowCount(1);  // m_table is a QTableWidget*
    m_table->setItem(0, 0, new QTableWidgetItem("< No records found! >"));

  // Add attributes of all states obtained after executing the query.
  foreach (EsriRuntimeQt::Graphic* state, featureSet->graphics())
    int nRowCount = m_table->rowCount();

    // Get attributes' value in the same order as the header.
    int nCol = 0;
    foreach (QString attrName, attrNames)
      m_table->setItem(nRowCount, nCol++, new QTableWidgetItem(state->attributeValue(attrName).toString()));

There are various output interfaces available to display the results in your application. To display the results on the map, you can loop through the features found, create a graphic for each feature, and display the graphic on the map by adding it to a graphics layer.