/// <summary> /// Constructing an ObjectGrid this way assumes the values are not in ram and will /// simply buffer 3 rows. /// </summary> /// <param name="sourceRaster"></param> public IntValueGrid(IntRaster sourceRaster) { _sourceRaster = sourceRaster; if (sourceRaster.IsInRam == true) { // we will just be forwarding requests to the data array } else { _rowBuffer = new int[3][]; _topRow = 0; for (int row = 0; row < 3; row++) { _rowBuffer[row] = _sourceRaster.ReadRow(row); } } }
// ----------------------------------- FROM AND TO IN RAM ONLY --------------------------------- /// <summary> /// This creates an IN MEMORY ONLY window from the in-memory window of this raster. If, however, the requested range /// is outside of what is contained in the in-memory portions of this raster, an appropriate cast /// is required to ensure that you have the correct File handling, like a BinaryRaster etc. /// </summary> /// <param name="startRow">The 0 based integer index of the top row to get from this raster. If this raster is itself a window, 0 represents the startRow from the file.</param> /// <param name="endRow">The integer index of the bottom row to get from this raster. The largest allowed value is NumRows - 1.</param> /// <param name="startColumn">The 0 based integer index of the leftmost column to get from this raster. If this raster is a window, 0 represents the startColumn from the file.</param> /// <param name="endColumn">The 0 based integer index of the rightmost column to get from this raster. The largest allowed value is NumColumns - 1</param> /// <param name="inRam">Boolean. If this is true and the window is small enough, a copy of the values will be loaded into memory.</param> /// <returns>An implementation of IRaster</returns> public IRaster GetWindow(int startRow, int endRow, int startColumn, int endColumn, bool inRam) { if (IsInRam == false) throw new ArgumentException(MessageStrings.RasterRequiresCast); if (startRow < StartRow || endRow > EndRow || StartColumn < startColumn || EndColumn > endColumn) { // the requested extents are outside of the extents that have been windowed into ram. File Handling is required. throw new ArgumentException(MessageStrings.RasterRequiresCast); } int numCols = endColumn - startColumn + 1; int numRows = endRow - startRow + 1; IntRaster result = new IntRaster(numRows, numCols); result.Filename = Filename; result.Projection = Projection; result.DataType = typeof(int); result.NumRows = numRows; result.NumColumns = numCols; result.NumRowsInFile = NumRowsInFile; result.NumColumnsInFile = NumColumnsInFile; result.NoDataValue = NoDataValue; result.StartColumn = startColumn; result.StartRow = startRow; result.EndColumn = endColumn; result.EndRow = EndRow; result.FileType = FileType; // Reposition the new "raster" so that it matches the specified window, not the whole raster // X = [0] + [1] * column + [2] * row; // Y = [3] + [4] * column + [5] * row; result.Bounds.AffineCoefficients = new double[6]; result.Bounds.AffineCoefficients[0] = Bounds.AffineCoefficients[0] + Bounds.AffineCoefficients[1]*startColumn + Bounds.AffineCoefficients[2]*startRow; result.Bounds.AffineCoefficients[1] = Bounds.AffineCoefficients[1]; result.Bounds.AffineCoefficients[2] = Bounds.AffineCoefficients[2]; result.Bounds.AffineCoefficients[3] = Bounds.AffineCoefficients[3] + Bounds.AffineCoefficients[4]*startColumn + Bounds.AffineCoefficients[5]*startRow; result.Bounds.AffineCoefficients[4] = Bounds.AffineCoefficients[4]; result.Bounds.AffineCoefficients[5] = Bounds.AffineCoefficients[5]; // Now we can copy any values currently in memory. ProgressMeter pm = new ProgressMeter(ProgressHandler, MessageStrings.CopyingValues, endRow); pm.StartValue = startRow; // copy values directly using both data structures for (int row = 0; row < numRows; row++) { for (int col = 0; col < numCols; col++) { result.Data[row][col] = Data[startRow + row][startColumn + col]; } pm.CurrentValue = row; } pm.Reset(); result.Value = new IntValueGrid(result); return result; }
/// <summary> /// Writes the integer row array to the output raster. The square distance is /// converted to a normal distance. Unknown distance is converted to 'no data' value /// </summary> /// <param name="output"></param> /// <param name="rowNumber"></param> /// <param name="rowArray"></param> private static void writeOutputRow(IntRaster output, int rowNumber, int[] rowArray) { int noDataVal = (int)output.NoDataValue; for (int col=0; col < rowArray.Length; col++) { int val = rowArray[col]; if (val == int.MaxValue) { output.Data[rowNumber][col] = noDataVal; } else { output.Data[rowNumber][col] = (int)(Math.Sqrt(val)); } } }
// ------------------------------------------FROM AND TO IN RAM ONLY ----------------- /// <summary> /// This creates a completely new raster from the windowed domain on the original raster. This new raster /// will not have a source file, and values like NumRowsInFile will correspond to the in memory version. /// All the values will be copied to the new source file. InRam must be true at this level. /// </summary> /// <param name="filename"></param> /// <param name="startRow">The 0 based integer index of the top row to copy from this raster. If this raster is itself a window, 0 represents the startRow from the file.</param> /// <param name="endRow">The integer index of the bottom row to copy from this raster. The largest allowed value is NumRows - 1.</param> /// <param name="startColumn">The 0 based integer index of the leftmost column to copy from this raster. If this raster is a window, 0 represents the startColumn from the file.</param> /// <param name="endColumn">The 0 based integer index of the rightmost column to copy from this raster. The largest allowed value is NumColumns - 1</param> /// <param name="copyValues">If this is true, the valeus are saved to the file. If this is false and the data can be loaded into Ram, no file handling is done. Otherwise, a file of NoData values is created.</param> /// <param name="inRam">Boolean. If this is true and the window is small enough, a copy of the values will be loaded into memory.</param> /// <returns>An implementation of IRaster</returns> public IRaster CopyWindow(string filename, int startRow, int endRow, int startColumn, int endColumn, bool copyValues, bool inRam) { if (inRam == false || (endColumn - startColumn + 1)*(endRow - startRow + 1) > 64000000) throw new ArgumentException(MessageStrings.RasterRequiresCast); if (IsInRam == false) throw new ArgumentException(MessageStrings.RasterRequiresCast); int numCols = endColumn - startColumn + 1; int numRows = endRow - startRow + 1; IntRaster result = new IntRaster(numRows, numCols); result.Projection = Projection; // The affine coefficients defining the world file are the same except that they are translated over. Only the position of the // upper left corner changes. Everything else is the same as the previous raster. // X = [0] + [1] * column + [2] * row; // Y = [3] + [4] * column + [5] * row; result.Bounds.AffineCoefficients = new double[6]; result.Bounds.AffineCoefficients[0] = Bounds.AffineCoefficients[0] + Bounds.AffineCoefficients[1]*startColumn + Bounds.AffineCoefficients[2]*startRow; result.Bounds.AffineCoefficients[1] = Bounds.AffineCoefficients[1]; result.Bounds.AffineCoefficients[2] = Bounds.AffineCoefficients[2]; result.Bounds.AffineCoefficients[3] = Bounds.AffineCoefficients[3] + Bounds.AffineCoefficients[4]*startColumn + Bounds.AffineCoefficients[5]*startRow; result.Bounds.AffineCoefficients[4] = Bounds.AffineCoefficients[4]; result.Bounds.AffineCoefficients[5] = Bounds.AffineCoefficients[5]; ProgressMeter pm = new ProgressMeter(ProgressHandler, MessageStrings.CopyingValues, numRows); // copy values directly using both data structures for (int row = 0; row < numRows; row++) { for (int col = 0; col < numCols; col++) { result.Data[row][col] = Data[startRow + row][startColumn + col]; } pm.CurrentValue = row; } pm.Reset(); result.Value = new IntValueGrid(result); return result; }