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 am working with an existing raster attribute table. I wonder how can I add a new field to it and then loop through the existing records to populate this new field? Of course I have done this many times for a feature class and a database table but I do not know how to do it with a raster table. I work with VBA. Any code please? Thanks.

share|improve this question
2  
Have you seen this post about adding raster field? gis.stackexchange.com/questions/14093/… –  artwork21 Nov 20 '11 at 17:05
    
Yes, I have seen that post but it did not help me. –  Demetris Nov 20 '11 at 17:58
add comment

2 Answers 2

up vote 1 down vote accepted

VBA sample code is here:

Public Sub CalculateArea(raster As IRaster, areaField As String)
    Dim bandCol As IRasterBandCollection
    Dim band As IRasterBand

    Set bandCol = raster
    Set band = bandCol.Item(0)

    Dim hasTable As Boolean
    band.hasTable hasTable
    If (hasTable = False) Then
        Exit Sub
    End If    

    If (AddVatField(raster, areaField, esriFieldTypeDouble, 38) = True) Then
        ' calculate cell size
        Dim rstProps As IRasterProps
        Set rstProps = raster

        Dim pnt As IPnt
        Set pnt = rstProps.MeanCellSize

        Dim cellSize As Double
        cellSize = (pnt.X + pnt.Y) / 2#

        ' get fields index
        Dim attTable As ITable
        Set attTable = band.AttributeTable

        Dim idxArea As Long, idxCount As Long
        idxArea = attTable.FindField(areaField)
        idxCount = attTable.FindField("COUNT")

        ' using update cursor
        Dim gridTableOp As IGridTableOp
        Set gridTableOp = New gridTableOp

        Dim cellCount As Long, cellArea As Double

        Dim updateCursor As ICursor, updateRow As IRow
        Set updateCursor = gridTableOp.Update(band.RasterDataset, Nothing, False)
        Set updateRow = updateCursor.NextRow()
        Do Until updateRow Is Nothing
            cellCount = CLng(updateRow.Value(idxCount))
            cellArea = cellCount * (cellSize * cellSize)

            updateRow.Value(idxArea) = cellArea
            updateCursor.updateRow updateRow

            Set updateRow = updateCursor.NextRow()
        Loop

    End If
End Sub
Private Function AddVatField(raster As IRaster, fieldName As String, fieldType As esriFieldType, fieldLength As Long) As Boolean
    Dim bandCol As IRasterBandCollection
    Dim band As IRasterBand

    Set bandCol = raster
    Set band = bandCol.Item(0)

    Dim hasTable As Boolean
    band.hasTable hasTable

    If (hasTable = True) Then
        Dim attTable As ITable
        Set attTable = band.AttributeTable

        If (attTable.FindField(fieldName)  -1) Then
            AddVatField = True
            Exit Function
        End If

        Dim newField As IField
        Dim fieldEdit As IFieldEdit

        Set newField = New Field
        Set fieldEdit = newField

        With fieldEdit
            .Name = fieldName
            .Type = fieldType
            .Editable = True
            .IsNullable = True
            .Length = fieldLength
        End With

        Dim gridTableOp As IGridTableOp
        Set gridTableOp = New gridTableOp
        gridTableOp.AddField band.RasterDataset, newField

        AddVatField = True
        Exit Function
    End If

    AddVatField = False
End Function
share|improve this answer
    
@ MapPlus: Although I did it with another way, many thanks for the answer. –  Demetris Nov 23 '11 at 13:48
add comment

you could use IGridTableOp interface. reference: http://www.onspatial.com/2011/11/arcobjectsgrid-vatvalue-attribute-table.html

bool AddVatField(IRaster raster, string fieldName, esriFieldType fieldType, int fieldLength) {
    IRasterBandCollection bandCol = (IRasterBandCollection)raster;
    IRasterBand band = bandCol.Item(0);

    bool hasTable = false;
    band.HasTable(out hasTable);

    if (hasTable) {
        ITable attTable = band.AttributeTable;
        if (attTable.FindField(fieldName) != -1) {
            return true;
        }

        IField newField = new FieldClass();
        IFieldEdit fieldEdit = (IFieldEdit)newField;

        fieldEdit.Name_2 = fieldName;
        fieldEdit.Type_2 = fieldType;
        fieldEdit.Editable_2 = true;
        fieldEdit.IsNullable_2 = true;
        fieldEdit.Length_2 = fieldLength;

        IGridTableOp gridTableOp = new GridTableOpClass();
        gridTableOp.AddField(band.RasterDataset, newField);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(gridTableOp);

        return true;
    }

    return false;
}
void CalculateArea(IRaster raster, string areaField) {
    IRasterBandCollection bandCol = (IRasterBandCollection)raster;
    IRasterBand band = bandCol.Item(0);

    bool hasTable = false;
    band.HasTable(out hasTable);
    if (!hasTable) return;

    // Add Field
    if (AddVatField(raster, areaField, esriFieldType.esriFieldTypeDouble, 38)) {
        // calculate cell size
        IRasterProps rstProps = (IRasterProps)raster;
        IPnt pnt = rstProps.MeanCellSize();
        double cellSize = (pnt.X + pnt.Y) / 2.0;

        // get fields index
        ITable attTable = band.AttributeTable;
        int idxArea = attTable.FindField(areaField);
        int idxCount = attTable.FindField("COUNT");

        // using update cursor
        IGridTableOp gridTableOp = new GridTableOpClass();
        ICursor updateCursor = gridTableOp.Update(band.RasterDataset, null, false);
        IRow updateRow = updateCursor.NextRow();
        while (updateRow != null) {
            int cellCount = Convert.ToInt32(updateRow.get_Value(idxCount));
            double cellArea = cellCount * (cellSize * cellSize);

            updateRow.set_Value(idxArea, cellArea);
            updateCursor.UpdateRow(updateRow);

            updateRow = updateCursor.NextRow();
        }
        System.Runtime.InteropServices.Marshal.ReleaseComObject(gridTableOp);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(updateCursor);
    }
}
share|improve this answer
1  
Welcome to gis.stackexchange @MapPlus. We are trying to collect the best answers and save them for future users. When posting an answer, please include all necessary details in the answer text instead of just linking them. Links can break easily and then the answer would be worthless. –  underdark Nov 20 '11 at 20:11
1  
I suppose that the above code is in Python. Do you have any code in VBA? –  Demetris Nov 21 '11 at 6:51
    
It isn't python, its C++ or java I am guessing? –  Hairy Nov 24 '11 at 9:32
add comment

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.