Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for Qt

Query map image sublayer

Sample Viewer View Sample on GitHub

Find features in a sublayer based on attributes and location.

Use case

Sublayers of an ArcGISMapImageLayer may expose a ServiceFeatureTable through a table property. This allows you to perform the same queries available when working with a table from a FeatureLayer: attribute query, spatial query, statistics query, query for related features, etc. An image layer with a sublayer of counties can be queried by population to only show those above a minimum population.

How to use the sample

Specify a minimum population in the input field (values under 1810000 will produce a selection in all layers) and click the query button to query the sublayers in the current view extent. After a short time, the results for each sublayer will appear as graphics.

How it works

  1. Create an ArcGISMapImageLayer object using the URL of an image service.
  2. After loading the layer, get the sublayer you want to query with (ArcGISMapImageSublayer) layer.mapImageSublayers.get(index).
  3. Load the sublayer, and then get its ServiceFeatureTable with sublayer.table.
  4. Create QueryParameters. You can use queryParameters.whereClause = sqlQueryString to query against a table attribute and/or set queryParameters.geometry = extent to limit the results to an area of the map.
  5. Call sublayerTable.queryFeatures(queryParameters) to get a FeatureQueryResult with features matching the query. The result is an iterable of features.

Relevant API

  • ArcGISMapImageLayer
  • ArcGISMapImageLayer.loadTablesAndLayers
  • ArcGISMapImageSublayer
  • ArcGISMapImageSublayer.table
  • QueryParameters
  • ServiceFeatureTable

Additional information

An ArcGISMapImageSublayer must be loaded before accessing its metadata or table. Use ArcGISMapImageLayer.loadTablesAndLayers to recursively load all sublayers and tables associated with a map image layer. Some sublayers do not have an associated table (group layers, for example) and some may not support specific types of queries. Consult the map service metadata for details.


MapServer, Query, Sublayer, Table

Sample Code

import QtQuick 2.6
import QtQuick.Controls 2.2
import Esri.ArcGISRuntime 100.9

Rectangle {
    id: rootRectangle
    clip: true
    width: 800
    height: 600
    property var citiesTable
    property var  statesTable
    property var  countiesTable

    // Declare a MapView
    MapView {
        id: mapView
        anchors.fill: parent

        // Desclare a Map inside the MapView
        Map {
            // Declare a Basemap
            BasemapStreetsVector {}

            // Add a Map Image Layer
            ArcGISMapImageLayer {
                url: ""

                // Once the layer loads, load the tables and sublayers
                onLoadStatusChanged: {
                    if (loadStatus !== Enums.LoadStatusLoaded)


                // Once tables and sublayers load, obtain the tables and connect signals
                onLoadTablesAndLayersStatusChanged: {
                    if (loadTablesAndLayersStatus !== Enums.TaskStatusCompleted)

                    if (mapImageSublayers.count < 4)

                    // get the sublayer's tables
                    citiesTable = mapImageSublayers.get(0).table;
                    statesTable = mapImageSublayers.get(2).table;
                    countiesTable = mapImageSublayers.get(3).table;

                    // connect to city sublayer query signal
                    citiesTable.queryFeaturesStatusChanged.connect(()=> {
                        if (citiesTable.queryFeaturesStatus !== Enums.TaskStatusCompleted)

                        // add the results as graphics
                        addResultsAsGraphics(citiesTable.queryFeaturesResult, citySymbol);

                    // connect to county sublayer query signal
                    countiesTable.queryFeaturesStatusChanged.connect(()=> {
                        if (countiesTable.queryFeaturesStatus !== Enums.TaskStatusCompleted)

                        // add the results as graphics
                        addResultsAsGraphics(countiesTable.queryFeaturesResult, countyFillSymbol);

                    // connect to state sublayer query signal
                    statesTable.queryFeaturesStatusChanged.connect(()=> {
                        if (statesTable.queryFeaturesStatus !== Enums.TaskStatusCompleted)

                        // add the results as graphics
                        addResultsAsGraphics(statesTable.queryFeaturesResult, stateFillSymbol);

            // set an initial viewpoint
            ViewpointCenter {
                targetScale: 6000000
                Point {
                    x: -12716000.00
                    y: 4170400.00
                    spatialReference: SpatialReference { wkid: 3857 }

        // Add a graphics overlay to show selected features
        GraphicsOverlay {
            id: selectedFeaturesOverlay

    function addResultsAsGraphics(results, symbol) {
        // get the iterator of features
        const iter = results.iterator;
        // add a graphic for each feature in the result
        while (iter.hasNext) {
            const feat =;
            const graphic = ArcGISRuntimeEnvironment.createObject("Graphic",
                                                                      geometry: feat.geometry,
                                                                      symbol: symbol

    Rectangle {
        anchors {
            fill: controlColumn
            margins: -5
        color: "#efefef"
        radius: 5
        border {
            color: "darkgray"
            width: 1

    Column {
        id: controlColumn
        anchors {
            left: parent.left
            margins: 10
        spacing: 5

        Row {
            spacing: 5
            Text {
                id: fieldText
                anchors.verticalCenter: parent.verticalCenter
                text: "POP2000 >"

            TextField {
                id: populationText
                anchors.verticalCenter: parent.verticalCenter
                width: 100
                text: "1100000"
                selectByMouse: true
                validator: IntValidator{}

        Button {
            anchors.horizontalCenter: parent.horizontalCenter
            text: "Query in extent"
            onClicked: {
                if (!citiesTable || !countiesTable || !statesTable)


                // create the parameters
                const queryParams = ArcGISRuntimeEnvironment.createObject("QueryParameters",
                                                                              whereClause: fieldText.text + populationText.text,
                                                                              geometry: mapView.currentViewpointExtent.extent

                // query the feature tables

    SimpleMarkerSymbol {
        id: citySymbol
        color: "red"
        size: 16
        style: Enums.SimpleMarkerSymbolStyleCircle

    SimpleFillSymbol {
        id: countyFillSymbol
        style: Enums.SimpleFillSymbolStyleDiagonalCross
        color: "cyan"

        SimpleLineSymbol {
            style: Enums.SimpleLineSymbolStyleDash
            color: "cyan"
            width: 2

    SimpleFillSymbol {
        id: stateFillSymbol
        color: "transparent"

        SimpleLineSymbol {
            id: stateLineSymbol
            color: "darkcyan"
            width: 6