This sample code demonstrates how to implement neighborhood-notation processing using PixelBlock. This sub creates an output equivalent to OutRas = InRas + (InRas(-1,-1) - InRas(1,1))
How to use
- Call this sub in VBA or VB.
- Make sure to add reference to ESRI DataSourceRaster Object Library.
Sub NeighborhoodNotation(sInPath As String, sInRasDSName As String, sOutPath As String, sOutRasDSName As String)
'sInPath: path of the input raster dataset
'sInRasDSName: name of the input raster dataset
'sOutPath: path of the output raster dataset
'sOutRasDSName: name of the output raster dataset'Open input raster dataset
Dim pRWS As IRasterWorkspace2
Dim pWSF As IWorkspaceFactory
Set pWSF = New RasterWorkspaceFactory
If Not pWSF.IsWorkspace(sInPath) Then
Exit Sub
End If
Set pRWS = pWSF.OpenFromFile(sInPath, 0)
Dim pInRasDS As IRasterDataset
Set pInRasDS = pRWS.OpenRasterDataset(sInRasDSName)
'Get the forst band from the input raster
Dim pInBand As IRasterBand
Dim pInputBandCol As IRasterBandCollection
Set pInputBandCol = pInRasDS
Set pInBand = pInputBandCol.Item(0)
'QI raster properties
Dim pInRasProps As IRasterProps
Set pInRasProps = pInBand
'Create a default raster from input raster dataset
Dim pInputRaster As IRaster
Set pInputRaster = pInRasDS.CreateDefaultRaster
'Create output raster dataset
Dim fsObj, fl
Set fsObj = CreateObject("Scripting.FileSystemObject")
If fsObj.FolderExists(sOutPath) Then
Set fl = fsObj.GetFolder(sOutPath)
If fl.Attributes And 1 Then Exit Sub
Else
Exit Sub
End If
Set pRWS = pWSF.OpenFromFile(sOutPath, 0)
Dim pOrigin As IPoint
Set pOrigin = New Point
pOrigin.X = pInRasProps.Extent.XMin
pOrigin.Y = pInRasProps.Extent.YMin
'Find out the pixel type of the input raster dataset
Dim outPixelType As rstPixelType
Select Case pInRasProps.PixelType
Case PT_CHAR
outPixelType = PT_LONG
Case PT_COMPLEX
MsgBox "Operation not supported on complex data", vbOKOnly, "Neighborhood Notation"
Exit Sub
Case PT_DCOMPLEX
MsgBox "Operation not supported on complex data", vbOKOnly, "Neighborhood Notation"
Exit Sub
Case PT_DOUBLE
outPixelType = PT_FLOAT
Case PT_FLOAT
outPixelType = PT_FLOAT
Case PT_LONG
outPixelType = PT_LONG
Case PT_SHORT
outPixelType = PT_LONG
Case PT_U1
outPixelType = PT_LONG
Case PT_U2
outPixelType = PT_LONG
Case PT_U4
outPixelType = PT_LONG
Case PT_UCHAR
outPixelType = PT_LONG
Case PT_ULONG
outPixelType = PT_LONG
Case PT_USHORT
outPixelType = PT_LONG
End Select
Dim pOutRasDS As IRasterDataset
Set pOutRasDS = pRWS.CreateRasterDataset(sOutRasDSName, "GRID", pOrigin, _
pInRasProps.Width, pInRasProps.Height, pInRasProps.MeanCellSize.X, _
pInRasProps.MeanCellSize.Y, 1, outPixelType, pInRasProps.SpatialReference, True)
'Create a default raster from the output raster dataset
Dim pOutRaster As IRaster
Set pOutRaster = pOutRasDS.CreateDefaultRaster
'Get the first band from the output raster
Dim pOutBand As IRasterBand
Dim pOutputBandCol As IRasterBandCollection
Set pOutputBandCol = pOutRasDS
Set pOutBand = pOutputBandCol.Item(0)
'QI IRawPixels interface for input
Dim pInRawPixels As IRawPixels
Set pInRawPixels = pInBand
'QI IRawPixels interface for output
Dim pOutRawPixel As IRawPixels
Set pOutRawPixel = pOutBand
'Create a DblPnt to hold the PixelBlock size
Dim pPnt As IPnt
Set pPnt = New DblPnt
pPnt.SetCoords pInRasProps.Width, pInRasProps.Height
'Creates PixelBlock from input
Dim pInPixelBlock As IPixelBlock3
Set pInPixelBlock = pInRawPixels.CreatePixelBlock(pPnt)
'Creates PixelBlock from output
Dim pOutPixelBlock As IPixelBlock3
Set pOutPixelBlock = pOutRawPixel.CreatePixelBlock(pPnt)
'Read input PixelBlock
pPnt.X = 0
pPnt.Y = 0
pInRawPixels.Read pPnt, pInPixelBlock
'Get the SafeArray associated with the first band of the output
Dim vSafeArray As Variant
vSafeArray = pOutPixelBlock.PixelDataByRef(0)
'QI RasterProps for output for NoData handling
Dim pOutRasProps As IRasterProps
Set pOutRasProps = pOutBand
'Loop through the SafeArray and calculate each pixel value according to the neighborhood-notation
Dim i, j As Long
For i = 0 To pInRasProps.Width - 1
For j = 0 To pInRasProps.Height - 1
If (i - 1) >= 0 And (i + 1) <= pInRasProps.Width - 1 And _
(j - 1) >= 0 And (j + 1) <= pInRasProps.Height - 1 Then
If (Not CDbl(pInPixelBlock.GetVal(0, i, j)) = CDbl(pInRasProps.NoDataValue)) And _
(Not CDbl(pInPixelBlock.GetVal(0, i - 1, j - 1)) = CDbl(pInRasProps.NoDataValue)) And _
(Not CDbl(pInPixelBlock.GetVal(0, i + 1, j + 1)) = CDbl(pInRasProps.NoDataValue)) Then
vSafeArray(i, j) = CDbl(pInPixelBlock.GetVal(0, i, j)) + _
(CDbl(pInPixelBlock.GetVal(0, i - 1, j - 1)) - CDbl(pInPixelBlock.GetVal(0, i + 1, j + 1)))
Else
vSafeArray(i, j) = CDbl(pOutRasProps.NoDataValue)
End If
Else
vSafeArray(i, i) = CDbl(pOutRasProps.NoDataValue)
End If
Next j
Next i
'Write out the result
pOutRawPixel.Write pPnt, pOutPixelBlock
End Sub