How to create features in the geodatabase


Summary
This article explains how to create features in a geodatabase feature class. Two methods are shown, one which creates an individual feature using the IFeatureClass.CreateFeature and IFeature.Store methods, and one which uses and insert cursor to execute a bulk load.

In this topic


Creating features in the geodatabase

The functionality available for feature creation is dependent on the following:
For more information on the geodatabase functionality available at different licensing levels, see ArcView 9 and the geodatabase.
There are two primary methods for creating features in the geodatabase: CreateFeature and Store and Insert cursors. The following are the primary differences between the two methods:

Using the CreateFeature and Store methods

The CreateFeature method is used to create individual features in the geodatabase. It has the effect of assigning a system-generated ObjectID (OID), which is the value of the OIDField. Use the IFeature.Store method to actually store this new feature in the database.
This basic process to create a new feature is used independently of whether the feature is created in a point, line, or polygon feature class or in a feature class participating in a geometric network or topology. See the following steps:
  1. Creating the feature—Calling the CreateFeature method on a feature class has the same effect as calling the CreateRow method on the ITable interface, except that the IFeatureClass method returns a reference to the IFeature interface representing the returned row object. The OID of the feature is available once the CreateFeature method is called. See the following illustration:
  2. Create the geometry for the feature—One of the fundamental differences between a feature and a row object is the association between a feature and a geometry. There are many different ways to create the geometry for the feature. For guidelines on creating geometries, see How to efficiently create a polyline and How to efficiently create a polygon.
  3. Store the geometry in the feature—Use the IFeature.Shape property to store the geometry with the feature. See the following illustration:
  4. Set the subtype, initialize any default values, and set other field values—After calling CreateFeature, the default subtype value is not automatically set nor are default values initialized. For features without a subtype that have defined default values, calling IRowSubtypes.InitDefaultValues initializes the default values. For features created within a feature class containing subtypes, use IRowSubtypes.SubtypeCode to set the subtype value for features before calling IRowSubtypes.InitDefaultValues to ensure the default values are set for the particular subtype.

    After initializing the default values, the remaining field values can be set through the IFeature.Value property. If the field values are not correct for the type of field, an error is raised. However, if the field is too small to accept the defined value, an error is raised after the call to Store. See the following illustration:
  5. Store the feature—The feature is not written to the database until the IFeature.Store method has been called. Once Store has been called, all subsequent queries in the same edit session, using the geodatabase application programming interface (API), will reflect the modified state of the feature. See the following illustration:
Once the Store method is called, the following actions are triggered:
  • The IRowEvents.OnChanged is called for the row being stored. The OnNew method is called if this is a newly created row being stored for the first time. A custom row object can implement the OnChanged method and take some special action when it is called; for example, updating a special column in the row.
  • The IRelatedObjectEvents.RelatedObjectChanged method is called for related objects in a related object class if the table for this row is an object class that participates in relationship classes with notification.
It is not necessary to explicitly call Connect on network features or create and associate network elements with network features. All network behavior is handled by the through object behavior when Store is called on the feature. This is also the case with features in a topology; dirty area creation is handled internally when Store is called.
Store should not be called inside edit events, such as OnCreateFeature, OnChangeFeature, or OnDeleteFeature. Even if you are modifying the geometry or other field values, Store is called once the event is complete.
CreateFeature and Store methods important information
Calling the CreateFeature method on a feature class has the same effect as calling the CreateRowmethod on the ITable interface on the feature class, except that the IFeatureClassmethods return a reference to the IFeature interface corresponding to the returned row object.
When working with a versioned feature class, CreateFeature should only be called in an edit session. You can start an edit session by calling IWorkspaceEdit.StartEditing or IMultiuserWorkspaceEdit.StartMultiuserEditing. All edits to features that participate in a topology, geometric network, terrain, or representation must be performed in an edit session and bracketed in an edit operation.
The following code example demonstrates how to use the IFeatureClass.CreateFeature method and IFeature.Store to create a new feature in a feature class containing fittings:
[Java]
static void createFeature(IFeatureClass featureClass, IPoint point)throws Exception{
    // Ensure the feature class contains points.
    if (featureClass.getShapeType() != esriGeometryType.esriGeometryPoint){
        return ;
    }
    // Build the feature.
    IFeature feature = featureClass.createFeature();
    feature.setShapeByRef(point);
    // Apply the appropriate subtype to the feature.
    ISubtypes subtypes = (ISubtypes)featureClass;
    IRowSubtypes rowSubtypes = (IRowSubtypes)feature;
    if (subtypes.isHasSubtype())
    { // Does the feature class have subtypes?
        rowSubtypes.setSubtypeCode(3); 
            //In this example 3 represents the Cross subtype.
    }
    // Initialize any default values that the feature has.
    rowSubtypes.initDefaultValues();
    // Update the value on a string field that indicates who installed the feature.
    int contractorFieldIndex = featureClass.findField("CONTRACTOR");
    feature.setValue(contractorFieldIndex, "K Johnston");
    // Commit the new feature to the geodatabase.
    // If edit sessions are to be used, this is where one should be started.
    feature.store();
}

Insert cursors

The Insert method returns an insert cursor, which can be used for bulk insertion of rows or features. It offers significantly faster performance than multiple calls to CreateFeature and Store for tables and feature classes storing simple rows and simple features. Simple rows and features are those class identifiers (CLSIDs), such as esriGeoDatabase.Row, esriGeoDatabase.Object, or esriGeoDatabase.Feature. Insert cursors on table and feature classes containing custom rows use CreateFeature and Store, negating the performance benefits of an insert cursor when creating features. See the following illustration:
The IFeatureCursor interface provides access to a set of features in a feature class. It operates in the same way as ICursor, although it does not inherit from that interface. This saves you from having to cast when dealing with features rather than rows.
Calling the CreateFeatureBuffer method in IFeatureClass has the same effect as calling the CreateRowBuffer interface in ITable, except that the IFeatureClass methods return an IFeatureBuffer interface on the created row buffer.  
Insert cursors important information
Feature cursors can be used as an input to IFeatureCursorBuffer, which lets you spatially buffer the features by a distance. Do not confuse this interface with IFeatureBuffer, which applies to data buffers used with insert and update feature cursors. You can draw the features from a cursor on the display. For more information, see the IFeatureRenderer.Draw method.
For more information on insert cursors and cursor use within the geodatabase, see How to use cursors in the geodatabase.
The following code example uses a FeatureBuffer to buffer two sets of 99 inserts into a table. These inserts are stored in a buffer and only flushed when Flush is called:
[Java]
static void createBulkFeatures(IFeatureClass featureClass, List < IGeometry >
    geometryList)throws Exception{
    // Create the feature buffer.
    IFeatureBuffer featureBuffer = featureClass.createFeatureBuffer();
    // Create insert feature cursor using buffering.
    IFeatureCursor featureCursor = featureClass.IFeatureClass_insert(true);
    // All of the features to be created were installed by "B Pierce."
    int contractorFieldIndex = featureClass.findField("CONTRACTOR");
    featureBuffer.setValue(contractorFieldIndex, "B Pierce");
    for (IGeometry geometry: geometryList){
        //Set the feature buffer's shape and insert it.
        featureBuffer.setShapeByRef(geometry);
        featureCursor.insertFeature(featureBuffer);
    }
    // Attempt to flush the buffer
    featureCursor.flush();
    // Release the cursor as it's no longer needed
    Cleaner.release(featureCursor);
}
When using insert cursors, you can override the default behavior, instructing the geodatabase to fire events when features are created through an insert cursor with the use of the IWorkspaceEditControl.SetStoreEventsRequired method.


See Also:

How to use cursors in the geodatabase
How to efficiently create a polyline
How to efficiently create a polygon