6

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.

whuber
70.4k17 gold badges189 silver badges285 bronze badges
asked Nov 20, 2011 at 15:06
2
  • 2
    Have you seen this post about adding raster field? gis.stackexchange.com/questions/14093/… Commented Nov 20, 2011 at 17:05
  • Yes, I have seen that post but it did not help me. Commented Nov 20, 2011 at 17:58

2 Answers 2

1

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
answered Nov 22, 2011 at 18:14
1
  • @ MapPlus: Although I did it with another way, many thanks for the answer. Commented Nov 23, 2011 at 13:48
1

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);
 }
}
answered Nov 20, 2011 at 18:46
3
  • 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. Commented Nov 20, 2011 at 20:11
  • 1
    I suppose that the above code is in Python. Do you have any code in VBA? Commented Nov 21, 2011 at 6:51
  • It isn't python, its C++ or java I am guessing? Commented Nov 24, 2011 at 9:32

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.