/// <summary> /// Constructor /// </summary> /// <param name="br">binary reader</param> /// <param name="aDataInfo">GRIB1 data info</param> public GRIB1Message(BinaryReader br, GRIB1DataInfo aDataInfo) { RecordIS = new GRIB1IndicatorSection(br); // read Indicator Section RecordPDS = new GRIB1ProductDefineSection(br); // read Product Definition Section if (RecordPDS.GDSExist) { RecordGDS = new GRIB1GridDefineSection(br); } else { //throw new NoValidGribException("GribRecord: No GDS included."); } if (RecordPDS.BMSExist) { RecordBMS = new GRIB1BitMapSection(br); // read Bitmap Section } // read Binary Data Section if (RecordPDS.GDSExist) { RecordBDS = new GRIB1BinaryDataSection(br, RecordPDS.DecimalScale, RecordBMS, RecordGDS.ScanMode, RecordGDS.NX, RecordGDS.NY); } else { RecordBDS = new GRIB1BinaryDataSection(br, RecordPDS.DecimalScale, RecordBMS, 64, aDataInfo.X.Length, aDataInfo.Y.Length); } }
/// <summary> /// Constructor /// </summary> /// <param name="br">binary reader</param> /// <param name="decimalscale">decimal scale</param> /// <param name="bms">GRIB 1 BMS</param> /// <param name="scanMode">scan mode</param> /// <param name="Xlength">X coordinate number</param> /// <param name="Ylength">Y coordinate number</param> public GRIB1BinaryDataSection(BinaryReader br, int decimalscale, GRIB1BitMapSection bms, int scanMode, int Xlength, int Ylength) { byte[] bytes = br.ReadBytes(3); Length = Bytes2Number.Uint3(bytes[0], bytes[1], bytes[2]); br.BaseStream.Seek(-3, SeekOrigin.Current); bytes = br.ReadBytes(11); //Read before the data array. // octet 4, 1st half (packing flag) int unusedbits = Convert.ToInt32(bytes[3]); if ((unusedbits & 192) != 0) { throw new NotSupportedException( "Grib1BinaryDataSection: (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; BinScale = Bytes2Number.Int2(bytes[4], bytes[5]); RefValue = Bytes2Number.Float4(bytes[6], bytes[7], bytes[8], bytes[9]); NumBits = Convert.ToInt32(bytes[10]); if (NumBits == 0) { IsConstant = true; } // *** read values ************************************************************ float refd = (float)(Math.Pow(10.0, -decimalscale) * RefValue); float scale = (float)(Math.Pow(10.0, -decimalscale) * Math.Pow(2.0, BinScale)); if (bms != null) { bool[] bitmap = bms.Bitmap; Data = new double[bitmap.Length]; for (int i = 0; i < bitmap.Length; i++) { if (bitmap[i]) { if (!IsConstant) { Data[i] = refd + scale * Bits2UInt(NumBits, br); if (Data[i] > MaxValue) { MaxValue = Data[i]; } if (Data[i] < MinValue) { MinValue = Data[i]; } } else {// rdg - added this to handle a constant valued parameter Data[i] = refd; } } else { Data[i] = UNDEF; } } ScanningModeCheck(scanMode, Xlength); } else { if (!IsConstant) { Data = new double[((Length - 11) * 8 - unusedbits) / NumBits]; for (int i = 0; i < Data.Length; i++) { Data[i] = refd + scale * Bits2UInt(NumBits, br); if (Data[i] > MaxValue) { MaxValue = this.Data[i]; } if (Data[i] < MinValue) { MinValue = this.Data[i]; } } ScanningModeCheck(scanMode, Xlength); } else { // constant valued - same min and max Data = new double[Xlength * Ylength]; MaxValue = refd; MinValue = refd; for (int i = 0; i < Data.Length; i++) { Data[i] = refd; } } } }