How to convert simple data to a geodatabase


Summary
The article shows how to use the IFeatureDataConverter interface to load simple feature data into a geodatabase. Examples of this include copying a shapefile into a file geodatabase, or a feature class from a file geodatabase into an ArcSDE geodatabase.
Code samples explaining how to use a spatial index grid size other than the default and how to modify the output spatial reference (project) are also included.

In this topic


Converting simple data to a geodatabase

This article shows how to create a new feature class in a geodatabase based on a simple data from another data source, such as another geodatabase or a folder of shapefiles.  The new feature class should not be created in the geodatabase beforehand; the following code will do that (and will fail if the feature class already exists).  The remainder of this article will assume that a shapefile is being converted to a file geodatabase, but the process is similar for converting a feature class between geodatabases.
The IFeatureDataConverter interface was designed to work with the ArcCatalog IGxDialog mini-browser. As this example does not use an ArcCatalog IGxDialog mini-browser, to convert a shapefile to a geodatabase feature class, the following objects must first be created:
 
Creating source and target names
Two name objects are required for the conversion: one for the source (the shapefile) and one for the target (the new File GDB feature class).  When creating a feature class name object, it's necessary to have a name object for the containing workspace, as well.  By connecting to the two workspaces - the shapefile folder and the File GDB - and casting to the IDataset interface, name objects can be retrieved.  For more information about connecting to workspaces, see How to connect to a geodatabase.
The following code example shows how to obtain these workspace names:
[Java]
// Open the source and target workspaces.
String sourceWorkspacePath = "C:/arcgis/ArcTutor/ArcReader and Publisher/Data";
String targetWorkspacePath = "C:/Temp/Maritimes.gdb";
IWorkspaceFactory sourceWorkspaceFactory = new ShapefileWorkspaceFactory();
IWorkspaceFactory targetWorkspaceFactory = new FileGDBWorkspaceFactory();
IWorkspace sourceWorkspace = sourceWorkspaceFactory.openFromFile(sourceWorkspacePath,
    0);
IWorkspace targetWorkspace = targetWorkspaceFactory.openFromFile(targetWorkspacePath,
    0);
// Cast the workspaces to the IDataset interface and get name objects.
IDataset sourceWorkspaceDataset = (IDataset)sourceWorkspace;
IDataset targetWorkspaceDataset = (IDataset)targetWorkspace;
IName sourceWorkspaceDatasetName = sourceWorkspaceDataset.getFullName();
IName targetWorkspaceDatasetName = targetWorkspaceDataset.getFullName();
IWorkspaceName sourceWorkspaceName = (IWorkspaceName)sourceWorkspaceDatasetName;
IWorkspaceName targetWorkspaceName = (IWorkspaceName)targetWorkspaceDatasetName;
To build feature class name objects, two things are required:  name objects for the containing workspaces (which were just created), and the names of the source and target feature classes.  The shapefile to be copied is named "Can_Mjr_Cities", but to abbreviate it in the target geodatabase, it will be renamed "Cities".  The following code example shows how to build these feature class name objects:
[Java]
// Create a name object for the shapefile and cast to the IDataset interface.
IFeatureClassName sourceFeatureClassName = new FeatureClassName();
IDatasetName sourceDatasetName = (IDatasetName)sourceFeatureClassName;
sourceDatasetName.setName("Can_Mjr_Cities");
sourceDatasetName.setWorkspaceNameByRef(sourceWorkspaceName);
// Create a name object for the FGDB feature class and cast to the IDataset interface.
IFeatureClassName targetFeatureClassName = new FeatureClassName();
IDatasetName targetDatasetName = (IDatasetName)targetFeatureClassName;
targetDatasetName.setName("Cities");
targetDatasetName.setWorkspaceNameByRef(targetWorkspaceName);
When setting the IDatasetName.Name property, ensure that the formatting is appropriate for the data source.  For example, ArcSDE feature classes may require qualification, and Coverages also use a format different from other data sources.
Creating output feature class fields and geometry
Dataset name objects (including feature class name objects) can be cast to the IName interface, from where the IName.Open method can be called to open the actual dataset.  The IFieldChecker interface should then be used to convert the source's fields collection to a new collection that's compatible with the target workspace, as different data sources have different restrictions on field properties, such as the maximum length of a field name.  If an error is found, an enumerator of field errors (accessed through the IEnumFieldError interface) can be traversed and an error returned. Refer to IFieldChecker.Validate and IFieldError for details. See the following code:
[Java]
// Open source feature class to get field definitions.
IName sourceName = (IName)sourceFeatureClassName;
IFeatureClass sourceFeatureClass = (IFeatureClass)sourceName.open();
// Create the objects and references necessary for field validation.
IFieldChecker fieldChecker = new FieldChecker();
IFields sourceFields = sourceFeatureClass.getFields();
IFields targetFields[] = new IFields[1];
IEnumFieldError[] enumFieldError = new IEnumFieldError[1];
// Set the required properties for the IFieldChecker interface.
fieldChecker.setInputWorkspace(sourceWorkspace);
fieldChecker.setValidateWorkspaceByRef(targetWorkspace);
// Validate the fields and check for errors.
fieldChecker.validate(sourceFields, enumFieldError, targetFields);
if (enumFieldError != null){
    // Handle the errors in a way appropriate to your application.
    System.out.println("Errors were encountered during field validation.");
}
Do not add or remove fields from the target fields collection, as doing so will cause the conversion to fail.  To restrict the fields created in the target feature class, see the section below regarding the use of a query filter.
The geometry definition for the target feature class should be obtained by cloning the geometry definition from the source feature class.  The following code example shows how to do this:
[Java]
// Find the shape field.
String shapeFieldName = sourceFeatureClass.getShapeFieldName();
int shapeFieldIndex = sourceFeatureClass.findField(shapeFieldName);
IField shapeField = sourceFields.getField(shapeFieldIndex);
// Get the geometry definition from the shape field and clone it.
IGeometryDef geometryDef = shapeField.getGeometryDef();
IClone geometryDefClone = (IClone)geometryDef;
IClone targetGeometryDefClone = geometryDefClone.esri_clone();
IGeometryDef targetGeometryDef = (IGeometryDef)targetGeometryDefClone;
Once a geometry definition exists for the target feature class, any necessary modifications to it can be made through the IGeometryDefEdit interface, such as changing the grid count, the grid size, or the spatial reference.  Note that doing this is not necessary; typically, the existing values are acceptable.  The following code example shows how to change the grid count and size of the target's geometry definition:
[Java]
// Cast the IGeometryDef to the IGeometryDefEdit interface.
IGeometryDefEdit targetGeometryDefEdit = (IGeometryDefEdit)targetGeometryDef;
// Set the IGeometryDefEdit properties.
targetGeometryDefEdit.setGridCount(1);
targetGeometryDefEdit.setGridSize(0, 0.75);
Executing the conversion
Two types of restrictions can be applied to the conversion: the number of features that accompany the conversion (through attribute constraints), and the number of fields that are created in the new feature class.  Both of these restrictions can be applied through using a query filter, specifically the IQueryFilter.WhereClause and IQueryFilter.SubFields properties.  If spatial constraints are also necessary, the ISpatialFilter interface can also be used.  Note that applying constraints is optional, and a null value can be passed to the conversion method in lieu of a query filter if they aren't applicable.
The following code example shows how to create a query filter resulting in the target feature class only containing cities from a single province and only four of the original fields:
[Java]
// Create a query filter to only select cities with a province (PROV) value of 'NS'.
IQueryFilter queryFilter = new QueryFilter();
queryFilter.setWhereClause("PROV = 'NS'");
queryFilter.setSubFields("Shape, NAME, TERM, Pop1996");
Convert the feature class by calling IFeatureDataConverter.ConvertFeatureClass. Though rarely needed, rejected features can be reported using the IEnumInvalidObject and IInvalidObjectInfo interfaces. See the following code:
[Java]
// Create the converter and run the conversion.
IFeatureDataConverter featureDataConverter = new FeatureDataConverter();
IEnumInvalidObject enumInvalidObject = featureDataConverter.convertFeatureClass
    (sourceFeatureClassName, queryFilter, null, targetFeatureClassName,
    targetGeometryDef, targetFields[0], "", 1000, 0);
// Check for errors.
IInvalidObjectInfo invalidObjectInfo = null;
enumInvalidObject.reset();
while ((invalidObjectInfo = enumInvalidObject.next()) != null){
    // Handle the errors in a way appropriate to the application.
    System.out.println("Errors occurred for the following feature: " +
        invalidObjectInfo.getInvalidObjectID());
}

Complete code example

The following code is the concatenation of the previous examples:
[Java]
static void convertShapefileToFeatureClass()throws Exception{

    // Open the source and target workspaces.
    String sourceWorkspacePath = "C:/arcgis/ArcTutor/ArcReader and Publisher/Data";
    String targetWorkspacePath = "C:/Temp/Maritimes.gdb";
    IWorkspaceFactory sourceWorkspaceFactory = new ShapefileWorkspaceFactory();
    IWorkspaceFactory targetWorkspaceFactory = new FileGDBWorkspaceFactory();
    IWorkspace sourceWorkspace = sourceWorkspaceFactory.openFromFile
        (sourceWorkspacePath, 0);
    IWorkspace targetWorkspace = targetWorkspaceFactory.openFromFile
        (targetWorkspacePath, 0);
    // Cast the workspaces to the IDataset interface and get name objects.
    IDataset sourceWorkspaceDataset = (IDataset)sourceWorkspace;
    IDataset targetWorkspaceDataset = (IDataset)targetWorkspace;
    IName sourceWorkspaceDatasetName = sourceWorkspaceDataset.getFullName();
    IName targetWorkspaceDatasetName = targetWorkspaceDataset.getFullName();
    IWorkspaceName sourceWorkspaceName = (IWorkspaceName)sourceWorkspaceDatasetName;
    IWorkspaceName targetWorkspaceName = (IWorkspaceName)targetWorkspaceDatasetName;
    // Create a name object for the shapefile and cast to the IDataset interface.
    IFeatureClassName sourceFeatureClassName = new FeatureClassName();
    IDatasetName sourceDatasetName = (IDatasetName)sourceFeatureClassName;
    sourceDatasetName.setName("Can_Mjr_Cities");
    sourceDatasetName.setWorkspaceNameByRef(sourceWorkspaceName);
    // Create a name object for the FGDB feature class and cast to the IDataset interface.
    IFeatureClassName targetFeatureClassName = new FeatureClassName();
    IDatasetName targetDatasetName = (IDatasetName)targetFeatureClassName;
    targetDatasetName.setName("Cities");
    targetDatasetName.setWorkspaceNameByRef(targetWorkspaceName);
    // Open source feature class to get field definitions.
    IName sourceName = (IName)sourceFeatureClassName;
    IFeatureClass sourceFeatureClass = (IFeatureClass)sourceName.open();
    // Create the objects and references necessary for field validation.
    IFieldChecker fieldChecker = new FieldChecker();
    IFields sourceFields = sourceFeatureClass.getFields();
    IFields targetFields[] = new IFields[1];
    IEnumFieldError[] enumFieldError = new IEnumFieldError[1];
    // Set the required properties for the IFieldChecker interface.
    fieldChecker.setInputWorkspace(sourceWorkspace);
    fieldChecker.setValidateWorkspaceByRef(targetWorkspace);
    // Validate the fields and check for errors.
    fieldChecker.validate(sourceFields, enumFieldError, targetFields);
    if (enumFieldError != null){
        // Handle the errors in a way appropriate to your application.
        System.out.println("Errors were encountered during field validation.");
    }
    // Find the shape field.
    String shapeFieldName = sourceFeatureClass.getShapeFieldName();
    int shapeFieldIndex = sourceFeatureClass.findField(shapeFieldName);
    IField shapeField = sourceFields.getField(shapeFieldIndex);
    // Get the geometry definition from the shape field and clone it.
    IGeometryDef geometryDef = shapeField.getGeometryDef();
    IClone geometryDefClone = (IClone)geometryDef;
    IClone targetGeometryDefClone = geometryDefClone.esri_clone();
    IGeometryDef targetGeometryDef = (IGeometryDef)targetGeometryDefClone;
    // Cast the IGeometryDef to the IGeometryDefEdit interface.
    IGeometryDefEdit targetGeometryDefEdit = (IGeometryDefEdit)targetGeometryDef;
    // Set the IGeometryDefEdit properties.
    targetGeometryDefEdit.setGridCount(1);
    targetGeometryDefEdit.setGridSize(0, 0.75);
    // Create a query filter to only select cities with a province (PROV) value of 'NS'.
    IQueryFilter queryFilter = new QueryFilter();
    queryFilter.setWhereClause("PROV = 'NS'");
    queryFilter.setSubFields("Shape, NAME, TERM, Pop1996");
    // Create the converter and run the conversion.
    IFeatureDataConverter featureDataConverter = new FeatureDataConverter();
    IEnumInvalidObject enumInvalidObject = featureDataConverter.convertFeatureClass
        (sourceFeatureClassName, queryFilter, null, targetFeatureClassName,
        targetGeometryDef, targetFields[0], "", 1000, 0);
    // Check for errors.
    IInvalidObjectInfo invalidObjectInfo = null;
    enumInvalidObject.reset();
    while ((invalidObjectInfo = enumInvalidObject.next()) != null){
        // Handle the errors in a way appropriate to the application.
        System.out.println("Errors occurred for the following feature: " +
            invalidObjectInfo.getInvalidObjectID());
    }
}


See Also:

How to convert to other formats (shapefiles)
How to use copy and paste to transfer data




Additional Requirements
  • The IFeatureDataConverter interface only loads simple feature data (points, lines, polygons).
  • If working in ArcSDE, an ArcEditor or greater license will be needed for ArcGIS Desktop and the Geodatabase Update extension will be 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