/// <summary> /// Calls the basic setup for the raster. /// </summary> protected void Initialize() { StartRow = 0; EndRow = NumRows - 1; StartColumn = 0; EndColumn = NumColumns - 1; NumColumnsInFile = NumColumns; NumRowsInFile = NumRows; // Just set the cell size to one NumValueCells = 0; if (IsInRam) { Bounds = new RasterBounds(NumRows, NumColumns, new[] { 0.5, 1.0, 0.0, NumRows - .5, 0.0, -1.0 }); Data = new T[NumRows][]; for (int row = 0; row < NumRows; row++) { Data[row] = new T[NumColumns]; } } Value = new ValueGrid <T>(this); NoDataValue = Global.ToDouble(Global.MinimumValue <T>()); DataType = typeof(T); }
/// <summary> /// Opens the specified file /// </summary> public override void Open() { NoDataValue = Global.ToDouble(Global.MinimumValue <T>()); // Sets it to the appropriate minimum for the int datatype ReadHeader(Filename); StartRow = 0; EndRow = NumRows - 1; StartColumn = 0; EndColumn = NumColumns - 1; NumColumnsInFile = NumColumns; NumRowsInFile = NumRows; NumValueCells = 0; Value = new ValueGrid <T>(this); DataType = typeof(T); if (base.NumColumnsInFile * base.NumRowsInFile < 64000000) { base.IsInRam = true; Data = ReadRaster(); base.GetStatistics(); } else { base.IsInRam = false; // Don't read in any data at this point. Let the user use ReadRaster for specific blocks. } }
/// <summary> /// Obtains only the statistics for the small window specified by startRow, endRow etc. /// This only works if the window is also InRam. /// </summary> public void GetWindowStatistics() { if (IsInRam == false) { throw new ArgumentException(DataStrings.RasterRequiresCast); } ProgressMeter pm = new ProgressMeter(ProgressHandler, "Calculating Statistics.", NumRows); double total = 0; double sqrTotal = 0; int count = 0; T min = Global.MaximumValue <T>(); T max = Global.MinimumValue <T>(); for (int row = 0; row < NumRows; row++) { for (int col = 0; col < NumColumns; col++) { T val = Data[row][col]; double dblVal = Global.ToDouble(val); if (dblVal != NoDataValue) { if (val.CompareTo(max) > 0) { max = val; } if (val.CompareTo(min) < 0) { min = val; } total += dblVal; sqrTotal += dblVal * dblVal; count++; } } pm.CurrentValue = row; } Value.Updated = false; Minimum = Global.ToDouble(min); Maximum = Global.ToDouble(max); NumValueCells = count; StdDeviation = (float)Math.Sqrt((sqrTotal / NumValueCells) - (total / NumValueCells * (total / NumValueCells))); }
/// <summary> /// Writes the header, regardless of which subtype of binary raster this is written for /// </summary> /// <param name="fileName">The string fileName specifying what file to load</param> public void ReadHeader(string fileName) { using (var br = new BinaryReader(new FileStream(fileName, FileMode.Open))) { StartColumn = 0; NumColumns = br.ReadInt32(); NumColumnsInFile = NumColumns; EndColumn = NumColumns - 1; StartRow = 0; NumRows = br.ReadInt32(); NumRowsInFile = NumRows; EndRow = NumRows - 1; Bounds = new RasterBounds(NumRows, NumColumns, new[] { 0.0, 1.0, 0.0, NumRows, 0.0, -1.0 }); CellWidth = br.ReadDouble(); Bounds.AffineCoefficients[5] = -br.ReadDouble(); // dy Xllcenter = br.ReadDouble(); Yllcenter = br.ReadDouble(); br.ReadInt32(); // Read RasterDataType only to skip it since we know the type already. byte[] noDataBytes = br.ReadBytes(ByteSize); var nd = new T[1]; Buffer.BlockCopy(noDataBytes, 0, nd, 0, ByteSize); NoDataValue = Global.ToDouble(nd[0]); string proj = Encoding.Default.GetString(br.ReadBytes(255)).Replace('\0', ' ').Trim(); ProjectionString = proj; Notes = Encoding.Default.GetString(br.ReadBytes(255)).Replace('\0', ' ').Trim(); if (Notes.Length == 0) { Notes = null; } } string prj = Path.ChangeExtension(Filename, ".prj"); if (File.Exists(prj)) { using (var sr = new StreamReader(prj)) { ProjectionString = sr.ReadToEnd(); } } }
/// <summary> /// This involves boxing and unboxing as well as a convert to double, but IConvertible was /// not CLS Compliant, so we were always getting warnings about it. I am trying to make /// all the code CLS Compliant to remove warnings. /// </summary> /// <param name="value"></param> /// <returns></returns> public static double ToDouble(T value) { return(Global.ToDouble(value)); }
/// <summary> /// Gets the statistics of all the values. If the entire content is not currently in-ram, /// ReadRow will be used to read individual lines and perform the calculations. /// </summary> public override void GetStatistics() { ProgressMeter pm = new ProgressMeter(ProgressHandler, DataStrings.CalculatingStatistics, NumRows); T min = Global.MaximumValue <T>(); T max = Global.MinimumValue <T>(); double total = 0; double sqrTotal = 0; int count = 0; if (!IsInRam || !this.IsFullyWindowed()) { for (int row = 0; row < NumRowsInFile; row++) { T[] values = ReadRow(row); for (int col = 0; col < NumColumnsInFile; col++) { T val = values[col]; double dblVal = Global.ToDouble(val); if (dblVal == NoDataValue) { continue; } if (val.CompareTo(max) > 0) { max = val; } if (val.CompareTo(min) < 0) { min = val; } total += dblVal; sqrTotal += dblVal * dblVal; count++; } pm.CurrentValue = row; } } else { for (int row = 0; row < NumRows; row++) { for (int col = 0; col < NumColumns; col++) { T val = Data[row][col]; double dblVal = Global.ToDouble(val); if (dblVal == NoDataValue) { continue; } if (val.CompareTo(max) > 0) { max = val; } if (val.CompareTo(min) < 0) { min = val; } total += dblVal; sqrTotal += dblVal * dblVal; count++; } pm.CurrentValue = row; } } Value.Updated = false; Minimum = Global.ToDouble(min); Maximum = Global.ToDouble(max); Mean = total / count; NumValueCells = count; StdDeviation = (float)Math.Sqrt((sqrTotal / NumValueCells) - (total / NumValueCells * (total / NumValueCells))); pm.Reset(); }