Query a feature layer (SQL)

Learn how to execute a SQL query to return features from a feature layer based on spatial and attribute criteria.

query a feature layer

A feature layer can contain a large number of features stored in ArcGIS. You can query a layer to access a subset of its features using any combination of spatial and attribute criteria. You can control whether or not each feature's geometry is returned, as well as which attributes are included in the results. Queries allow you to return a well-defined subset of your hosted data for analysis or display in your ArcGIS Runtime app.

In this tutorial, you'll write code to perform SQL queries that return a subset of features in the LA County Parcel feature layer (containing over 2.4 million features). Features that meet the query criteria are selected in the map.

Prerequisites

The following are required for this tutorial:

  1. An ArcGIS account to access API keys. If you don't have an account, sign up for free.
  2. Your system meets the system requirements.
  3. The ArcGIS Runtime API for Qt is installed.

Steps

Open the project in Qt Creator

  1. To start this tutorial, complete the Display a map tutorial or download and unzip the solution.

  2. Open the display_a_map project in Qt Creator.

  3. If you downloaded the Display a map solution, set your API key.

    An API Key enables access to services, web maps, and web scenes hosted in ArcGIS Online.

    1. Go to your developer dashboard to get your API key. For these tutorials, use your default API key. It is scoped to include all of the services demonstrated in the tutorials.

    2. In the Projects window, in the Sources folder, open the main.cpp file.

    3. Modify the code to set the API key. Paste the API key, acquired from your dashboard, between the quotes. Then save and close the file.

      main.cpp
      Expand
      Use dark colors for code blocks
      39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 40 41 42 43 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44
      Change line
      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
          // 2. API key: A permanent key that gives your application access to Esri
          // location services. Create a new API key or access existing API keys from
          // your ArcGIS for Developers dashboard (https://links.esri.com/arcgis-api-keys).
      
          const QString apiKey = QString("");
      
      Expand

Update the header file

This app will use various functions and member variables that need to be declared in the header file.

  1. In Projects, double-click Headers > Display_a_map.h to open the file.

  2. Forward declare the following classes.

    Display_a_map.h
    Use dark colors for code blocks
                                                                 
    Add line.Add line.
    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
    namespace ArcGISRuntime
    {
    class Map;
    class MapQuickView;
    
    class FeatureLayer;
    class ServiceFeatureTable;
    
  3. Add the following code to define a function called runQuery that will be invokable from the GUI.

    Display_a_map.h
    Use dark colors for code blocks
                                                                 
    Add line.
    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
    public:
        explicit Display_a_map(QObject* parent = nullptr);
        ~Display_a_map() override;
    
        Q_INVOKABLE void runQuery(const QString& expression);
    
  4. Declare the following private functions and member variables.

    Display_a_map.h
    Use dark colors for code blocks
                                                                 
    Add line.Add line.Add line.Add line.
    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
    private:
        Esri::ArcGISRuntime::MapQuickView* mapView() const;
        void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView);
        void setupViewpoint();
    
        void addFeatureLayer();
        void selectFeatures();
        Esri::ArcGISRuntime::FeatureLayer* m_featureLayer = nullptr;
        Esri::ArcGISRuntime::ServiceFeatureTable* m_featureTable = nullptr;
    

Include header files in the source code

To create this app you will need to include several class header files from the ArcGIS Runtime Qt C++ API.

  1. In Projects, double-click Sources > Display_a_map.cpp to open the file.

  2. Add the following include statements. Each of these classes are needed for this tutorial.

    Display_a_map.cpp
    Use dark colors for code blocks
                                                                                                                                
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    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
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    #include "MapQuickView.h"
    #include <QUrl>
    
    #include "FeatureLayer.h"
    #include "SpatialReference.h"
    #include "ServiceFeatureTable.h"
    #include "Viewpoint.h"
    #include "Point.h"
    #include "QueryParameters.h"
    #include "FeatureQueryResult.h"
    #include "Feature.h"
    #include "SelectionProperties.h"
    #include <QColor>
    #include <QList>
    #include <memory>
    

Add a feature layer, query features, and select results

You will add three functions to add a feature layer from ArcGIS online, execute a query of that layer, and create a features list from the query result.

  1. Add code to create the addFeatureLayer function. This function adds the LA_County_Parcels feature layer hosted on ArcGIS Online to the map.

    Display_a_map.cpp
    Use dark colors for code blocks
                                                                                                                                
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    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
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    void Display_a_map::setupViewpoint()
    {
        const Point center(-118.80543, 34.02700, SpatialReference::wgs84());
        const Viewpoint viewpoint(center, 100000.0);
        m_mapView->setViewpoint(viewpoint);
    }
    
    void Display_a_map::addFeatureLayer()
    {
        // Create a ServiceFeatureTable from a QUrl.
        m_featureTable = new ServiceFeatureTable(QUrl("https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0"), this);
        // Create the feature layer using the feature table.
        m_featureLayer = new FeatureLayer(m_featureTable, this);
        // Add the feature layer to the map.
        m_map->operationalLayers()->append(m_featureLayer);
    }
    
  2. Add the following function to implement the query. The runQuery function executes a query of the parcels layer. This function creates a QueryParameters object that includes the currently visible map extent and a SQL expression, and then executes the query on the parcels table. Note that the SQL expression will come from a ComboBox that you will implement in a coming step.

    Display_a_map.cpp
    Use dark colors for code blocks
                                                                                                                                
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    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
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    void Display_a_map::addFeatureLayer()
    {
        // Create a ServiceFeatureTable from a QUrl.
        m_featureTable = new ServiceFeatureTable(QUrl("https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0"), this);
        // Create the feature layer using the feature table.
        m_featureLayer = new FeatureLayer(m_featureTable, this);
        // Add the feature layer to the map.
        m_map->operationalLayers()->append(m_featureLayer);
    }
    
    void Display_a_map::runQuery(const QString& expression)
    {
        if (!m_featureTable)
            return;
    
        // Create a query parameter object and set the WhereClause.
        QueryParameters queryParams;
        queryParams.setGeometry(m_mapView->currentViewpoint(ViewpointType::BoundingGeometry).targetGeometry().extent());
        queryParams.setWhereClause(expression);
        m_featureTable->queryFeatures(queryParams);
    }
    
  3. Next, add the selectFeatures function. When a query completes, this code iterates the returned results and adds those features to a list. That list is then used to select features in the parcels layer.

    Display_a_map.cpp
    Use dark colors for code blocks
                                                                                                                                
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    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
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    void Display_a_map::runQuery(const QString& expression)
    {
        if (!m_featureTable)
            return;
    
        // Create a query parameter object and set the WhereClause.
        QueryParameters queryParams;
        queryParams.setGeometry(m_mapView->currentViewpoint(ViewpointType::BoundingGeometry).targetGeometry().extent());
        queryParams.setWhereClause(expression);
        m_featureTable->queryFeatures(queryParams);
    }
    
    void Display_a_map::selectFeatures()
    {
        connect(m_featureTable, &ServiceFeatureTable::queryFeaturesCompleted, this, [this](QUuid, FeatureQueryResult* rawQueryResult)
        {
            if (!rawQueryResult)
                return;
    
            // Wrap the FeatureQueryResult in a unique_ptr to manage the memory effectively.
            auto queryResult = std::unique_ptr<FeatureQueryResult>(rawQueryResult);
    
            // Clear any existing selection.
            m_featureLayer->clearSelection();
            QList<Feature*> features;
    
            // Iterate over the result object.
            while(queryResult->iterator().hasNext())
            {
                Feature* feature = queryResult->iterator().next(this);
                // Add each feature to the list.
                features.append(feature);
            }
            // Select features.
            m_featureLayer->selectFeatures(features);
        });
    }
    
  4. By default, selected features in the map view are displayed in cyan. Modify the setMapView function to call your new functions and also set the color for displaying selected parcel layer features (or any other selection) in your map view. Then save the file.

    Display_a_map.cpp
    Expand
    Use dark colors for code blocks
                                                                                                                                
    Add line.Add line.Add line.
    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
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    // Set the view (created in QML)
    void Display_a_map::setMapView(MapQuickView* mapView)
    {
        if (!mapView || mapView == m_mapView)
        {
            return;
        }
        m_mapView = mapView;
        m_mapView->setMap(m_map);
    
        addFeatureLayer();
        selectFeatures();
        m_mapView->setSelectionProperties(SelectionProperties(QColor(Qt::yellow)));
    
    Expand

Show a list of query expressions for the user to choose from

You will create a UI that allows the user to choose from a list of predefined query expressions. The expressions are presented in a ComboBox control and when the user makes a choice, the expression is passed to the runQuery method to find parcels that meet the selected criterion within the currently visible map extent.

  1. In Projects, double-click Resources > qml\qml.qrc/qml/Display_a_mapForm.qml to open the file.

  2. Add the following code to create a ComboBox control to execute a predefined query expression.

    Display_a_map.qml
    Expand
    Use dark colors for code blocks
                                                               
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    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
        // Declare the C++ instance that creates the map etc., and supply the view.
        Display_a_map {
            id: model
            mapView: view
        }
    
        ComboBox {
            id: queryComboBox
            anchors {
                left: parent.left
                top: parent.top
                margins: 15
            }
    
            property int bestWidth: implicitWidth
            width: bestWidth + indicator.width + leftPadding + rightPadding
            model: ["Choose a SQL where clause",
                "UseType = 'Government'",
                "UseType = 'Residential'",
                "UseType = 'Irrigated Farm'",
                "TaxRateArea = 10853",
                "TaxRateArea = 10860",
                "Roll_LandValue > 1000000",
                "Roll_LandValue < 1000000"]
    
            onCurrentTextChanged: {
                model.runQuery(queryComboBox.currentText)
            }
        }
    
    Expand
  3. Press <Ctrl+R> to run the app.

The app loads with the map centered on the Santa Monica Mountains in California with the parcels feature layer displayed. Choose an attribute expression, and parcels in the current extent that meet the selected criteria will display in the specified selection color.

What's next?

Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials:

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