/// <summary> /// This Method should be overrridden by classes, and provides the primary ability. /// </summary> /// <param name="xOff">The horizontal offset of the area to read values from.</param> /// <param name="yOff">The vertical offset of the window to read values from.</param> /// <param name="sizeX">The number of values to read into the buffer.</param> /// <param name="sizeY">The vertical size of the window to read into the buffer.</param> /// <returns>A jagged array of type T.</returns> public override T[][] ReadRaster(int xOff, int yOff, int sizeX, int sizeY) { FileStream fs = new(Filename, FileMode.Open, FileAccess.Read, FileShare.Read, NumColumns *ByteSize); ProgressMeter pm = new(ProgressHandler, DataStrings.ReadingValuesFrom_S.Replace("%S", Filename), NumRows); fs.Seek(HeaderSize, SeekOrigin.Begin); // Position the binary reader at the top of the "window" fs.Seek(yOff * NumColumnsInFile * ByteSize, SeekOrigin.Current); BinaryReader br = new(fs); T[][] result = new T[NumRows][]; int endX = xOff + sizeX; for (int row = 0; row < sizeY; row++) { result[row] = new T[sizeX]; // Position the binary reader at the beginning of the window fs.Seek(ByteSize * xOff, SeekOrigin.Current); byte[] values = br.ReadBytes(sizeX * ByteSize); Buffer.BlockCopy(values, 0, result[row], 0, ByteSize * sizeX); pm.CurrentValue = row; fs.Seek(ByteSize * (NumColumnsInFile - endX), SeekOrigin.Current); } br.Close(); return(result); }
/// <summary> /// Reads the the contents for the "window" specified by the start and end values /// for the rows and columns. /// </summary> public void Read() { FileStream fs = new(Filename, FileMode.Open, FileAccess.Read, FileShare.Read, NumColumns *ByteSize); ProgressMeter pm = new(ProgressHandler, DataStrings.ReadingValuesFrom_S.Replace("%S", Filename), NumRows); fs.Seek(HeaderSize, SeekOrigin.Begin); // Position the binary reader at the top of the "window" fs.Seek(StartRow * NumColumnsInFile * ByteSize, SeekOrigin.Current); BinaryReader br = new(fs); Data = new T[NumRows][]; T min = MinValue; T max = MaxValue; double total = 0; double sqrTotal = 0; T noDataValue = ConvertTo <T>(NoDataValue); for (int row = 0; row < NumRows; row++) { Data[row] = new T[NumColumns]; // Position the binary reader at the beginning of the window fs.Seek(4 * StartColumn, SeekOrigin.Current); for (int col = 0; col < NumColumns; col++) { T val = br.Read <T>(); if (!EqualityComparer <T> .Default.Equals(val, noDataValue)) { if (Operator.GreaterThan(val, max)) { max = val; } if (Operator.LessThan(val, min)) { min = val; } double valAsDouble = Convert.ToDouble(val); total += valAsDouble; sqrTotal += valAsDouble * valAsDouble; NumValueCells++; } Data[row][col] = val; } pm.CurrentValue = row; fs.Seek(ByteSize * (NumColumnsInFile - EndColumn - 1), SeekOrigin.Current); } Maximum = Convert.ToDouble(max); Minimum = Convert.ToDouble(min); StdDeviation = Math.Sqrt((sqrTotal / NumValueCells) - (total / NumValueCells) * (total / NumValueCells)); br.Close(); }
/// <summary> /// Copies the contents from the specified sourceRaster into this sourceRaster. If both rasters are InRam, this does not affect the files. /// </summary> /// <param name="sourceRaster">The raster of values to paste into this raster. If the CellWidth and CellHeight values do not match between the files, /// an exception will be thrown. If the sourceRaster overlaps with the edge of this raster, only the intersecting region will be /// pasted.</param> /// <param name="startRow">Specifies the row in this raster where the top row of the sourceRaster will be pasted. </param> /// <param name="startColumn">Specifies the column in this raster where the left column of the sourceRaster will be pasted.</param> public void PasteRaster(Raster <T> sourceRaster, int startRow, int startColumn) { int byteSize = ByteSize; if (sourceRaster.DataType != typeof(int)) { throw new ArgumentException(DataStrings.ArgumentOfWrongType_S1_S2.Replace("%S1", "sourceRaster").Replace("%S2", "BinaryRaster")); } if (startRow + sourceRaster.NumRows <= 0) { return; // sourceRaster is above this raster } if (startColumn + sourceRaster.NumColumns <= 0) { return; // sourceRaster is left of this raster } if (startRow > NumRows) { return; // sourceRaster is below this raster } if (startColumn > NumColumns) { return; // sourceRaster is to the right of this raster } if (sourceRaster.CellWidth != CellWidth || sourceRaster.CellHeight != CellHeight) { throw new ArgumentException(DataStrings.RastersNeedSameCellSize); } // These are specified in coordinates that match the source raster int sourceStartColumn = 0; int sourceStartRow = 0; int destStartColumn = startColumn; int destStartRow = startRow; int numPasteColumns = sourceRaster.NumColumns; int numPasteRows = sourceRaster.NumRows; // adjust range to cover only the overlapping sections if (startColumn < 0) { sourceStartColumn = -startColumn; destStartColumn = 0; } if (startRow < 0) { sourceStartRow = -startRow; destStartRow = 0; } if (numPasteRows + destStartRow > NumRows) { numPasteRows = NumRows - destStartRow; } if (numPasteColumns + destStartColumn > NumColumns) { numPasteColumns = NumColumns - destStartRow; } if (IsInRam) { // ---------------------- RAM BASED ------------------------------------------------------ if (sourceRaster.IsInRam) { // both members are inram, so directly copy values. for (int row = 0; row < numPasteRows; row++) { for (int col = 0; col < numPasteColumns; col++) { // since we are copying direct, we don't have to do a type check on T Data[destStartRow + row][destStartColumn + col] = sourceRaster.Data[sourceStartRow + row][sourceStartColumn + col]; } } } else { FileStream fs = new(sourceRaster.Filename, FileMode.Open, FileAccess.Write, FileShare.None, numPasteColumns *byteSize); ProgressMeter pm = new(ProgressHandler, DataStrings.ReadingValuesFrom_S.Replace("%S", sourceRaster.Filename), numPasteRows); fs.Seek(HeaderSize, SeekOrigin.Begin); // Position the binary reader at the top of the "sourceRaster" fs.Seek(sourceStartRow * sourceRaster.NumColumnsInFile * byteSize, SeekOrigin.Current); BinaryReader br = new(fs); for (int row = 0; row < numPasteRows; row++) { // Position the binary reader at the beginning of the sourceRaster fs.Seek(byteSize * sourceStartColumn, SeekOrigin.Current); for (int col = 0; col < numPasteColumns; col++) { Data[destStartRow + row][destStartColumn + col] = br.Read <T>(); } pm.CurrentValue = row; fs.Seek(byteSize * (NumColumnsInFile - sourceStartColumn - numPasteColumns), SeekOrigin.Current); } br.Close(); } // The statistics will have changed with the newly pasted data involved GetStatistics(); } else { // ----------------------------------------- FILE BASED --------------------------------- FileStream writefs = new(Filename, FileMode.Open, FileAccess.Write, FileShare.None, NumColumns *byteSize); BinaryWriter bWriter = new(writefs); ProgressMeter pm = new(ProgressHandler, DataStrings.WritingValues_S.Replace("%S", Filename), numPasteRows); writefs.Seek(HeaderSize, SeekOrigin.Begin); writefs.Seek(destStartRow * NumColumnsInFile * byteSize, SeekOrigin.Current); // advance to top of paste window area if (sourceRaster.IsInRam) { // we can just write values for (int row = 0; row < numPasteColumns; row++) { // Position the binary reader at the beginning of the sourceRaster writefs.Seek(byteSize * destStartColumn, SeekOrigin.Current); for (int col = 0; col < numPasteColumns; col++) { T val = sourceRaster.Data[sourceStartRow + row][sourceStartColumn + col]; bWriter.Write(val); } pm.CurrentValue = row; writefs.Seek(byteSize * (NumColumnsInFile - destStartColumn - numPasteColumns), SeekOrigin.Current); } } else { // Since everything is handled from a file, we don't have to type check. Just copy the bytes. FileStream readfs = new(sourceRaster.Filename, FileMode.Open, FileAccess.Read, FileShare.Read, numPasteColumns *byteSize); BinaryReader bReader = new(readfs); readfs.Seek(HeaderSize, SeekOrigin.Begin); readfs.Seek(sourceStartRow * sourceRaster.NumColumnsInFile * byteSize, SeekOrigin.Current); // advances to top of paste window area for (int row = 0; row < numPasteRows; row++) { readfs.Seek(sourceStartColumn * byteSize, SeekOrigin.Current); writefs.Seek(destStartColumn * byteSize, SeekOrigin.Current); byte[] rowData = bReader.ReadBytes(numPasteColumns * byteSize); bWriter.Write(rowData); readfs.Seek(sourceRaster.NumColumnsInFile - sourceStartColumn - numPasteColumns, SeekOrigin.Current); writefs.Seek(NumColumnsInFile - destStartColumn - numPasteColumns, SeekOrigin.Current); } bReader.Close(); } bWriter.Close(); } }