Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm creating a new feature class with the attribute table schema (field names, types etc.) copied from another feature class. Then, I'd like to modify this schema slightly (e.g. add an additional field).

What is the best way to achieve this? Should I loop through all input fields and create respective output fields?

Thanks in advance, Jan

share|improve this question

3 Answers 3

up vote 5 down vote accepted

I'd consider leveraging IFieldChecker. There's some sample code under the Creating output feature class fields and geometry section on this page.

Also, if you need to keep track of which destination fields were derived from which origin fields, you might consider using IModelInfo:

... the model name which is a tool for developers of custom objects to use to guarantee the names of objects independent of the true name or alias name.

If you just need to add a field, the simplest is probably calling IClone.Clone() on the origin featureclass's IFeatureClass.Fields member, then using IFieldsEdit.AddField on the resulting clone to add the single field, then using that to create the new featureclass.

share|improve this answer
    
IClone.Clone() worked perfectly and should be sufficient for my purpose. It clones all field's parameters, including Spatial Reference for geometry. Thanks! –  jan_b Nov 17 '11 at 7:40

Here's a few subroutines I use in creating new feature classes with an existing template and adding fields.

A few notes about the code. I have created a global variable for the geoprocessor (Globals.GP) and initiated that elsewhere. Also you should be able to use an IFeatureClass as the input for the template property of the CreateFeatureclass tool, but the bug NIM068724 (which may be fixed in 10.1) currently prevents this and you have to use the path name for the feature class.

    Public Sub AddField(ByVal Input As Object, ByVal FieldName As String, ByVal FieldType As String, Optional ByVal Precision As Long = 0,
                    Optional ByVal Scale As Long = 0, Optional ByVal Length As Long = 0, Optional ByVal FieldAlias As String = Nothing,
                    Optional ByVal Nullable As String = "NULLABLE", Optional ByVal Required As String = "NON_REQUIRED", Optional ByVal Domain As String = Nothing)

    Dim AddField As New ESRI.ArcGIS.DataManagementTools.AddField
    Dim Result As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2

    Try
        Using releaser As New ESRI.ArcGIS.ADF.ComReleaser
            releaser.ManageLifetime(AddField)

            AddField.in_table = Input
            AddField.field_name = FieldName
            AddField.field_type = FieldType
            AddField.field_precision = Precision
            AddField.field_scale = Scale
            AddField.field_length = Length
            AddField.field_alias = FieldAlias
            AddField.field_is_nullable = Nullable
            AddField.field_is_required = Required
            AddField.field_domain = Domain

            Result = RunTool(AddField, Nothing)
            If Result Is Nothing Then
                System.Windows.Forms.MessageBox.Show("Could not add field")
            End If
        End Using
    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.ToString, "Add Field error")
    End Try

End Sub

Private Function CreateFeatureClass(ByVal PathString As String, ByVal Name As String, ByVal pTemplateFClass As ESRI.ArcGIS.Geodatabase.IFeatureClass) As ESRI.ArcGIS.Geodatabase.IFeatureClass

    Dim CreateFC As New ESRI.ArcGIS.DataManagementTools.CreateFeatureclass
    Dim ShapeType As String
    Dim dataset As ESRI.ArcGIS.Geodatabase.IDataset
    Dim Result As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2
    Dim Path As String

    Try
        Using releaser As New ESRI.ArcGIS.ADF.ComReleaser
            releaser.ManageLifetime(CreateFC)

            Select Case pTemplateFClass.ShapeType
                Case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint
                    ShapeType = "Point"
                Case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline
                    ShapeType = "Line"
                Case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon
                    ShapeType = "Polygon"
                Case Else
                    Return Nothing
            End Select

            dataset = pTemplateFClass
            Path = dataset.Workspace.PathName & "\" & dataset.Name
            If dataset.Workspace.WorkspaceFactory.WorkspaceType = ESRI.ArcGIS.Geodatabase.esriWorkspaceType.esriFileSystemWorkspace Then
                If TypeOf dataset.Workspace.WorkspaceFactory Is ESRI.ArcGIS.DataSourcesFile.ShapefileWorkspaceFactory Then
                    Path = Path & ".shp"
                End If
            End If

            Dim pSR As ESRI.ArcGIS.Geometry.ISpatialReference3 = GetSpatialReferenceFromDataset(pTemplateFClass)

            CreateFC.out_path = PathString 
            CreateFC.out_name = Name
            CreateFC.geometry_type = ShapeType
            CreateFC.template = Path
            CreateFC.spatial_reference = GetSpatialReferenceFromDataset(pTemplateFClass)

            Result = RunTool(CreateFC, Nothing)
            If Result Is Nothing Then
                System.Windows.Forms.MessageBox.Show("Could not create dataset")
                Return Nothing
            End If

            Return ReturnObjectfromResult(Result, "Feature Class")
        End Using

    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.ToString, "Create InMemory Featureclass error")
        Return Nothing
    End Try

End Function

Public Function GetSpatialReferenceFromDataset(ByVal dataset As ESRI.ArcGIS.Geodatabase.IDataset) As ESRI.ArcGIS.Geometry.ISpatialReference3

    'If the dataset supports IGeoDataset
    If TypeOf dataset Is ESRI.ArcGIS.Geodatabase.IGeoDataset Then
        'then grab the spatial reference information and return it.
        Dim geoDataset As ESRI.ArcGIS.Geodatabase.IGeoDataset = CType(dataset, ESRI.ArcGIS.Geodatabase.IGeoDataset)

        Return geoDataset.SpatialReference

    Else

        Return Nothing 'otherwise return nothing

    End If

End Function

Friend Function ReturnObjectfromResult(ByVal result As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2, ByVal Type As String) As Object

    Dim GPVal As ESRI.ArcGIS.Geodatabase.IGPValue
    Dim InMemFC As String
    Dim GPUtil As ESRI.ArcGIS.Geoprocessing.IGPUtilities3 = New ESRI.ArcGIS.Geoprocessing.GPUtilities

    Try
        GPVal = result.GetOutput(0)
        InMemFC = GPVal.GetAsText()

        Select Case Type
            Case "Feature Class"
                Return GPUtil.OpenFeatureClassFromString(InMemFC)
            Case "Table"
                Return GPUtil.OpenTableFromString(InMemFC)
        End Select

    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.ToString, "Return FeatureClass error")
        Return Nothing
    End Try

End Function

Friend Function RunTool(ByVal Process As ESRI.ArcGIS.Geoprocessor.IGPProcess, ByVal TC As ESRI.ArcGIS.esriSystem.ITrackCancel2) As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2

    Dim Result As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2

    Try
        Result = CType(Globals.GP.Execute(Process, Nothing), ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2)
        If Result.Status <> ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded Then ReturnMessages(Result, "Geoprocessing Error")
        Globals.GP.ClearMessages()
    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.ToString, "Run Geoprocessor")
    End Try

    Return Result

End Function
share|improve this answer
    
Thanks Ken for the code. I'll give it a try as well. –  jan_b Nov 17 '11 at 7:43

In general you can use the following ArcToolbox tool:

Data Management -> Feature Class -> Create Feature Class

in the "Template Feature Class" optional field you have to choose the original feature class, this is the field schema source

The new empty feature class will have the same source field schema and then you can add the new fields

Hope this helps

share|improve this answer
1  
It appears that jan_b is interested in an ArcObjects solution. –  artwork21 Nov 16 '11 at 21:11
    
yes, it's true: usually I tend to use in arcobjects the Geoprocessing object to take advantage from ArcToolbox Tools, so I can shorten code. but I forgot to point this. –  robymes Nov 17 '11 at 9:08

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.