Select features in feature layer

View on GitHub

Select features in a feature layer.

Screenshot of select features in feature layer sample

Use case

Selecting features, whether by query or identify, can be an important step both in editing data and in visualizing results. One possible use case would be to query a feature layer containing street furniture. A query might look for type "bench" and return a list of bench features contained in the features with an attribute of type bench. These might be selected for further editing or may just be highlighted visually.

How to use the sample

Tap on a feature in the map. All features within a given tolerance (in points) of the tap will be selected.

How it works

  1. Create a FeatureLayer instance from a portal item (feature layer or feature service) and add it to the map's operational layers.
  2. Create instances of MapViewReader and MapView.
  3. Asynchronously identify nearby features at the tapped location from the map view using the MapViewProxy.identify(layer:screenPoint:tolerance:maximumResults:) method.
  4. Select all identified features in the feature layer with FeatureLayer.select(features:).

Relevant API

  • Feature
  • FeatureLayer
  • MapViewProxy
  • MapViewReader

About the data

This sample uses the Gross Domestic Product Per Capita, 1960-2016 feature service. Only the 2016 GDP values are shown.

Tags

features, layers, select, selection, tolerance

Sample Code

SelectFeaturesInFeatureLayerView.swift
Use dark colors for code blocksCopy
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
// Copyright 2022 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
//
//   https://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 SwiftUI
import ArcGIS

struct SelectFeaturesInFeatureLayerView: View {
    /// The selected features.
    @State private var selectedFeatures: [Feature] = []

    /// The point indicating where to identify features.
    @State private var identifyPoint: CGPoint?

    /// The error shown in the error alert.
    @State private var error: Error?

    /// The view model for the sample.
    @StateObject private var model = Model()

    var body: some View {
        MapViewReader { mapViewProxy in
            MapView(map: model.map)
                .onSingleTapGesture { screenPoint, _ in
                    identifyPoint = screenPoint
                }
                .task(id: identifyPoint) {
                    guard let identifyPoint = identifyPoint else { return }

                    do {
                        // Unselects the selected features.
                        model.gdpPerCapitaLayer.unselectFeatures(selectedFeatures)

                        // Saves the results from the identify method on the map view proxy.
                        let results = try await mapViewProxy.identify(
                            on: model.gdpPerCapitaLayer,
                            screenPoint: identifyPoint,
                            tolerance: 12,
                            maximumResults: 10
                        )

                        // Updates the selected features to the geo elements from the results.
                        selectedFeatures = results.geoElements as! [Feature]

                        // Selects the features from the selected features array.
                        model.gdpPerCapitaLayer.selectFeatures(selectedFeatures)
                    } catch {
                        // Updates the error and shows an alert.
                        self.error = error
                    }
                }
                .overlay(alignment: .top) {
                    Text("\(selectedFeatures.count) feature(s) selected.")
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 6)
                        .background(.thinMaterial, ignoresSafeAreaEdges: .horizontal)
                }
                .errorAlert(presentingError: $error)
        }
    }
}

private extension SelectFeaturesInFeatureLayerView {
    /// The model used to store the geo model and other expensive objects
    /// used in this view.
    class Model: ObservableObject {
        /// A feature layer visualizing GDP per capita.
        let gdpPerCapitaLayer = FeatureLayer(
            item: PortalItem(
                portal: .arcGISOnline(connection: .anonymous),
                id: .gdpPerCapita
            )
        )

        /// A map with a topographic basemap style and a feature layer.
        let map: Map

        init() {
            map = Map(basemapStyle: .arcGISTopographic)
            map.addOperationalLayer(gdpPerCapitaLayer)
        }
    }
}

private extension PortalItem.ID {
    static var gdpPerCapita: Self { Self("10d76a5b015647279b165f3a64c2524f")! }
}

#Preview {
    SelectFeaturesInFeatureLayerView()
}

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