public GRIB_Point[] Read() { try { if (_fs != null) { IGribBitMapSection bms = null; GRIB_Point[] points = null; bool isConstant = false; _fs.Seek(_dataOffset, SeekOrigin.Begin); if (_isBmsExist) { bms = new Grib1BitMapSection(_fs); } // octets 1-3 (section _length) int dataLength = GribNumberHelper.Uint3(_fs); // octet 4, 1st half (packing flag) int unusedbits = _fs.ReadByte(); if ((unusedbits & 192) != 0) { throw new NotSupportedException("BDS: (octet 4, 1st half) not grid point data and simple packing "); } // octet 4, 2nd half (number of unused bits at end of this section) unusedbits = unusedbits & 15; // octets 5-6 (binary scale factor) int binscale = GribNumberHelper.Int2(_fs); // octets 7-10 (reference point = minimum value) float refvalue = GribNumberHelper.Float4(_fs); // octet 11 (number of bits per value) int numbits = _fs.ReadByte(); if (numbits == 0) { isConstant = true; } float refRenamed = (float)(Math.Pow(10.0, -_decscale) * refvalue); float scale = (float)(System.Math.Pow(10.0, -_decscale) * System.Math.Pow(2.0, binscale)); if (_firstlat == 0 & _lastlat == 90) { if (bms != null) { bool[] bitmap = bms.Bitmap; points = new GRIB_Point[bitmap.Length]; for (int i = 0; i < bitmap.Length; i++) { int m = (_height - (int)(i / _width) - 1) * _width + (i % _width); if (bitmap[i]) { if (!isConstant) { points[m] = new GRIB_Point(); points[m].Index = i; points[m].Value = refRenamed + scale * Bits2UInt(numbits, _fs); } else { // rdg - added this to handle a constant valued parameter points[m] = new GRIB_Point(); points[m].Index = i; points[m].Value = refRenamed; } } else { points[m] = new GRIB_Point(); points[m].Index = i; points[m].Value = -9999f; } } } else { if (!isConstant) { points = new GRIB_Point[((dataLength - 11) * 8 - unusedbits) / numbits]; for (int i = 0; i < points.Length; i++) { int m = (_height - (int)(i / _width) - 1) * _width + (i % _width); points[m] = new GRIB_Point(); points[m].Index = i; points[m].Value = refRenamed + scale * Bits2UInt(numbits, _fs); } } else { // constant valued - same min and max int x = 0, y = 0; _fs.Seek(_fs.Position - 53, SeekOrigin.Begin); // return to start of GDS dataLength = (int)GribNumberHelper.Uint3(_fs); if (dataLength == 42) { // Lambert/Mercator offset _fs.Seek(3, SeekOrigin.Current); x = GribNumberHelper.Int2(_fs); y = GribNumberHelper.Int2(_fs); } else { _fs.Seek(7, SeekOrigin.Current); dataLength = GribNumberHelper.Uint3(_fs); if (dataLength == 32) { // Polar sterographic _fs.Seek(3, SeekOrigin.Current); x = GribNumberHelper.Int2(_fs); y = GribNumberHelper.Int2(_fs); } else { x = y = 1; } } points = new GRIB_Point[x * y]; for (int i = 0; i < points.Length; i++) { int m = (_height - (int)(i / _width) - 1) * _width + (i % _width); points[m] = new GRIB_Point(); points[m].Index = i; points[m].Value = refRenamed; } } } } else { if (bms != null) { bool[] bitmap = bms.Bitmap; points = new GRIB_Point[bitmap.Length]; for (int i = 0; i < bitmap.Length; i++) { if (bitmap[i]) { if (!isConstant) { points[i] = new GRIB_Point(); points[i].Index = i; points[i].Value = refRenamed + scale * Bits2UInt(numbits, _fs); } else { // rdg - added this to handle a constant valued parameter points[i] = new GRIB_Point(); points[i].Index = i; points[i].Value = refRenamed; } } else { points[i] = new GRIB_Point(); points[i].Index = i; points[i].Value = -9999f; } } } else { if (!isConstant) { points = new GRIB_Point[((dataLength - 11) * 8 - unusedbits) / numbits]; for (int i = 0; i < points.Length; i++) { points[i] = new GRIB_Point(); points[i].Index = i; points[i].Value = refRenamed + scale * Bits2UInt(numbits, _fs); } } else { // constant valued - same min and max int x = 0, y = 0; _fs.Seek(_fs.Position - 53, SeekOrigin.Begin); // return to start of GDS dataLength = (int)GribNumberHelper.Uint3(_fs); if (dataLength == 42) { // Lambert/Mercator offset _fs.Seek(3, SeekOrigin.Current); x = GribNumberHelper.Int2(_fs); y = GribNumberHelper.Int2(_fs); } else { _fs.Seek(7, SeekOrigin.Current); dataLength = GribNumberHelper.Uint3(_fs); if (dataLength == 32) { // Polar sterographic _fs.Seek(3, SeekOrigin.Current); x = GribNumberHelper.Int2(_fs); y = GribNumberHelper.Int2(_fs); } else { x = y = 1; } } points = new GRIB_Point[x * y]; for (int i = 0; i < points.Length; i++) { points[i] = new GRIB_Point(); points[i].Index = i; points[i].Value = refRenamed; } } } } return(points); } return(null); } finally { _fs.Seek(0, SeekOrigin.Begin); } }