How to create new fields


Summary
This article discusses the process for building a fields collection, adding a single field to an existing feature class, accessing and modifying a field's GeometryDef (before it is associated with a feature class), getting the minimum required fields for a feature class, and adding user-defined fields to the fields collection.

In this topic


Building the fields collection

When modifying fields, the restrictions that apply in ArcCatalog also apply in ArcObjects; for example, you cannot change the field name or field type.
The following code example uses IFieldsEdit to create a new fields collection. IFieldEdit is used to modify the properties of a newly created IField that is added to the fields collection. The resulting fields collection can be used to create a table in a geodatabase. However, when you read further in this article, a better alternative than starting from scratch is discussed.
In the following code example, note the use of IFieldsEdit.FieldCount_2 to set the number of fields that will be added to the fields collection.
[Java]
public IFields createFieldsCollectionForTable()throws Exception{
    // Create a new fields collection.
    IFields fields = new Fields();
    // Cast for IFieldsEdit to modify the properties of the fields collection.
    IFieldsEdit fieldsEdit = (IFieldsEdit)fields;
    // Set the FieldCount to the total number of fields to be created.
    fieldsEdit.setFieldCount(2);
    // Create the ObjectID field.
    IField fieldUserDefined = new Field();
    // Cast for IFieldEdit to modify the properties of the new field.
    IFieldEdit fieldEdit = (IFieldEdit)fieldUserDefined;
    fieldEdit.setAliasName("FID");
    fieldEdit.setName("ObjectID");
    fieldEdit.setType(esriFieldType.esriFieldTypeOID);
    // Add the new field to the fields collection.
    fieldsEdit.setFieldByRef(0, fieldUserDefined);
    // Create the text field.
    fieldUserDefined = new Field();
    fieldEdit = (IFieldEdit)fieldUserDefined;
    fieldEdit.setLength(30); //Only string fields require that you set the length.
    fieldEdit.setName("Owner");
    fieldEdit.setType(esriFieldType.esriFieldTypeString);
    // Add the new field to the fields collection.
    fieldsEdit.setFieldByRef(1, fieldUserDefined);
    return fields;
}
When a field is created, the editable property is set to true by default. If the editable property has been set to false, it cannot be reset to true. However, an editable property set to true can be changed to false.
Adding a single field to an existing feature class or table
The IClass.AddField method (inherited on ITable, IObjectClass, and IFeatureClass) can be used to add a single field to an existing table. The following line of code shows the addition of a field (for example, the created string field) to a feature class. As with any schema editing, an exclusive lock should be established on the class first (ISchemaLock). See the following code example:
[Java]
static void addFieldToFeatureClass(IFeatureClass featureClass, IField field)throws
    Exception{
    ISchemaLock schemaLock = (ISchemaLock)featureClass;
    // A try block is necessary, as an exclusive lock may not be available.
    schemaLock.changeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
    // Add the field.
    featureClass.addField(field);
    // Set the lock to shared, whether or not an error occurred.
    schemaLock.changeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
}

Modifying the GeometryDef object

The GeometryDef object defines the spatial qualities of a feature class. The most fundamental spatial quality is the geometry type; for example, point, line, and polygon. Other necessary information to define the feature class includes the spatial referencing system; whether the vertices have height or measure data; and for geodatabases, the spatial index parameters.
The GeometryDef coclass can be accessed from a shape field with a field of type esriFieldTypeGeometry. The actual geometry type is defined by the esriGeometryType enumeration, although currently, only the following five values are acceptable with respect to GeometryDef objects:
Beware of the confusion between the esriGeometryType enumeration and the similarly named esriFeatureType (feature types defined by feature class extensions) and esriShapeType (geometry type of a shapefile). Although similarly named the former is for geodatabase feature classes while the later is used only for shapefiles.
IGeometryDef
The IGeometryDef interface establishes read-only access to the GeometryDef properties. The following code shows how to get to IGeometryDef from a feature class:
[Java]
static void getIGeometryDef(IFeatureClass featureClass)throws Exception{
    // The code shows how to get to IGeometryDef from a feature class.
    // First, determine the name of the shape field.
    String shapeFieldName = featureClass.getShapeFieldName();

    // Get the feature class fields collection.
    IFields fields = featureClass.getFields();

    // Find the index that represents the shape field's place in the collection.
    int geometryIndex = fields.findField(shapeFieldName);

    // Use the index value to get the field.
    IField field = fields.getField(geometryIndex);

    // Finally, from the field ask for the GeometryDef.
    IGeometryDef geometryDef = field.getGeometryDef();
}
The AverageNumPoints, GridCount, and GridSize properties are all attributes of the geodatabase spatial index. Personal geodatabase feature classes only support a single grid, while file and ArcSDE geodatabases both support multiple grid levels. Shapefiles will return zero for the GridCount.
The IGeometryDefEdit interface is used when creating a GeometryDef object. You normally use this interface when defining a new feature class.
You cannot use IGeometryDefEdit to modify an existing GeometryDef object that is attached to a feature class. Use IGeoDatasetSchemaEdit to make these changes.

Getting the minimum required fields for a feature class

The IFeatureClassDescription interface in conjunction with IObjectClassDescription can be used to obtain the minimum required fields for both object classes (tables) or feature classes.
The following code example shows IGeometryDefEdit being used to edit the GeometryDef object on a shape field in a fields collection returned from the required fields for a feature class. The editing of the GeometryDef object as well as the addition of one non-required field can be done before the field collection is used in the creation of a new feature class:
[Java]
static IFields createFieldsCollectionForFeatureClass(ISpatialReference
    spatialReference)throws Exception{
    //    Use the feature class description to return the required fields in a fields collection.
    //    The same process could and should be used to create an object class required fields.
    IFeatureClassDescription fcDesc = new FeatureClassDescription();
    IObjectClassDescription ocDesc = (IObjectClassDescription)fcDesc;

    //    Create the fields using the required fields method.
    IFields fields = ocDesc.getRequiredFields();

    //    Locate the shape field with the name from the feature class description.
    int shapeFieldIndex = fields.findField(fcDesc.getShapeFieldName());
    IField shapeField = fields.getField(shapeFieldIndex);

    //    Modify the GeometryDef object before using the fields collection to create a new feature class.
    IGeometryDef geometryDef = shapeField.getGeometryDef();
    IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
    //    Alter the feature class geometry type to lines (default is polygons).
    geometryDefEdit.setGeometryType(esriGeometryType.esriGeometryPolyline);
    //    The lines will have measures.
    geometryDefEdit.setHasM(true);
    geometryDefEdit.setGridCount(1);
    //    Set the first grid size to zero and allow ArcGIS to determine a valid grid size.
    geometryDefEdit.setGridSize(0, 0);

    //    Assign the spatial reference that was passed in, possibly from
    //    IGeodatabase::SpatialReference for the containing feature dataset.
    if (spatialReference != null){
        geometryDefEdit.setSpatialReferenceByRef(spatialReference);
    }

    //    Because the fields collection already exists, the AddField method on the IFieldsEdit interface
    //    will be used to add a field that is not required to the fields collection.
    IFieldsEdit fieldsEdit = (IFieldsEdit)fields;
    IField field = new Field();
    IFieldEdit fieldEdit = (IFieldEdit)field;

    //    Create a user-defined double field.
    //    Set the field properties.
    fieldEdit.setAliasName("average income for 1999-2000");
    fieldEdit.setEditable(true);
    fieldEdit.setIsNullable(false);
    fieldEdit.setName("average_income");
    fieldEdit.setPrecision(2);
    fieldEdit.setScale(5);
    fieldEdit.setType(esriFieldType.esriFieldTypeDouble);
    //    Add the field to the fields collection.
    fieldsEdit.addField(field);

    //    The returned fields collection can now be used in 
    //    IFeatureWorkspace::CreateFeatureClass or 
    //    IFeatureDataset::CreateFeatureClass as the fields argument.
    return fields;
}


See Also:

How to work with fields
How to create subtypes




Additional Requirements
  • If working in ArcSDE, an ArcEditor or greater license is required for ArcGIS Desktop, and the Geodatabase Update extension is required for ArcGIS Engine.

Development licensingDeployment licensing
ArcGIS for Desktop BasicArcGIS for Desktop Basic
ArcGIS for Desktop StandardArcGIS for Desktop Standard
ArcGIS for Desktop AdvancedArcGIS for Desktop Advanced
Engine Developer KitEngine: Geodatabase Update