Add delete related features

View on GitHubSample viewer app

Add or delete related features on an origin feature.

Map of parks List of related features

Use case

Adding or deleting related features is a helpful workflow when you have two features with shared or dependent attributes. In this scenario, you can add or remove to a list of species that exist within a national park.

How to use the sample

Tap on a park in the map view. A list of species as related features will be shown. Tap on the top left button to add a new species to the park. Drag a row from right to left to delete a species from the park.

How it works

  1. Create an AGSServiceFeatureTable from a URL.
  2. Create an AGSFeatureLayer from the service feature table.
  3. Add the feature layer to the map's operationalLayers array.
  4. Add a related feature by using the AGSFeatureTable.createFeature(attributes:geometry:) method on the the related feature table.
  5. Relate the new feature to the origin feature using the AGSArcGISFeature.relate(to:) method on AGSFeature then add it to the related feature table.
  6. To delete a related feature, use the delete(_:completion:) method on the related feature table.
  7. Apply the edits using applyEdits(completion:) on the feature table.

Relevant API

  • AGSArcGISFeature.relate(to:)
  • AGSFeatureLayer
  • AGSFeatureTable.createFeature(attributes:geometry:)
  • AGSServiceFeatureTable

Tags

editing, features, service, updating

Sample Code

AddDeleteRelatedFeaturesViewController.swiftAddDeleteRelatedFeaturesViewController.swiftRelatedFeaturesViewController.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
102
103
104
105
//
// 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 AddDeleteRelatedFeaturesViewController: UIViewController, AGSGeoViewTouchDelegate {
    @IBOutlet var mapView: AGSMapView!

    private var parksFeatureTable: AGSServiceFeatureTable!
    private var parksFeatureLayer: AGSFeatureLayer!

    private var selectedPark: AGSFeature!

    override func viewDidLoad() {
        super.viewDidLoad()

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

        // initialize map with basemap
        let map = AGSMap(basemapStyle: .arcGISStreets)

        // initial viewpoint
        let point = AGSPoint(x: -16507762.575543, y: 9058828.127243, spatialReference: .webMercator())

        // parks feature table
        self.parksFeatureTable = AGSServiceFeatureTable(url: URL(string: "https://services2.arcgis.com/ZQgQTuoyBrtmoGdP/ArcGIS/rest/services/AlaskaNationalParksSpecies_Add_Delete/FeatureServer/0")!)

        // parks feature layer
        let parksFeatureLayer = AGSFeatureLayer(featureTable: self.parksFeatureTable)

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

        // species feature table (destination feature table)
        // related to the parks feature layer in a 1..M relationship
        let speciesFeatureTable = AGSServiceFeatureTable(url: URL(string: "https://services2.arcgis.com/ZQgQTuoyBrtmoGdP/ArcGIS/rest/services/AlaskaNationalParksSpecies_Add_Delete/FeatureServer/1")!)

        // add table to the map
        // for the related query to work, the related table should be present in the map
        map.tables.add(speciesFeatureTable)

        // assign map to map view
        mapView.map = map
        mapView.setViewpoint(AGSViewpoint(center: point, scale: 36764077))

        // set touch delegate
        mapView.touchDelegate = self

        // store the feature layer for later use
        self.parksFeatureLayer = parksFeatureLayer
    }

    // MARK: - AGSGeoViewTouchDelegate

    func geoView(_ geoView: AGSGeoView, didTapAtScreenPoint screenPoint: CGPoint, mapPoint: AGSPoint) {
        // show progress hud for identify
        UIApplication.shared.showProgressHUD(message: "Identifying feature")

        // identify features at tapped location
        self.mapView.identifyLayer(self.parksFeatureLayer, screenPoint: screenPoint, tolerance: 12, returnPopupsOnly: false) { [weak self] (result) in
            // hide progress hud
            UIApplication.shared.hideProgressHUD()

            if let error = result.error {
                // show error to user
                self?.presentAlert(error: error)
            } else if let feature = result.geoElements.first as? AGSFeature {
                // select the first feature
                self?.selectedPark = feature

                // show related features view controller
                self?.performSegue(withIdentifier: "RelatedFeaturesSegue", sender: self)
            }
        }
    }

    // MARK: - Navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "RelatedFeaturesSegue",
            let navigationController = segue.destination as? UINavigationController,
            let controller = navigationController.viewControllers.first as? RelatedFeaturesViewController {
            // share selected park
            controller.originFeature = self.selectedPark as? AGSArcGISFeature

            // share parks feature table as origin feature table
            controller.originFeatureTable = self.parksFeatureTable
        }
    }
}

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