Skip to main content
added 171 characters in body
Source Link
Conor
  • 3k
  • 2
  • 17
  • 44

I solved this earlier today. The code is an adaptation of this method. The concept behind this isn'twasn't terribly difficult once you figureI figured out what the objects with which you are workingused to interface with the raster actually do. The below method takes two input datasets (inRasterDS and outRasterDS). They are both the same dataset, I just made a copy of inRasterDS and passed it into the method as outRasterDS. This way they both have the same extent, spatial reference, etc. The method reads the values from inRasterDS, cell by cell, and does nearest neighbor comparisons on them. It uses the results of those comparisons as stored values in outRasterDS.

I solved this earlier today. The code is an adaptation of this method. The concept behind this isn't terribly difficult once you figure out what the objects with which you are working with actually do. The below method takes two input datasets (inRasterDS and outRasterDS). They are both the same dataset, I just made a copy of inRasterDS and passed it into the method as outRasterDS. This way they both have the same extent, spatial reference, etc. The method reads the values from inRasterDS, cell by cell, and does nearest neighbor comparisons on them. It uses the results of those comparisons as stored values in outRasterDS.

I solved this earlier today. The code is an adaptation of this method. The concept behind this wasn't terribly difficult once I figured out what the objects used to interface with the raster actually do. The below method takes two input datasets (inRasterDS and outRasterDS). They are both the same dataset, I just made a copy of inRasterDS and passed it into the method as outRasterDS. This way they both have the same extent, spatial reference, etc. The method reads the values from inRasterDS, cell by cell, and does nearest neighbor comparisons on them. It uses the results of those comparisons as stored values in outRasterDS.

added 171 characters in body
Source Link
Conor
  • 3k
  • 2
  • 17
  • 44

A solution:

The Process:

I used IRasterCursor -> IPixelBlock -> SafeArray to get at the pixel values and IRasterEdit to write new ones to the raster. When you create IPixelBlock, you are telling the machine the size and location of the area that you want to read/write to. If you only want to edit the bottom half of a raster, you set that as your IPixelBlock parameters. If you want to loop over the entire raster, you have to set IPixelBlock equal to the size of the entire raster. I do this in the method below by passing the size to IRasterCursor (pSize) then getting the PixelBlock from the raster cursor.

I used IRasterCursor -> IPixelBlock -> SafeArray to get at the pixel values and IRasterEdit to write new ones to the raster. When you create IPixelBlock, you are telling the machine the size and location of the area that you want to read/write to. If you want to loop over the entire raster, you have to set IPixelBlock equal to the size of the entire raster. I do this in the method below by passing the size to IRasterCursor (pSize) then getting the PixelBlock from the raster cursor.

A solution:

The Process:

I used IRasterCursor -> IPixelBlock -> SafeArray to get at the pixel values and IRasterEdit to write new ones to the raster. When you create IPixelBlock, you are telling the machine the size and location of the area that you want to read/write to. If you only want to edit the bottom half of a raster, you set that as your IPixelBlock parameters. If you want to loop over the entire raster, you have to set IPixelBlock equal to the size of the entire raster. I do this in the method below by passing the size to IRasterCursor (pSize) then getting the PixelBlock from the raster cursor.

Source Link
Conor
  • 3k
  • 2
  • 17
  • 44

I solved this earlier today. The code is an adaptation of this method. The concept behind this isn't terribly difficult once you figure out what the objects with which you are working with actually do. The below method takes two input datasets (inRasterDS and outRasterDS). They are both the same dataset, I just made a copy of inRasterDS and passed it into the method as outRasterDS. This way they both have the same extent, spatial reference, etc. The method reads the values from inRasterDS, cell by cell, and does nearest neighbor comparisons on them. It uses the results of those comparisons as stored values in outRasterDS.

I used IRasterCursor -> IPixelBlock -> SafeArray to get at the pixel values and IRasterEdit to write new ones to the raster. When you create IPixelBlock, you are telling the machine the size and location of the area that you want to read/write to. If you want to loop over the entire raster, you have to set IPixelBlock equal to the size of the entire raster. I do this in the method below by passing the size to IRasterCursor (pSize) then getting the PixelBlock from the raster cursor.

The other key is that you have to use SafeArray to interface with the values in this method. You get IPixelBlock from IRasterCursor, then SafeArray from IPixelBlock. Then you read and write to SafeArray. When you finish read/write to SafeArray, write your entire SafeArray back to IPixelBlock, then write your IPixelBlock to IRasterCursor, then finally use IRasterCursor to set the location to start write and IRasterEdit to do the write itself. This final step is where you actually edit the values of the dataset.

    public static void CreateBoundaryRaster(IRasterDataset2 inRasterDS, IRasterDataset2 outRasterDS)
    {
        try
        {
            //Create a raster. 
            IRaster2 inRaster = inRasterDS.CreateFullRaster() as IRaster2; //Create dataset from input raster
            IRaster2 outRaster = outRasterDS.CreateFullRaster() as IRaster2; //Create dataset from output raster
            IRasterProps pInRasterProps = (IRasterProps)inRaster;
            //Create a raster cursor with a pixel block size matching the extent of the input raster
            IPnt pSize = new DblPnt();
            pSize.SetCoords(pInRasterProps.Width, pInRasterProps.Height); //Give the size of the raster as a IPnt to pass to IRasterCursor
            IRasterCursor inrasterCursor = inRaster.CreateCursorEx(pSize); //Create IRasterCursor to parse input raster 
            IRasterCursor outRasterCursor = outRaster.CreateCursorEx(pSize); //Create IRasterCursor to parse output raster
            //Declare IRasterEdit, used to write the new values to raster
            IRasterEdit rasterEdit = outRaster as IRasterEdit;
            IRasterBandCollection inbands = inRasterDS as IRasterBandCollection;//set input raster as IRasterBandCollection
            IRasterBandCollection outbands = outRasterDS as IRasterBandCollection;//set output raster as IRasterBandCollection
            IPixelBlock3 inpixelblock3 = null; //declare input raster IPixelBlock
            IPixelBlock3 outpixelblock3 = null; //declare output raster IPixelBlock
            long blockwidth = 0; //store # of columns of raster
            long blockheight = 0; //store # of rows of raster

            //create system array for input/output raster. System array is used to interface with values directly. It is a grid that overlays your IPixelBlock which in turn overlays your raster.
            System.Array inpixels; 
            System.Array outpixels; 
            IPnt tlc = null; //set the top left corner

            // define the 3x3 neighborhood objects
            object center;
            object topleft;
            object topmiddle;
            object topright;
            object middleleft;
            object middleright;
            object bottomleft;
            object bottommiddle;
            object bottomright;

            long bandCount = outbands.Count; //use for multiple bands (only one in this case)
            
            do
            {
                
                inpixelblock3 = inrasterCursor.PixelBlock as IPixelBlock3; //get the pixel block from raster cursor
                outpixelblock3 = outRasterCursor.PixelBlock as IPixelBlock3;
                blockwidth = inpixelblock3.Width; //set the # of columns in raster
                blockheight = inpixelblock3.Height; //set the # of rows in raster
                outpixelblock3.Mask(255); //set any NoData values
                
                for (int k = 0; k < bandCount; k++) //for every band in raster (will always be 1 in this case)
                {
                    //Get the pixel array.
                    inpixels = (System.Array)inpixelblock3.get_PixelData(k); //store the raster values in a System Array to read
                    outpixels = (System.Array)outpixelblock3.get_PixelData(k); //store the raster values in a System Array to write
                    for (long i = 1; i < blockwidth - 1; i++) //for every column (except outside columns)
                    {
                        for (long j = 1; j < blockheight - 1; j++) //for every row (except outside rows)
                        {
                            //Get the pixel values of center cell and  neighboring cells

                            center = inpixels.GetValue(i, j);

                            topleft = inpixels.GetValue(i - 1, j + 1);
                            topmiddle = inpixels.GetValue(i, j + 1);
                            topright = inpixels.GetValue(i + 1, j + 1);
                            middleleft = inpixels.GetValue(i - 1, j);
                            middleright = inpixels.GetValue(i + 1, j);
                            bottomleft = inpixels.GetValue(i - 1, j - 1);
                            bottommiddle = inpixels.GetValue(i, j - 1);
                            bottomright = inpixels.GetValue(i - 1, j - 1);

                            
                            //compare center cell value with middle left cell and middle right cell in a 3x3 grid. If true, give output raster value of 1
                            if ((Convert.ToDouble(center) >= Convert.ToDouble(middleleft)) && (Convert.ToDouble(center) >= Convert.ToDouble(middleright)))
                            {
                                outpixels.SetValue(1, i, j);
                            }
                            
                            
                            //compare center cell value with top middle and bottom middle cell in a 3x3 grid. If true, give output raster value of 1
                            else if ((Convert.ToDouble(center) >= Convert.ToDouble(topmiddle)) && (Convert.ToDouble(center) >= Convert.ToDouble(bottommiddle)))
                            {
                                outpixels.SetValue(1, i, j);
                            }

                            //if neither conditions are true, give raster value of 0
                            else
                            {

                                outpixels.SetValue(0, i, j);
                            }
                        }
                    }
                    //Write the pixel array to the pixel block.
                    outpixelblock3.set_PixelData(k, outpixels);
                }
                //Finally, write the pixel block back to the raster.
                tlc = outRasterCursor.TopLeft;
                rasterEdit.Write(tlc, (IPixelBlock)outpixelblock3);
            }
            while (inrasterCursor.Next() == true && outRasterCursor.Next() == true);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(rasterEdit);
            

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        
    }
Post Made Community Wiki by Conor