Query

A query provides the ability to return a subset of features from a dataset based on any combination of attribute, spatial, and temporal (time) criteria.

  • Attribute criteria are defined with a standard SQL expression based on the available attribute fields.
  • Spatial criteria use a geometry and a spatial relationship (within, contains, intersect, and so on).
  • A temporal filter can be defined using a single date or time, or a range.

You can also perform queries to return related features, a feature count, an extent containing all features meeting your criteria, or statistical information about a dataset.

How query works

Query criteria is defined using a query parameters object. This is where you specify the attribute, spatial, and/or temporal inputs. Most ArcGIS Runtime queries take query parameters as an input to define the query criteria as well as some preferences for the results. When the query is executed against a specific dataset (feature table), results are returned as a collection of features.

A query does not require that each type of criteria be defined. Query criteria are only evaluated if explicitly defined (missing temporal criteria, for example, means not to filter the results according to time).

Relevant classes and members in the API ref

Query parameters

Query parameters define the query criteria using:

  • An SQL expression for attribute criteria
  • Geometry and a spatial relationship for spatial criteria
  • A date/time or a range of dates/times for temporal criteria

Some spatial relationships you can define for the query include:

  • Intersects: part of a feature is contained in the geometry.
  • Touches: a feature touches the border of the geometry.
  • Crosses: a feature crosses the geometry.
  • Within: a feature is completely enclosed by the geometry.
  • Contains: part or all of a feature is contained within the geometry.

The query parameters can be used in a standard query to return features, or in queries that return a feature count or extent. You can also use the query parameters to make a selection in the map showing the features that match the criteria.

Specialized query parameters are used for queries that return statistics or related features. In addition to query criteria, these query parameters define things like the type of statistics to return or the relationships to evaluate.

The following code snippet selects a set of features that have a specific attribute value. First, a query executes against the FeatureTable.

                                                                                                                 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// --- Edit ---

// connect to the mouse clicked signal on the MapQuickView
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
    // obtain the map point
    Point newPoint = m_mapView->screenToLocation(mouseEvent.x(), mouseEvent.y());


    // create the feature attributes
    QMap<QString, QVariant> featureAttributes;
    featureAttributes.insert("typdamage", "Minor");
    featureAttributes.insert("primcause", "Earthquake");


    // create a new feature and add it to the feature table
    Feature* feature = m_featureTable->createFeature(featureAttributes,newPoint,this);
    m_featureTable->addFeature(feature);
});



foreach (Feature* feature, selectedFeatures)
{
  feature->attributes()->replaceAttribute("TraumaLevel", 101);
}


currentTaskId = hospitalTable->updateFeatures(selectedFeatures).taskId();



currentTaskId = hospitalTable->deleteFeatures(selectedFeatures).taskId();


// --- Query ---


QueryParameters query;
query.setWhereClause("TraumaLevel=99");
currentTaskId = hospitalLayer->selectFeatures(query, SelectionMode::New).taskId();


QUuid selectTaskId;
FeatureQueryResult* selectFeaturesResult = nullptr;
connect(hospitalLayer, &FeatureLayer::selectFeaturesCompleted, this,
        [this, &selectFeaturesResult, &selectTaskId]
        (QUuid taskId, FeatureQueryResult* featureQueryResult)
{
  selectTaskId = taskId;
  selectFeaturesResult = featureQueryResult;
  // ...


QList<Feature*> selectedFeatures;
while (selectFeaturesResult->iterator().hasNext())
{
  selectedFeatures.append(selectFeaturesResult->iterator().next());
}



// TODO:



// TODO:



// TODO:



// lambda expression for the mouse press event on the mapview... do an identify operation
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
    double tolerance = 22.0;
    bool returnPopupsOnly = false;
    int maximumResults = 1000;
    m_mapView->identifyLayer(m_featureLayer, mouseEvent.x(), mouseEvent.y(), tolerance, returnPopupsOnly, maximumResults);
});


// once the identify is done
connect(m_mapView, &MapQuickView::identifyLayerCompleted, this, [this](QUuid, Esri::ArcGISRuntime::IdentifyLayerResult* identifyResult)
{
    if (!identifyResult)
      return;


    // clear any existing selection
    m_featureLayer->clearSelection();


    // create a list to store the identified elements
    QList<Feature*> identifiedFeatures;
    for (int i = 0; i < identifyResult->geoElements().size(); i++)
    {
        GeoElement* element = identifyResult->geoElements().at(i);
        if (static_cast<Feature*>(element))
            // add the element to the list
            identifiedFeatures.append(static_cast<Feature*>(element));
    }


    // select the identified features
    m_featureLayer->selectFeatures(identifiedFeatures);
    // update the member with the number of selected features
    int count = identifiedFeatures.length();
    m_selectedFeatureText = count > 1 ? QString::number(count) + " features selected." : QString::number(count) + " feature selected.";
    emit selectedFeatureTextChanged();
});

When the signal ServiceFeatureTable::selectFeaturesDone emits, it contains the results of the selection.

                                                                                                                 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// --- Edit ---

// connect to the mouse clicked signal on the MapQuickView
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
    // obtain the map point
    Point newPoint = m_mapView->screenToLocation(mouseEvent.x(), mouseEvent.y());


    // create the feature attributes
    QMap<QString, QVariant> featureAttributes;
    featureAttributes.insert("typdamage", "Minor");
    featureAttributes.insert("primcause", "Earthquake");


    // create a new feature and add it to the feature table
    Feature* feature = m_featureTable->createFeature(featureAttributes,newPoint,this);
    m_featureTable->addFeature(feature);
});



foreach (Feature* feature, selectedFeatures)
{
  feature->attributes()->replaceAttribute("TraumaLevel", 101);
}


currentTaskId = hospitalTable->updateFeatures(selectedFeatures).taskId();



currentTaskId = hospitalTable->deleteFeatures(selectedFeatures).taskId();


// --- Query ---


QueryParameters query;
query.setWhereClause("TraumaLevel=99");
currentTaskId = hospitalLayer->selectFeatures(query, SelectionMode::New).taskId();


QUuid selectTaskId;
FeatureQueryResult* selectFeaturesResult = nullptr;
connect(hospitalLayer, &FeatureLayer::selectFeaturesCompleted, this,
        [this, &selectFeaturesResult, &selectTaskId]
        (QUuid taskId, FeatureQueryResult* featureQueryResult)
{
  selectTaskId = taskId;
  selectFeaturesResult = featureQueryResult;
  // ...


QList<Feature*> selectedFeatures;
while (selectFeaturesResult->iterator().hasNext())
{
  selectedFeatures.append(selectFeaturesResult->iterator().next());
}



// TODO:



// TODO:



// TODO:



// lambda expression for the mouse press event on the mapview... do an identify operation
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
    double tolerance = 22.0;
    bool returnPopupsOnly = false;
    int maximumResults = 1000;
    m_mapView->identifyLayer(m_featureLayer, mouseEvent.x(), mouseEvent.y(), tolerance, returnPopupsOnly, maximumResults);
});


// once the identify is done
connect(m_mapView, &MapQuickView::identifyLayerCompleted, this, [this](QUuid, Esri::ArcGISRuntime::IdentifyLayerResult* identifyResult)
{
    if (!identifyResult)
      return;


    // clear any existing selection
    m_featureLayer->clearSelection();


    // create a list to store the identified elements
    QList<Feature*> identifiedFeatures;
    for (int i = 0; i < identifyResult->geoElements().size(); i++)
    {
        GeoElement* element = identifyResult->geoElements().at(i);
        if (static_cast<Feature*>(element))
            // add the element to the list
            identifiedFeatures.append(static_cast<Feature*>(element));
    }


    // select the identified features
    m_featureLayer->selectFeatures(identifiedFeatures);
    // update the member with the number of selected features
    int count = identifiedFeatures.length();
    m_selectedFeatureText = count > 1 ? QString::number(count) + " features selected." : QString::number(count) + " feature selected.";
    emit selectedFeatureTextChanged();
});

Retrieve the selected features from the results.

                                                                                                                 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// --- Edit ---

// connect to the mouse clicked signal on the MapQuickView
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
    // obtain the map point
    Point newPoint = m_mapView->screenToLocation(mouseEvent.x(), mouseEvent.y());


    // create the feature attributes
    QMap<QString, QVariant> featureAttributes;
    featureAttributes.insert("typdamage", "Minor");
    featureAttributes.insert("primcause", "Earthquake");


    // create a new feature and add it to the feature table
    Feature* feature = m_featureTable->createFeature(featureAttributes,newPoint,this);
    m_featureTable->addFeature(feature);
});



foreach (Feature* feature, selectedFeatures)
{
  feature->attributes()->replaceAttribute("TraumaLevel", 101);
}


currentTaskId = hospitalTable->updateFeatures(selectedFeatures).taskId();



currentTaskId = hospitalTable->deleteFeatures(selectedFeatures).taskId();


// --- Query ---


QueryParameters query;
query.setWhereClause("TraumaLevel=99");
currentTaskId = hospitalLayer->selectFeatures(query, SelectionMode::New).taskId();


QUuid selectTaskId;
FeatureQueryResult* selectFeaturesResult = nullptr;
connect(hospitalLayer, &FeatureLayer::selectFeaturesCompleted, this,
        [this, &selectFeaturesResult, &selectTaskId]
        (QUuid taskId, FeatureQueryResult* featureQueryResult)
{
  selectTaskId = taskId;
  selectFeaturesResult = featureQueryResult;
  // ...


QList<Feature*> selectedFeatures;
while (selectFeaturesResult->iterator().hasNext())
{
  selectedFeatures.append(selectFeaturesResult->iterator().next());
}



// TODO:



// TODO:



// TODO:



// lambda expression for the mouse press event on the mapview... do an identify operation
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
    double tolerance = 22.0;
    bool returnPopupsOnly = false;
    int maximumResults = 1000;
    m_mapView->identifyLayer(m_featureLayer, mouseEvent.x(), mouseEvent.y(), tolerance, returnPopupsOnly, maximumResults);
});


// once the identify is done
connect(m_mapView, &MapQuickView::identifyLayerCompleted, this, [this](QUuid, Esri::ArcGISRuntime::IdentifyLayerResult* identifyResult)
{
    if (!identifyResult)
      return;


    // clear any existing selection
    m_featureLayer->clearSelection();


    // create a list to store the identified elements
    QList<Feature*> identifiedFeatures;
    for (int i = 0; i < identifyResult->geoElements().size(); i++)
    {
        GeoElement* element = identifyResult->geoElements().at(i);
        if (static_cast<Feature*>(element))
            // add the element to the list
            identifiedFeatures.append(static_cast<Feature*>(element));
    }


    // select the identified features
    m_featureLayer->selectFeatures(identifiedFeatures);
    // update the member with the number of selected features
    int count = identifiedFeatures.length();
    m_selectedFeatureText = count > 1 ? QString::number(count) + " features selected." : QString::number(count) + " feature selected.";
    emit selectedFeatureTextChanged();
});

Query results

Query results typically provide a collection of features. You can iterate the result features to display them on the map, read their attributes, and so on. A query for statistics returns a collection of records that describe the requested statistics for features in the dataset. Queries for feature count or extent return a number and an envelope respectively.

Geometry for the query results can be returned in a specified spatial reference by specifying the output spatial reference in the query parameters. If a spatial reference is not specified, results will be returned in the spatial reference of the dataset. Most often, you will need the result features in the same spatial reference as your app's map.

You can also set a maximum number of features to return in the result. This is useful in situations where you might only need a subset of features that meet your criteria. It may also improve performance by limiting the amount of information returned with the result.

Identify

Identify is like a shortcut for a spatial query. It allows you to quickly answer the question: what is here? It gives users a quick way to explore and learn about the map or scene content by tapping or clicking. Information returned from an identify operation can be shown in pop-ups or other UI components in your app. Unlike a query, you can't provide attribute or time criteria to filter results. You can, however, return all geoelements (from all layers) at the specified location.

                                                                                                                 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// --- Edit ---

// connect to the mouse clicked signal on the MapQuickView
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
    // obtain the map point
    Point newPoint = m_mapView->screenToLocation(mouseEvent.x(), mouseEvent.y());


    // create the feature attributes
    QMap<QString, QVariant> featureAttributes;
    featureAttributes.insert("typdamage", "Minor");
    featureAttributes.insert("primcause", "Earthquake");


    // create a new feature and add it to the feature table
    Feature* feature = m_featureTable->createFeature(featureAttributes,newPoint,this);
    m_featureTable->addFeature(feature);
});



foreach (Feature* feature, selectedFeatures)
{
  feature->attributes()->replaceAttribute("TraumaLevel", 101);
}


currentTaskId = hospitalTable->updateFeatures(selectedFeatures).taskId();



currentTaskId = hospitalTable->deleteFeatures(selectedFeatures).taskId();


// --- Query ---


QueryParameters query;
query.setWhereClause("TraumaLevel=99");
currentTaskId = hospitalLayer->selectFeatures(query, SelectionMode::New).taskId();


QUuid selectTaskId;
FeatureQueryResult* selectFeaturesResult = nullptr;
connect(hospitalLayer, &FeatureLayer::selectFeaturesCompleted, this,
        [this, &selectFeaturesResult, &selectTaskId]
        (QUuid taskId, FeatureQueryResult* featureQueryResult)
{
  selectTaskId = taskId;
  selectFeaturesResult = featureQueryResult;
  // ...


QList<Feature*> selectedFeatures;
while (selectFeaturesResult->iterator().hasNext())
{
  selectedFeatures.append(selectFeaturesResult->iterator().next());
}



// TODO:



// TODO:



// TODO:



// lambda expression for the mouse press event on the mapview... do an identify operation
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
    double tolerance = 22.0;
    bool returnPopupsOnly = false;
    int maximumResults = 1000;
    m_mapView->identifyLayer(m_featureLayer, mouseEvent.x(), mouseEvent.y(), tolerance, returnPopupsOnly, maximumResults);
});


// once the identify is done
connect(m_mapView, &MapQuickView::identifyLayerCompleted, this, [this](QUuid, Esri::ArcGISRuntime::IdentifyLayerResult* identifyResult)
{
    if (!identifyResult)
      return;


    // clear any existing selection
    m_featureLayer->clearSelection();


    // create a list to store the identified elements
    QList<Feature*> identifiedFeatures;
    for (int i = 0; i < identifyResult->geoElements().size(); i++)
    {
        GeoElement* element = identifyResult->geoElements().at(i);
        if (static_cast<Feature*>(element))
            // add the element to the list
            identifiedFeatures.append(static_cast<Feature*>(element));
    }


    // select the identified features
    m_featureLayer->selectFeatures(identifiedFeatures);
    // update the member with the number of selected features
    int count = identifiedFeatures.length();
    m_selectedFeatureText = count > 1 ? QString::number(count) + " features selected." : QString::number(count) + " feature selected.";
    emit selectedFeatureTextChanged();
});

Samples

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.