I have a floating point raster and have applied a conditional to it in order to only extract the positive values, so there are 'no data' "holes" in the raster. I simply need to sum the values from this raster and output it as a number.
I came across this thread, which I'm sure some of you will recognize. Has anyone developed a working solution? I'm working in Arc10 and making use of ArcObjects if necessary.
EDIT: I've included a VB.NET version of @Kirk's C# code. It's provided as is, but it should be a good starting point if it doesn't already completely satisfy its purpose.
Public Shared Sub TestSumRaster()
Dim path As String = "D:\topo_modeling\topo_modeling\gis\usgs\ned_10m.img"
Dim rds = OpenRaster(path)
Dim sum As Double = SumRaster(rds)
Debug.Print("sum : {0}", sum)
End Sub
Public Shared Function SumRaster(rasDs As IRasterDataset) As Double
' sum up each band in a raster dataset
Dim rasBandCol As IRasterBandCollection = DirectCast(rasDs, IRasterBandCollection)
Dim sum As Double = 0.0
' Iterate through each band of the dataset.
For i As Integer = 0 To rasBandCol.Count - 1
sum += SumBand(rasBandCol.Item(i))
Next
Return sum
End Function
Private Shared Function SumBand(rBand As IRasterBand) As Double
' sum up each block in a band
Dim sum As Double = 0.0
' QI to IRawBlocks from IRasterBandCollection
Dim rawBlocks = DirectCast(rBand, IRawBlocks)
' Determine the tiling scheme for the raster dataset.
Dim tile = New Tile(rawBlocks.RasterInfo)
' NoData is array, but usually just has one value in it.
Debug.Print(rawBlocks.RasterInfo.NoData.[GetType]().ToString())
' Create the pixel block.
Dim pb = rawBlocks.CreatePixelBlock()
' Iterate through the pixel blocks.
For pbYcursor As Integer = tile.startY To tile.endY - 1
For pbXcursor As Integer = tile.startX To tile.endX - 1
' Get the pixel block.
rawBlocks.ReadBlock(pbXcursor, pbYcursor, 0, pb)
sum += SumBlock(pb, pbXcursor, pbYcursor, rawBlocks.RasterInfo.NoData)
Next
Next
Return sum
End Function
Private Shared Function SumBlock(pb As IPixelBlock, pbXcursor As Integer, pbYcursor As Integer, noDataValues As Object) As Double
' sum up each pixel in the pixelblock
Dim sum As Double = 0.0
' Put the pixel block into a SafeArray for manipulation.
Dim safeArray = TryCast(DirectCast(pb.get_SafeArray(0), System.Array), System.Array)
Dim noDataList = New List(Of [Single])(DirectCast(noDataValues, [Single]()))
' Iterate through the pixels in the pixel block.
For row As Integer = 0 To pb.Height - 1
For col As Integer = 0 To pb.Width - 1
Dim val As Object = safeArray.GetValue(row, col)
Dim singVal = DirectCast(val, [Single])
'Debug.Print(val.GetType().Name);
If Not noDataList.Contains(singVal) Then
sum += singVal
End If
Next
Next
Return sum
End Function