Feature layer query

View on GitHub
Sample viewer app

Find features in a feature table which match an SQL query.

Feature layer query options Feature layer query results

Use case

Query expressions can be used in ArcGIS to select a subset of features from a feature table. This is most useful in large or complicated data sets. A possible use case might be on a feature table marking the location of street furniture through a city. A user may wish to query by a TYPE column to return "benches". In this sample, we query a U.S. state by STATE_NAME from a feature table containing all U.S. states.

How to use the sample

Input the name of a U.S. state into the text field. A query is performed and the matching features are highlighted or an error is returned.

How it works

  1. Create an AGSServiceFeatureTable using the URL of a feature service.
  2. Create AGSQueryParameters with a whereClause specified.
  3. Perform the query using AGSFeatureTable.queryFeatures(with:completion:) on the service feature table.
  4. When complete, the query will return an AGSFeatureQueryResult which can be iterated over to get the matching features.

Relevant API

  • AGSFeatureLayer
  • AGSFeatureQueryResult
  • AGSQueryParameters
  • AGSServiceFeatureTable

About the data

This sample uses U.S. State polygon features from the USA 2016 Daytime Population feature service.

Tags

query, search

Sample Code

FLQueryViewController.swift
                                                                                                                     
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
// Copyright 2016 Esri.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import UIKit
import ArcGIS

class FLQueryViewController: UIViewController, UISearchBarDelegate {
    @IBOutlet private weak var mapView: AGSMapView!

    private var featureTable: AGSServiceFeatureTable?
    private var featureLayer: AGSFeatureLayer?

    private var selectedFeatures = [AGSFeature]()

    override func viewDidLoad() {
        super.viewDidLoad()

        // add the source code button item to the right of navigation bar
        (navigationItem.rightBarButtonItem as! SourceCodeBarButtonItem).filenames = ["FLQueryViewController"]

        // initialize map with topographic basemap
        let map = AGSMap(basemapStyle: .arcGISTopographic)
        // assign map to the map view
        mapView.map = map

        /// The url of a map service layer containing sample census data of United States counties.
        let statesFeatureTableURL = URL(string: "https://services.arcgis.com/jIL9msH9OI208GCb/arcgis/rest/services/USA_Daytime_Population_2016/FeatureServer/0")!
        // create feature table using a url
        let featureTable = AGSServiceFeatureTable(url: statesFeatureTableURL)
        self.featureTable = featureTable

        // create feature layer using this feature table
        let featureLayer = AGSFeatureLayer(featureTable: featureTable)
        self.featureLayer = featureLayer
        // show the layer at all scales
        featureLayer.minScale = 0
        featureLayer.maxScale = 0

        // set a new renderer
        let lineSymbol = AGSSimpleLineSymbol(style: .solid, color: .black, width: 1)
        let fillSymbol = AGSSimpleFillSymbol(style: .solid, color: UIColor.yellow.withAlphaComponent(0.5), outline: lineSymbol)
        featureLayer.renderer = AGSSimpleRenderer(symbol: fillSymbol)

        // add feature layer to the map
        map.operationalLayers.add(featureLayer)

        // center the layer
        mapView.setViewpointCenter(AGSPoint(x: -11e6, y: 5e6, spatialReference: .webMercator()), scale: 9e7)
    }

    func selectFeaturesForSearchTerm(_ searchTerm: String) {
        guard let featureLayer = featureLayer,
            let featureTable = featureTable else {
                return
        }

        // deselect all selected features
        if !selectedFeatures.isEmpty {
            featureLayer.unselectFeatures(selectedFeatures)
            selectedFeatures.removeAll()
        }

        let queryParams = AGSQueryParameters()
        queryParams.whereClause = "upper(STATE_NAME) LIKE '%\(searchTerm.uppercased())%'"

        featureTable.queryFeatures(with: queryParams) { [weak self] (result: AGSFeatureQueryResult?, error: Error?) in
            guard let self = self else {
                return
            }

            if let error = error {
                // display the error as an alert
                self.presentAlert(error: error)
            } else if let features = result?.featureEnumerator().allObjects {
                if !features.isEmpty {
                    // display the selection
                    featureLayer.select(features)

                    // zoom to the selected feature
                    self.mapView.setViewpointGeometry(features.first!.geometry!, padding: 25)
                } else {
                    if let fullExtent = featureLayer.fullExtent {
                        // no matches, zoom to show everything in the layer
                        self.mapView.setViewpointGeometry(fullExtent, padding: 50)
                    }
                }

                // update selected features array
                self.selectedFeatures = features
            }
        }
    }

    // MARK: - Search bar delegate

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        if let text = searchBar.text {
            selectFeaturesForSearchTerm(text)
        }
        searchBar.resignFirstResponder()
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchBar.resignFirstResponder()
    }
}

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