Add or delete related features on an origin feature.
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
- Create an
AGSServiceFeatureTable
from a URL. - Create an
AGSFeatureLayer
from the service feature table. - Add the feature layer to the map's
operationalLayers
array. - Add a related feature by using the
AGSFeatureTable.createFeature(attributes:geometry:)
method on the the related feature table. - Relate the new feature to the origin feature using the
AGSArcGISFeature.relate(to:)
method onAGSFeature
then add it to the related feature table. - To delete a related feature, use the
delete(_:completion:)
method on the related feature table. - 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
//
// 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
}
}
}