Implementing Neighborhood Notation

Created:5/23/2001
Last Modified:6/6/2001
Description:

This example reproduces the result you would get by running the following at the ArcGRID prompt: Grid: outgrid = ingrid + (ingrid(-1,-1) - ingrid(1,1)). It demonstrates how one would use the PixelBlock object to perform neighborhood notation.

How to use:
  1. Call this subroutine in VB or VBA.
Sub NeighborhoodNotation(sInputPath As String, sInputFileName As String, sOutputPath As String, sOutputFileName As String)
   ' sInputPath: path of the input raster dataset
  ' sInputFileName: name of input raster dataset
  ' sOutputPath: path of the output raster dataset
  ' sOutputFileName: 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(sInputPath) Then Exit Sub
  Set pRWS = pWSF.OpenFromFile(sInputPath, 0)
  Dim pInputRasterDS As IRasterDataset
  Set pInputRasterDS = pRWS.OpenRasterDataset(sInputFileName)

   ' Get RasterBand from the input raster and QI raster
  ' properties interface from input raster dataset
   Dim pInputBand As IRasterBand
  Dim pInputBandCol As IRasterBandCollection
  Set pInputBandCol = pInputRasterDS
  Set pInputBand = pInputBandCol.Item(0)
  Dim pInputRasProps As IRasterProps
  Set pInputRasProps = pInputBand

   ' Create a default raster from input raster dataset
   Dim pInputRaster As IRaster
  Set pInputRaster = pInputRasterDS.CreateDefaultRaster

   ' Create output raster dataset
   Dim fs, f
  Set fs = CreateObject("Scripting.FileSystemObject")
  If fs.FolderExists(sOutputPath) Then
    Set f = fs.GetFolder(sOutputPath)
    If f.Attributes And 1 Then Exit Sub
  Else
    Exit Sub
  End If
  Set pRWS = pWSF.OpenFromFile(sOutputPath, 0)
  Dim pOrigin As IPoint
  Set pOrigin = New Point
  pOrigin.X = pInputRasProps.Extent.XMin
  pOrigin.Y = pInputRasProps.Extent.YMin
  Dim pOutputRasterDS As IRasterDataset
  Dim outputPixelType As rstPixelType
  Select Case pInputRasProps.PixelType
    Case PT_CHAR
      outputPixelType = 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
      outputPixelType = PT_FLOAT
    Case PT_FLOAT
      outputPixelType = PT_FLOAT
    Case PT_LONG
      outputPixelType = PT_LONG
    Case PT_SHORT
      outputPixelType = PT_LONG
    Case PT_U1
      outputPixelType = PT_LONG
    Case PT_U2
      outputPixelType = PT_LONG
    Case PT_U4
      outputPixelType = PT_LONG
    Case PT_UCHAR
      outputPixelType = PT_LONG
    Case PT_ULONG
      outputPixelType = PT_LONG
    Case PT_USHORT
      outputPixelType = PT_LONG
  End Select
  Set pOutputRasterDS = pRWS.CreateRasterDataset(sOutputFileName, "GRID", pOrigin, _
                        pInputRasProps.Width, pInputRasProps.Height, pInputRasProps.MeanCellSize.X, _
                        pInputRasProps.MeanCellSize.Y, 1, outputPixelType, _
                        pInputRasProps.SpatialReference, True)    

   ' Create a default raster from output raster dataset
   Dim pOutputRaster As IRaster
  Set pOutputRaster = pOutputRasterDS.CreateDefaultRaster

   ' Get RasterBand from the output raster
   Dim pOutputBand As IRasterBand
  Dim pOutputBandCol As IRasterBandCollection
  Set pOutputBandCol = pOutputRasterDS
  Set pOutputBand = pOutputBandCol.Item(0)

   ' QI RawPixel interface for input
   Dim pInputRawPixel As IRawPixels
  Set pInputRawPixel = pInputBand

  ' QI RawPixel interface for output 
  Dim pOutputRawPixel As IRawPixels
  Set pOutputRawPixel = pOutputBand
    
  ' Create a DblPnt to hold the PixelBlock size 
  Dim pPnt As IPnt
  Set pPnt = New DblPnt
  pPnt.SetCoords pInputRasProps.Width, pInputRasProps.Height
    
  ' Creates PixelBlock of input with defined size 
  Dim pInputBlock As IPixelBlock
  Set pInputBlock = pInputRawPixel.CreatePixelBlock(pPnt)
    
    ' Creates PixelBlock of output with defined size 
  Dim pOutputBlock As IPixelBlock
  Set pOutputBlock = pOutputRawPixel.CreatePixelBlock(pPnt)
    
    ' Read input PixelBlock 
  pPnt.X = 0
  pPnt.Y = 0
  pInputRawPixel.Read pPnt, pInputBlock
   
  ' Get the SafeArray associated with the first band of output 
  Dim vSafeArray As Variant
  vSafeArray = pOutputBlock.SafeArray(0)
    
  ' QI RasterProps for output for NoData handling 
  Dim pOutputRasProps As IRasterProps
  Set pOutputRasProps = pOutputBand
  
  ' Loop through the SafeArray and calculate each pixel value using equation given above 
  Dim I, J As Long
  For I = 0 To pInputRasProps.Width - 1
    For J = 0 To pInputRasProps.Height - 1
      If I - 1 >= 0 And I + 1 <= pInputRasProps.Width - 1 And J - 1 >= 0 And J + 1 <= pInputRasProps.Height - 1 Then
        If Not CDbl(pInputBlock.GetVal(0, I, J)) = CDbl(pInputRasProps.NoDataValue) And Not CDbl(pInputBlock.GetVal(0, I - 1, J - 1)) = CDbl(pInputRasProps.NoDataValue) And Not CDbl(pInputBlock.GetVal(0, I + 1, J + 1)) = CDbl(pInputRasProps.NoDataValue) Then
          vSafeArray(I, J) = CDbl(pInputBlock.GetVal(0, I, J)) + (CDbl(pInputBlock.GetVal(0, I - 1, J - 1)) - CDbl(pInputBlock.GetVal(0, I + 1, J + 1)))
        Else
          vSafeArray(I, J) = CDbl(pOutputRasProps.NoDataValue)
        End If
      Else
        vSafeArray(I, J) = CDbl(pOutputRasProps.NoDataValue)
      End If
    Next J
  Next I
    
  ' Write out the result 
  pOutputRawPixel.Write pPnt, pOutputBlock
    
End Sub