Skip To Content

Edit features

In this topic

You can let users edit features while online (connected) or offline (disconnected). Editing includes adding new features, deleting features, and updating existing features by changing their geometry (location or shape), attributes, or attachments. There are two models for editing features: feature table editing and feature layer editing. This topic focuses on feature table editing. For an introduction to editing and the editing models, see Editing.

Whether you are online or offline, the workflow to edit features is similar. In both cases, you need to do the following:

  1. Create a feature table—In a connected workflow, create it from a feature service. In a disconnected workflow, create it from a geodatabase you generated with a sync-enabled feature service before you went offline, as described in Create an offline map.
  2. Create a feature layer from the feature table and add the layer to the map.
  3. Perform any edits against the feature table (add, update, and delete features and feature attachments).
  4. Commit your edits—In a connected workflow, apply any edits you make to the feature service right away. In a disconnected workflow, sync all your edits back to the service once you have a network connection, as described in Sync offline edits.

In a connected workflow, the type of feature table you create and edit is an AGSGDBFeatureServiceTable. In a disconnected workflow, the type of feature table you create and edit is an AGSGDBFeatureTable.

The methods to add, update, and delete features and feature attachments are common to the AGSGDBFeatureTable and AGSGDBFeatureServiceTable classes. Therefore, all the methods you have at your disposal to edit in an offline workflow are also available for an online workflow, since AGSGDBFeatureServiceTable is a child of AGSGDBFeatureTable. The AGSGDBFeatureServiceTable used in connected editing provides additional methods to apply feature edits and attachment edits back to the service. You should apply any edits to the service as soon as you have made them on your feature table.

To update or delete features, your app should enable users to select features on the map, as described below in Select features.

Create a feature table

Before you can edit features, you need to obtain feature data from a feature service. In an online workflow, create a feature table from a feature service right before you want to edit features, for example, on application load. In an offline workflow, generate a geodatabase from a sync-enabled feature service while you have a network connection, in preparation for editing features offline. When offline, create feature tables from the geodatabase to edit the features locally. In both cases, check the capabilities of the feature service to ensure the editing capability is available.

Online

In an online workflow, create a geodatabase feature service table (AGSGDBFeatureServiceTable class) from a feature service. You can then create a feature layer using this feature table. Once you add the feature layer to a map, features in the map extent are added to the feature service table and can be edited. As you pan and zoom the map (that is, change the map extent), more features are retrieved from the feature service and added to the geodatabase feature service table.

Note:

The number of features you see when you initially visit a new area of the map is limited by the feature service's MaxRecordCount property (the default value for this property is 1,000). Pan and zoom to query the service for more features. Once features are retrieved from the service and visible in your map, they are available in your geodatabase feature service table for editing and querying.

As part of initializing an AGSGDBFeatureServiceTable instance, you can set the table's spatial reference by using the spatialReference property. If you do not explicitly set the spatial reference of the table this way, the spatial reference of the service will be used. However, if your map is in a different spatial reference than your AGSGDBFeatureServiceTable, your features will not appear on the map, so it is good practice to always set the spatial reference explicitly. Alternatively, you can set your table's spatial reference to the spatial reference of your map once the mapViewDidLoad delegate method is fired, meaning the map has its spatial reference set.

//header
@property (nonatomic,strong) AGSGDBFeatureServiceTable *featureServiceTable;

//implementation file
//create the feature service table from the feature service url
//explicitly set the spatial reference
self.featureServiceTable = [[AGSGDBFeatureServiceTable alloc] 
 initWithServiceURL:featureLayerURL 
 credential:nil 
 spatialReference:[AGSSpatialReference webMercatorSpatialReference]];

Offline

In an offline workflow, generate a geodatabase from a sync-enabled feature service while you have a network connection. Follow the geodatabase generation process described in Create an offline map. This process results in a geodatabase stored locally on disk. The geodatabase contains one or more feature tables, one for each service layer or service table that you requested in the geodatabase generation process. When offline, create geodatabase feature tables from the geodatabase, for example, on application load. The features in the geodatabase feature tables are available for editing whether you create a feature layer or not, but in most cases you'll want to create a feature layer from the feature tables to display the features on a map. Also, consider generating an offline basemap to give the feature data some geographical context when your users edit offline, as described in Include a basemap.

The following code sample shows how to create a feature table from a local geodatabase:

//header file
@property (strong) AGSGDBGeodatabase *geodatabase;
@property (strong) AGSGDBFeatureTable *localFeatureTable;

//implementation file 
NSError *error = nil;

//create the geodatabase from a file on disk    
self.geodatabase = [[AGSGDBGeodatabase alloc]initWithPath:@"" error:&error];

//create the local feature table from the first layer in the geodatabase
self.localFeatureTable = [[geodatabase featureTables] objectAtIndex:0];

Add layers to the map

Display the features contained in the feature table in a map so your users can view and edit them. Create a feature layer from the feature table and add the layer to a map. The feature layer, once added to a map, takes care of displaying the features contained in your feature table that fall within the map extent displayed. When you make edits to features in the table, these edits are visible right away in the associated feature layer and map, but not yet committed back to the service.

The following code sample shows how to create a feature layer from a feature table:

//header file
@property (strong) AGSGDBFeatureTable *localFeatureTable;
@property (strong) AGSGDBFeatureServiceTable *featureServiceTable;
@property (strong) AGSFeatureTableLayer *featureTableLayer;

//implementation file

//from the feature service table (online)
self.featureTableLayer = [[AGSFeatureTableLayer alloc] 
 initWithFeatureTable:self.featureServiceTable];

//from local geodatabase table (offline)
weakSelf.localFeatureTableLayer = [[AGSFeatureTableLayer alloc] 
 initWithFeatureTable: self.localFeatureTable];

//add the layer to the map
self.featureTableLayer.delegate = self;	
[self.mapView addMapLayer:self.featureTableLayer withName:@"Feature Layer"];

Add features

To add or insert new features into a geodatabase table, create the geometry (for example, point, line, or polygon) and attributes for the new feature, and then call the saveFeature:error: method. This method returns a BOOL indicating whether the operation was a success. It also populates an NSError object by reference if an error was encountered. Adding a feature to a geodatabase table is shown in the code below:

//Create a geometry
AGSPoint *point = [[AGSPoint alloc]initWithX:-117 y: 50 spatialReference:[AGSSpatialReference wgs84SpatialReference]];

//Instantiate a new feature
AGSGDBFeature *feature = [[AGSGDBFeature alloc]initWithTable:localFeatureTable];

//Set the geometry
[feature setGeometry:point];

//Add the feature to the AGSGDBFeatureTable
NSError* err;
BOOL success = [localFeatureTable saveFeature:feature error:&err];

if (success){
	NSLog(@"Success adding this objectId : %ld", (long)r.objectId);
 }
else {
 NSLog(@"Fail. Investigate this error : %@", [error localizedDescription]);
}

Update features

Features can be updated with the saveFeature:error: method on the AGSGDBFeatureTable.

The code sample below shows a method that updates a point feature in the geodatabase feature table with a new point geometry, changing its location on the map.

//Set the geometry
[feature setGeometry:point];

//Update the feature
NSError* err;
BOOL success = [self.localFeatureTable saveFeature:feature error:&err];

if (success){
	NSLog(@"Success updating this feature : %ld", (long)r.objectId);
 }
else {
 NSLog(@"Fail. Investigate this error : %@", [error localizedDescription]);
}

Delete features

Features are deleted using the deleteFeature:error: method. The following code snippet deletes a feature from the geodatabase:

NSError* err;
BOOL success = [self.localFeatureTable deleteFeature:arrayOfFeatures error:&err];

if (success){
	NSLog(@"Success deleting feature");
 }
else {
 NSLog(@"Fail. Investigate this error : %@", [error localizedDescription]);
}

Select features

In a typical map application involving editing, users should be able to select features to edit. The user may select features by tapping a location or a feature on the map, or by choosing a set of features using a query. Once you know which features to select, you can programmatically select them using the setSelected:forFeature: method. The following code snippet shows how to select features in response to a user tapping on the map:

//Subscribe to the AGSMapViewTouchDelegate protocol and set the delegate to self
self.mapView.touchDelegate = self;

//In the method for clicking at a point on the map
-(void)mapView:(AGSMapView *)mapView didClickAtPoint:(CGPoint)screen mapPoint:(AGSPoint *)mappoint features:(NSDictionary *)features
{
    [self.localFeatureTableLayer clearSelection];
    if (features){
        for (AGSGDBFeature *feature in [features valueForKey:@"Offline Feature Layer"]) {
            [self.localFeatureTableLayer setSelected:YES forFeature:feature];
        }
    }
}

Commit your edits

Committing your feature table edits to the feature service is different depending on whether your workflow is fully connected or disconnected.

Online

In a fully connected workflow, you should apply feature edits and attachment edits back to the service as you make them. That way, anyone else using the same feature service will have access to your changes right away.

To commit your local feature edits to the service, call the applyFeatureEditsWithCompletion method. Optionally, you can list the current locally edited features by using the addedFeatures, updatedFeatures(), and deletedFeatures methods. Changes to the features returned by those three methods will be committed to the service on a call to applyFeatureEditsWithCompletion. Once the edits have been applied, newly added features will be given the server-generated object ID. The applyFeatureEditsWithCompletion method is asynchronous; any errors from this method call will be returned in the completion block as a array of featureEditErrors objects (or attachmentEditErrors).

//First apply feature edits then attachment edits (if there are any	
[self.featureServiceTable applyFeatureEditsWithCompletion:^(NSArray *featureEditErrors, NSError *error) 
 {...
  if (no featureEditErrors) {            			
   [weakSelf.featureServiceTable applyAttachmentEditsWithCompletion:^(NSArray *attachmentEditErrors, NSError *error2) 
    {...
     if (no attachmentEditErrors) {
      ...success!
     }
    }
   ]
  }
 }
];

Note:

For descriptions of errors that can arise during edit commits, go to the Apply Edits (Feature Service) topic and click the error code link in the Description section.

Offline

In a disconnected workflow, commit all edits back to the service, and optionally pull the latest changes from the service back to your geodatabase through a sync operation, as described in Sync offline edits. Syncing requires a network connection; therefore, do this when you are back online. Note that the edits that are last committed to the service will overwrite previously committed edits, even if committed edits were made at a later time.

Related topics