/// <summary> /// Constructor /// </summary> /// <param name="br">binary reader</param> public GRIB2BitMapSection(BinaryReader br) { long sectionEnd = br.BaseStream.Position; Length = Bytes2Number.Int4(br); sectionEnd += Length; SectionNum = br.ReadByte(); BitMapIndicator = br.ReadByte(); //No bit map if (BitMapIndicator != 0) { return; } //Get bit map data byte[] data = br.ReadBytes(Length - 6); Bitmap = new bool[(Length - 6) * 8]; int[] bitmask = { 128, 64, 32, 16, 8, 4, 2, 1 }; for (int i = 0; i < Bitmap.Length; i++) { Bitmap[i] = (data[i / 8] & bitmask[i % 8]) != 0; } //Set stream position to the section end br.BaseStream.Position = sectionEnd; }
/// <summary> /// Constructor /// </summary> /// <param name="br">binary reader</param> public GRIB2IdentificationSection(BinaryReader br) { byte[] bytes = br.ReadBytes(4); Length = Bytes2Number.Int4(bytes[0], bytes[1], bytes[2], bytes[3]); br.BaseStream.Seek(-4, SeekOrigin.Current); bytes = br.ReadBytes(Length); SectionNum = bytes[4]; CenterID = Bytes2Number.Int2(bytes[5], bytes[6]); SubCenterID = Bytes2Number.Int2(bytes[7], bytes[8]); MasterTableVersion = bytes[9]; LocalTableVersion = bytes[10]; SReferenceTime = bytes[11]; int year = Bytes2Number.Int2(bytes[12], bytes[13]); int month = bytes[14]; int day = bytes[15]; int hour = bytes[16]; int minute = bytes[17]; int second = bytes[18]; BaseTime = new DateTime(year, month, day, hour, minute, second); ProductStatus = bytes[19]; ProductType = bytes[20]; }
/// <summary> /// Constructor /// </summary> /// <param name="br">binary reader</param> public GRIB2LocalUseSection(BinaryReader br) { Length = Bytes2Number.Int4(br); br.BaseStream.Seek(-4, SeekOrigin.Current); byte[] bytes = br.ReadBytes(Length); SectionNum = bytes[4]; }
/// <summary> /// Constructor /// </summary> ///<param name="br">binary reader</param> ///<param name="gds">grid definition section</param> ///<param name="drs">data representation section</param> ///<param name="bms">bit map section</param> public GRIB2DataSection(BinaryReader br, GRIB2GridDefinitionSection gds, GRIB2DataRepresentationSection drs, GRIB2BitMapSection bms) { for (int i = 0; i < 31; i++) { bitsmv1[i] = (int)Math.Pow((double)2, (double)i) - 1; } Length = Bytes2Number.Int4(br); SectionNum = br.ReadByte(); int dtn = drs.DataTemplateNum; if (dtn == 0) { // 0: Grid point data - simple packing SimpleUnpacking(br, gds, drs, bms); } else if (dtn == 1) { // 1: Matrix values - simple packing Data = null; //logger.error("Matrix values - simple packing not implemented"); } else if (dtn == 2) { // 2:Grid point data - complex packing ComplexUnpacking(br, gds, drs, bms); } else if (dtn == 3) { // 3: complex packing with spatial differencing ComplexUnpackingWithSpatial(br, gds, drs, bms); } else if ((dtn == 40) || (dtn == 40000)) { // JPEG 2000 Stream Format jpeg2000Unpacking(br, gds, drs, bms); //MessageBox.Show("The packing method is not supported at present!", "Error"); } }
/// <summary> /// Constructor /// </summary> /// <param name="br">binary reader</param> public GRIB2DataRepresentationSection(BinaryReader br) { long sectionEnd = br.BaseStream.Position; Length = Bytes2Number.Int4(br); sectionEnd += Length; SectionNum = br.ReadByte(); DataPoints = Bytes2Number.Int4(br); DataTemplateNum = Bytes2Number.Uint2(br); switch (DataTemplateNum) { // Data Template Number case 0: case 1: // 0 - Grid point data - simple packing // 1 - Matrix values - simple packing //ReferenceValue = br.ReadSingle(); ReferenceValue = Bytes2Number.Float(br); BinaryScaleFactor = Bytes2Number.Int2(br); DecimalScaleFactor = Bytes2Number.Int2(br); NumberOfBits = br.ReadByte(); //System.out.println( "DRS numberOfBits=" + numberOfBits ); originalType = br.ReadByte(); //System.out.println( "DRS originalType=" + originalType ); if (DataTemplateNum == 0) { break; } // case 1 not implememted //System.out.println("DRS dataTemplate=1 not implemented yet"); break; case 2: case 3: // Grid point data - complex packing //System.out.println( "DRS dataTemplate=" + dataTemplate ); // octet 12 - 15 //ReferenceValue = br.ReadSingle(); ReferenceValue = Bytes2Number.Float(br); // octet 16 - 17 BinaryScaleFactor = Bytes2Number.Int2(br); // octet 18 - 19 DecimalScaleFactor = Bytes2Number.Int2(br); // octet 20 NumberOfBits = br.ReadByte(); //System.out.println( "DRS numberOfBits=" + numberOfBits ); // octet 21 originalType = br.ReadByte(); //System.out.println( "DRS originalType=" + originalType ); // octet 22 splittingMethod = br.ReadByte(); //System.out.println( "DRS splittingMethod=" + // splittingMethod ); // octet 23 MissingValueManagement = br.ReadByte(); //System.out.println( "DRS MissingValueManagement=" + // MissingValueManagement ); // octet 24 - 27 PrimaryMissingValue = br.ReadSingle(); // octet 28 - 31 SecondaryMissingValue = br.ReadSingle(); // octet 32 - 35 NumberOfGroups = Bytes2Number.Int4(br); //System.out.println( "DRS numberOfGroups=" + // numberOfGroups ); // octet 36 ReferenceGroupWidths = br.ReadByte(); //System.out.println( "DRS referenceGroupWidths=" + // referenceGroupWidths ); // octet 37 BitsGroupWidths = br.ReadByte(); // according to documentation subtract referenceGroupWidths // TODO: check again and delete //bitsGroupWidths = bitsGroupWidths - referenceGroupWidths; //System.out.println( "DRS bitsGroupWidths=" + // bitsGroupWidths ); // octet 38 - 41 ReferenceGroupLength = Bytes2Number.Int4(br); //System.out.println( "DRS referenceGroupLength=" + // referenceGroupLength ); // octet 42 LengthIncrement = br.ReadByte(); //System.out.println( "DRS lengthIncrement=" + // lengthIncrement ); // octet 43 - 46 LengthLastGroup = Bytes2Number.Int4(br); //System.out.println( "DRS lengthLastGroup=" + // lengthLastGroup ); // octet 47 BitsScaledGroupLength = br.ReadByte(); //System.out.println( "DRS bitsScaledGroupLength=" + // bitsScaledGroupLength ); if (DataTemplateNum == 2) { break; } // case 3 // complex packing & spatial differencing // octet 48 OrderSpatial = br.ReadByte(); //System.out.println( "DRS orderSpatial=" + orderSpatial); // octet 49 DescriptorSpatial = br.ReadByte(); //System.out.println( "DRS descriptorSpatial=" + descriptorSpatial); break; case 40: case 40000: // Grid point data - JPEG 2000 Code Stream Format //System.out.println( "DRS dataTemplate=" + dataTemplate ); //ReferenceValue = br.ReadSingle(); ReferenceValue = Bytes2Number.Float(br); BinaryScaleFactor = Bytes2Number.Int2(br); DecimalScaleFactor = Bytes2Number.Int2(br); NumberOfBits = br.ReadByte(); //System.out.println( "DRS numberOfBits=" + numberOfBits ); originalType = br.ReadByte(); //System.out.println( "DRS originalType=" + originalType ); compressionMethod = br.ReadByte(); //System.out.println( "DRS compressionMethod=" + compressionMethod ); compressionRatio = br.ReadByte(); //System.out.println( "DRS compressionRatio=" + compressionRatio ); break; default: break; } //Set stream position to the section end br.BaseStream.Position = sectionEnd; }
///// <summary> ///// check sum ///// </summary> //private String checksum = ""; ///// <summary> ///// 4.0 indexes use this for the GDS key ///// </summary> //private int gdskey; #endregion #region Constructor /// <summary> /// Constructor /// </summary> /// <param name="br">binary reader</param> public GRIB2GridDefinitionSection(BinaryReader br) { float ratio; double checkSum; int scalefactorradius = 0; int scaledvalueradius = 0; int scalefactormajor = 0; int scaledvaluemajor = 0; int scalefactorminor = 0; int scaledvalueminor = 0; long sectionEnd = br.BaseStream.Position; Length = Bytes2Number.Int4(br); sectionEnd += Length; SectionNum = br.ReadByte(); SourceGridDef = br.ReadByte(); NumPoints = Bytes2Number.Int4(br); checkSum = NumPoints; Olon = br.ReadByte(); Iolon = br.ReadByte(); TemplateNum = Bytes2Number.Int2(br); GridName = GetGridName(TemplateNum); switch (TemplateNum) { // Grid Definition Template Number case 0: case 1: case 2: case 3: // Latitude/Longitude Grid Shape = br.ReadByte(); //System.out.println( "shape=" + shape ); scalefactorradius = br.ReadByte(); scaledvalueradius = Bytes2Number.Int4(br); scalefactormajor = br.ReadByte(); scaledvaluemajor = Bytes2Number.Int4(br); scalefactorminor = br.ReadByte(); scaledvalueminor = Bytes2Number.Int4(br); NX = Bytes2Number.Int4(br); NY = Bytes2Number.Int4(br); Angle = Bytes2Number.Int4(br); SubdivisionsAngle = Bytes2Number.Int4(br); if (Angle == 0) { ratio = tenToNegSix; } else { ratio = Angle / SubdivisionsAngle; } la1 = (float)(Bytes2Number.Int4(br) * ratio); checkSum = 7 * checkSum + la1; lo1 = (float)(Bytes2Number.Int4(br) * ratio); checkSum = 7 * checkSum + lo1; resolution = br.ReadByte(); la2 = (float)(Bytes2Number.Int4(br) * ratio); checkSum = 7 * checkSum + la2; lo2 = (float)(Bytes2Number.Int4(br) * ratio); checkSum = 7 * checkSum + lo2; dx = (float)(Bytes2Number.Int4(br) * ratio); //checkSum = 7 * checkSum + dx; dy = (float)(Bytes2Number.Int4(br) * ratio); grid_units = "degrees"; //checkSum = 7 * checkSum + dy; ScanMode = br.ReadByte(); // 1, 2, and 3 needs checked if (TemplateNum == 1) { //Rotated Latitude/longitude spLat = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + spLat; spLon = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + spLon; rotationangle = br.ReadSingle(); } else if (TemplateNum == 2) { //Stretched Latitude/longitude poleLat = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + poleLat; poleLon = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + poleLon; factor = Bytes2Number.Int4(br); } else if (TemplateNum == 3) { //Stretched and Rotated // Latitude/longitude spLat = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + spLat; spLon = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + spLon; rotationangle = br.ReadSingle(); poleLat = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + poleLat; poleLon = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + poleLon; factor = Bytes2Number.Int4(br); } break; case 10: // Mercator // la1, lo1, lad, la2, and lo2 need checked Shape = br.ReadByte(); //System.out.println( "shape=" + shape ); scalefactorradius = br.ReadByte(); scaledvalueradius = Bytes2Number.Int4(br); scalefactormajor = br.ReadByte(); scaledvaluemajor = Bytes2Number.Int4(br); scalefactorminor = br.ReadByte(); scaledvalueminor = Bytes2Number.Int4(br); NX = Bytes2Number.Int4(br); //System.out.println( "nx=" + nx); NY = Bytes2Number.Int4(br); //System.out.println( "ny=" + ny); la1 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + la1; lo1 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + lo1; resolution = br.ReadByte(); lad = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + lad; la2 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + la2; lo2 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + lo2; ScanMode = br.ReadByte(); Angle = Bytes2Number.Int4(br); dx = (float)(Bytes2Number.Int4(br) * tenToNegThree); //checkSum = 7 * checkSum + dx; dy = (float)(Bytes2Number.Int4(br) * tenToNegThree); //checkSum = 7 * checkSum + dy; grid_units = "m"; break; case 20: // Polar stereographic projection // la1, lo1, lad, and lov need checked Shape = br.ReadByte(); //System.out.println( "shape=" + shape ); scalefactorradius = br.ReadByte(); scaledvalueradius = Bytes2Number.Int4(br); scalefactormajor = br.ReadByte(); scaledvaluemajor = Bytes2Number.Int4(br); scalefactorminor = br.ReadByte(); scaledvalueminor = Bytes2Number.Int4(br); NX = Bytes2Number.Int4(br); //System.out.println( "nx=" + nx); NY = Bytes2Number.Int4(br); //System.out.println( "ny=" + ny); la1 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + la1; lo1 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + lo1; resolution = br.ReadByte(); lad = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + lad; lov = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + lov; dx = (float)(Bytes2Number.Int4(br) * tenToNegThree); //checkSum = 7 * checkSum + dx; dy = (float)(Bytes2Number.Int4(br) * tenToNegThree); grid_units = "m"; //checkSum = 7 * checkSum + dy; projectionCenter = br.ReadByte(); ScanMode = br.ReadByte(); break; case 30: // Lambert Conformal Shape = br.ReadByte(); //System.out.println( "shape=" + shape ); scalefactorradius = br.ReadByte(); scaledvalueradius = Bytes2Number.Int4(br); scalefactormajor = br.ReadByte(); scaledvaluemajor = Bytes2Number.Int4(br); scalefactorminor = br.ReadByte(); scaledvalueminor = Bytes2Number.Int4(br); NX = Bytes2Number.Int4(br); //System.out.println( "nx=" + nx); NY = Bytes2Number.Int4(br); //System.out.println( "ny=" + ny); la1 = (float)(Bytes2Number.Int4(br) * tenToNegSix); checkSum = 7 * checkSum + la1; //System.out.println( "la1=" + la1 ); lo1 = (float)(Bytes2Number.Int4(br) * tenToNegSix); checkSum = 7 * checkSum + lo1; //System.out.println( "lo1=" + lo1); resolution = br.ReadByte(); lad = (float)(Bytes2Number.Int4(br) * tenToNegSix); checkSum = 7 * checkSum + lad; lov = (float)(Bytes2Number.Int4(br) * tenToNegSix); checkSum = 7 * checkSum + lov; dx = (float)(Bytes2Number.Int4(br) * tenToNegThree); //checkSum = 7 * checkSum + dx; dy = (float)(Bytes2Number.Int4(br) * tenToNegThree); //checkSum = 7 * checkSum + dy; grid_units = "m"; projectionCenter = br.ReadByte(); ScanMode = br.ReadByte(); latin1 = (float)(Bytes2Number.Int4(br) * tenToNegSix); checkSum = 7 * checkSum + latin1; latin2 = (float)(Bytes2Number.Int4(br) * tenToNegSix); checkSum = 7 * checkSum + latin2; //System.out.println( "latin1=" + latin1); //System.out.println( "latin2=" + latin2); spLat = (float)(Bytes2Number.Int4(br) * tenToNegSix); checkSum = 7 * checkSum + spLat; spLon = (float)(Bytes2Number.Int4(br) * tenToNegSix); checkSum = 7 * checkSum + spLon; //System.out.println( "spLat=" + spLat); //System.out.println( "spLon=" + spLon); break; case 31: // Albers Equal Area // la1, lo1, lad, and lov need checked Shape = br.ReadByte(); //System.out.println( "shape=" + shape ); scalefactorradius = br.ReadByte(); scaledvalueradius = Bytes2Number.Int4(br); scalefactormajor = br.ReadByte(); scaledvaluemajor = Bytes2Number.Int4(br); scalefactorminor = br.ReadByte(); scaledvalueminor = Bytes2Number.Int4(br); NX = Bytes2Number.Int4(br); //System.out.println( "nx=" + nx); NY = Bytes2Number.Int4(br); //System.out.println( "ny=" + ny); la1 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + la1; //System.out.println( "la1=" + la1 ); lo1 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + lo1; //System.out.println( "lo1=" + lo1); resolution = br.ReadByte(); lad = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + lad; lov = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + lov; dx = (float)(Bytes2Number.Int4(br) * tenToNegThree); //checkSum = 7 * checkSum + dx; dy = (float)(Bytes2Number.Int4(br) * tenToNegThree); //checkSum = 7 * checkSum + dy; grid_units = "m"; projectionCenter = br.ReadByte(); ScanMode = br.ReadByte(); latin1 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + latin1; latin2 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + latin2; //System.out.println( "latin1=" + latin1); //System.out.println( "latin2=" + latin2); spLat = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + spLat; spLon = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + spLon; //System.out.println( "spLat=" + spLat); //System.out.println( "spLon=" + spLon); break; case 40: case 41: case 42: case 43: // Gaussian latitude/longitude // octet 15 Shape = br.ReadByte(); //System.out.println( "shape=" + shape ); // octet 16 scalefactorradius = br.ReadByte(); // octets 17-20 scaledvalueradius = Bytes2Number.Int4(br); // octet 21 scalefactormajor = br.ReadByte(); // octets 22-25 scaledvaluemajor = Bytes2Number.Int4(br); // octet 26 scalefactorminor = br.ReadByte(); // octets 27-30 scaledvalueminor = Bytes2Number.Int4(br); // octets 31-34 NX = Bytes2Number.Int4(br); //System.out.println( "nx=" + nx); // octets 35-38 NY = Bytes2Number.Int4(br); //System.out.println( "ny=" + ny); // octets 39-42 Angle = Bytes2Number.Int4(br); // octets 43-46 SubdivisionsAngle = Bytes2Number.Int4(br); if (Angle == 0) { ratio = tenToNegSix; } else { ratio = Angle / SubdivisionsAngle; } //System.out.println( "ratio =" + ratio ); // octets 47-50 la1 = (float)(Bytes2Number.Int4(br) * ratio); checkSum = 7 * checkSum + la1; // octets 51-54 lo1 = (float)(Bytes2Number.Int4(br) * ratio); checkSum = 7 * checkSum + lo1; // octet 55 resolution = br.ReadByte(); // octets 56-59 la2 = (float)(Bytes2Number.Int4(br) * ratio); checkSum = 7 * checkSum + la2; // octets 60-63 lo2 = (float)(Bytes2Number.Int4(br) * ratio); checkSum = 7 * checkSum + lo2; // octets 64-67 dx = (float)(Bytes2Number.Int4(br) * ratio); //checkSum = 7 * checkSum + dx; grid_units = "degrees"; // octet 68-71 n = Bytes2Number.Int4(br); // octet 72 ScanMode = br.ReadByte(); if (TemplateNum == 41) { //Rotated Gaussian Latitude/longitude // octets 73-76 spLat = Bytes2Number.Int4(br) * ratio; checkSum = 7 * checkSum + spLat; // octets 77-80 spLon = Bytes2Number.Int4(br) * ratio; checkSum = 7 * checkSum + spLon; // octets 81-84 rotationangle = br.ReadSingle(); } else if (TemplateNum == 42) { //Stretched Gaussian // Latitude/longitude // octets 73-76 poleLat = Bytes2Number.Int4(br) * ratio; checkSum = 7 * checkSum + poleLat; // octets 77-80 poleLon = Bytes2Number.Int4(br) * ratio; checkSum = 7 * checkSum + poleLon; // octets 81-84 factor = Bytes2Number.Int4(br); } else if (TemplateNum == 43) { //Stretched and Rotated Gaussian // Latitude/longitude // octets 73-76 spLat = Bytes2Number.Int4(br) * ratio; checkSum = 7 * checkSum + spLat; // octets 77-80 spLon = Bytes2Number.Int4(br) * ratio; checkSum = 7 * checkSum + spLon; // octets 81-84 rotationangle = br.ReadSingle(); // octets 85-88 poleLat = Bytes2Number.Int4(br) * ratio; checkSum = 7 * checkSum + poleLat; // octets 89-92 poleLon = Bytes2Number.Int4(br) * ratio; checkSum = 7 * checkSum + poleLon; // octets 93-96 factor = Bytes2Number.Int4(br); } break; case 50: case 51: case 52: case 53: // Spherical harmonic coefficients j = br.ReadSingle(); k = br.ReadSingle(); m = br.ReadSingle(); method = br.ReadByte(); mode = br.ReadByte(); grid_units = ""; if (TemplateNum == 51) { //Rotated Spherical harmonic coefficients spLat = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + spLat; spLon = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + spLon; rotationangle = br.ReadSingle(); } else if (TemplateNum == 52) { //Stretched Spherical // harmonic coefficients poleLat = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + poleLat; poleLon = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + poleLon; factor = Bytes2Number.Int4(br); } else if (TemplateNum == 53) { //Stretched and Rotated // Spherical harmonic coefficients spLat = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + spLat; spLon = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + spLon; rotationangle = br.ReadSingle(); poleLat = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + poleLat; poleLon = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + poleLon; factor = Bytes2Number.Int4(br); } break; case 90: // Space view perspective or orthographic Shape = br.ReadByte(); //System.out.println( "shape=" + shape ); scalefactorradius = br.ReadByte(); scaledvalueradius = Bytes2Number.Int4(br); scalefactormajor = br.ReadByte(); scaledvaluemajor = Bytes2Number.Int4(br); scalefactorminor = br.ReadByte(); scaledvalueminor = Bytes2Number.Int4(br); NX = Bytes2Number.Int4(br); //System.out.println( "nx=" + nx); NY = Bytes2Number.Int4(br); //System.out.println( "ny=" + ny); lap = Bytes2Number.Int4(br); checkSum = 7 * checkSum + lap; lop = Bytes2Number.Int4(br); checkSum = 7 * checkSum + lop; resolution = br.ReadByte(); dx = Bytes2Number.Int4(br); //checkSum = 7 * checkSum + dx; dy = Bytes2Number.Int4(br); //checkSum = 7 * checkSum + dy; grid_units = ""; xp = (float)(Bytes2Number.Int4(br) * tenToNegThree); checkSum = 7 * checkSum + xp; yp = (float)(Bytes2Number.Int4(br) * tenToNegThree); checkSum = 7 * checkSum + yp; ScanMode = br.ReadByte(); Angle = Bytes2Number.Int4(br); //altitude = Bytes2Number.int4( raf ) * 1000000; byte[] bytes = br.ReadBytes(4); altitude = Bytes2Number.Int4(bytes[0], bytes[1], bytes[2], bytes[3]); altitude = (int)(altitude * 6.378169 - 6378169); if ((bytes[0] & 256) == 256 && (bytes[1] & 256) == 256 && (bytes[2] & 256) == 256 && (bytes[3] & 256) == 256) { isOrtho = true; } //altitude = Bytes2Number.Int4(br); checkSum = 7 * checkSum + altitude; xo = Bytes2Number.Int4(br); checkSum = 7 * checkSum + xo; yo = Bytes2Number.Int4(br); checkSum = 7 * checkSum + yo; break; case 100: // Triangular grid based on an icosahedron n2 = br.ReadByte(); checkSum = 7 * checkSum + n2; n3 = br.ReadByte(); checkSum = 7 * checkSum + n3; ni = Bytes2Number.Int2(br); checkSum = 7 * checkSum + ni; nd = br.ReadByte(); checkSum = 7 * checkSum + nd; poleLat = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + poleLat; poleLon = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + poleLon; lonofcenter = Bytes2Number.Int4(br); position = br.ReadByte(); order = br.ReadByte(); ScanMode = br.ReadByte(); n = Bytes2Number.Int4(br); grid_units = ""; break; case 110: // Equatorial azimuthal equidistant projection Shape = br.ReadByte(); scalefactorradius = br.ReadByte(); scaledvalueradius = Bytes2Number.Int4(br); scalefactormajor = br.ReadByte(); scaledvaluemajor = Bytes2Number.Int4(br); scalefactorminor = br.ReadByte(); scaledvalueminor = Bytes2Number.Int4(br); NX = Bytes2Number.Int4(br); NY = Bytes2Number.Int4(br); la1 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + la1; lo1 = Bytes2Number.Int4(br) * tenToNegSix; checkSum = 7 * checkSum + lo1; resolution = br.ReadByte(); dx = (float)(Bytes2Number.Int4(br) * tenToNegThree); dy = (float)(Bytes2Number.Int4(br) * tenToNegThree); grid_units = ""; projectionCenter = br.ReadByte(); ScanMode = br.ReadByte(); break; case 120: // Azimuth-range Projection nb = Bytes2Number.Int4(br); checkSum = 7 * checkSum + nb; nr = Bytes2Number.Int4(br); checkSum = 7 * checkSum + nr; la1 = Bytes2Number.Int4(br); checkSum = 7 * checkSum + la1; lo1 = Bytes2Number.Int4(br); checkSum = 7 * checkSum + lo1; dx = Bytes2Number.Int4(br); //checkSum = 7 * checkSum + dx; grid_units = ""; dstart = br.ReadSingle(); ScanMode = br.ReadByte(); for (int i = 0; i < nr; i++) { // get azi (33+4(Nr-1))-(34+4(Nr-1)) // get adelta (35+4(Nr-1))-(36+4(Nr-1)) } break; case 204: // Curvilinear orthographic Shape = br.ReadByte(); //System.out.println( "shape=" + shape ); scalefactorradius = br.ReadByte(); scaledvalueradius = Bytes2Number.Int4(br); scalefactormajor = br.ReadByte(); scaledvaluemajor = Bytes2Number.Int4(br); scalefactorminor = br.ReadByte(); scaledvalueminor = Bytes2Number.Int4(br); NX = Bytes2Number.Int4(br); NY = Bytes2Number.Int4(br); // octets 39 - 54 not used, set to 0 br.ReadBytes(16); resolution = br.ReadByte(); // octets 56 - 71 not used br.ReadBytes(16); ScanMode = br.ReadByte(); grid_units = ""; break; default: break; } // end switch // calculate earth radius if (((TemplateNum < 50) || (TemplateNum > 53)) && (TemplateNum != 100) && (TemplateNum != 120)) { if (Shape == 0) { earthRadius = 6367470; } else if (Shape == 1) { earthRadius = scaledvalueradius; if (scalefactorradius != 0) { earthRadius /= (float)Math.Pow(10, scalefactorradius); } } else if (Shape == 2) { majorAxis = (float)6378160.0; minorAxis = (float)6356775.0; } else if (Shape == 3) { majorAxis = scaledvaluemajor; //System.out.println( "majorAxisScale =" + scalefactormajor ); //System.out.println( "majorAxisiValue =" + scaledvaluemajor ); majorAxis /= (float)Math.Pow(10, scalefactormajor); minorAxis = scaledvalueminor; //System.out.println( "minorAxisScale =" + scalefactorminor ); //System.out.println( "minorAxisValue =" + scaledvalueminor ); minorAxis /= (float)Math.Pow(10, scalefactorminor); } else if (Shape == 4) { majorAxis = (float)6378137.0; minorAxis = (float)6356752.314; } else if (Shape == 6) { earthRadius = 6371229; } } // This is a quasi-regular grid, save the number of pts in each parallel if (Olon != 0) { //System.out.println( "olon ="+ olon +" iolon ="+ iolon ); int numPts; if ((ScanMode & 32) == 0) { numPts = NY; } else { numPts = NX; } olonPts = new int[numPts]; //int count = 0; maxPts = 0; if (Olon == 1) { for (int i = 0; i < numPts; i++) { olonPts[i] = br.ReadByte(); if (maxPts < olonPts[i]) { maxPts = olonPts[i]; } //count += olonPts[ i ]; //System.out.println( "parallel =" + i +" number pts ="+ latPts ); } } else if (Olon == 2) { for (int i = 0; i < numPts; i++) { olonPts[i] = br.ReadUInt16(); if (maxPts < olonPts[i]) { maxPts = olonPts[i]; } //count += olonPts[ i ]; //System.out.println( "parallel =" + i +" number pts ="+ latPts ); } } if ((ScanMode & 32) == 0) { NX = maxPts; } else { NY = maxPts; } //double lodiff = gds.getLo2() - gds.getLo1(); dx = (float)(lo2 - lo1) / (NX - 0); //System.out.println( "total number pts ="+ count ); } //gdskey = Double.ToString(checkSum).HashCode(); //checksum = Integer.toString(gdskey); br.BaseStream.Position = sectionEnd; }
/// <summary> /// Read data info /// </summary> /// <param name="aFile">file path</param> public override void ReadDataInfo(string aFile) { this.FileName = aFile; FileStream fs = new FileStream(aFile, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); int headerType; int headerRecordLength; //Read primary header _primaryHeader.Header_Type = br.ReadByte(); _primaryHeader.Header_Record_Length = Bytes2Number.Uint2(br); _primaryHeader.File_Type_Code = br.ReadByte(); if (_primaryHeader.File_Type_Code != 0) { return; } _primaryHeader.Total_Header_Length = Bytes2Number.UInt(br.ReadBytes(4)); _primaryHeader.Data_Field_Length = Bytes2Number.UInt(br.ReadBytes(8)); _dataLength = (int)(br.BaseStream.Length - br.BaseStream.Position); //Read secondary headers while (true) { headerType = br.ReadByte(); if (br.BaseStream.Position > _primaryHeader.Total_Header_Length) { break; } if (headerType > 132) { break; } switch (headerType) { case 1: //Read header type#1 - Image Structure _imageStructure.Header_Type = headerType; _imageStructure.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2)); _imageStructure.NB = br.ReadByte(); _imageStructure.NC = Bytes2Number.UInt(br.ReadBytes(2)); _imageStructure.NL = Bytes2Number.UInt(br.ReadBytes(2)); _imageStructure.Compression_Flag = br.ReadByte(); break; case 2: //Read header type#2 - Image Navigation _imageNavigation.Header_Type = headerType; _imageNavigation.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2)); _imageNavigation.Projection_Name = ASCIIEncoding.ASCII.GetString(br.ReadBytes(32)).Trim(); _imageNavigation.CFAC = Bytes2Number.Int4(br); _imageNavigation.LFAC = Bytes2Number.Int4(br); _imageNavigation.COFF = Bytes2Number.Int4(br); _imageNavigation.LOFF = Bytes2Number.Int4(br); //_imageNavigation.CFAC = BitConverter.ToInt32(br.ReadBytes(4), 0); //_imageNavigation.LFAC = BitConverter.ToInt32(br.ReadBytes(4), 0); //_imageNavigation.COFF = BitConverter.ToInt32(br.ReadBytes(4), 0); //_imageNavigation.LOFF = BitConverter.ToInt32(br.ReadBytes(4), 0); break; case 3: //Read header type#3 - Image Data Function _imageDataFunction.Header_Type = headerType; _imageDataFunction.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2)); _imageDataFunction.Data_Definition_Block = ASCIIEncoding.ASCII.GetString(br.ReadBytes(_imageDataFunction.Header_Record_Length - 3)); break; case 4: //Read header type#4 - Annotation _annotation.Header_Type = headerType; _annotation.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2)); _annotation.Annotation_Text = ASCIIEncoding.ASCII.GetString(br.ReadBytes(_annotation.Header_Record_Length - 3)); break; case 5: //Read header type#5 - Time Stamp _timeStamp.Header_Type = headerType; _timeStamp.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2)); _timeStamp.CDS_P_Field = br.ReadByte(); _timeStamp.CDS_T_Field = Bytes2Number.UInt(br.ReadBytes(6)); break; case 128: //Read header type#128 - Image Segment Identification _imageSegmentID.Header_Type = headerType; _imageSegmentID.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2)); _imageSegmentID.Image_Segm_Seq_No = br.ReadByte(); _imageSegmentID.Total_No_Image_Segm = br.ReadByte(); _imageSegmentID.Line_No_Image_Segm = Bytes2Number.UInt(br.ReadBytes(2)); break; case 130: //Read header type#130 - Image compensation information header _imageCompInfo.Header_Type = headerType; _imageCompInfo.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2)); _imageCompInfo.Image_Compensation_Information = ASCIIEncoding.ASCII.GetString(br.ReadBytes(_imageCompInfo.Header_Record_Length - 3)); break; case 131: //Read header type#131 - Image observation time _imageObsTime.Header_Type = headerType; _imageObsTime.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2)); _imageObsTime.Image_Observation_Time = ASCIIEncoding.ASCII.GetString(br.ReadBytes(_imageObsTime.Header_Record_Length - 3)); break; case 132: //Read header type#132 - Image quality information _imageQualityInfo.Header_Type = headerType; _imageQualityInfo.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2)); _imageQualityInfo.Image_Quality_Information = ASCIIEncoding.ASCII.GetString(br.ReadBytes(_imageQualityInfo.Header_Record_Length - 3)); break; default: headerRecordLength = Bytes2Number.UInt(br.ReadBytes(2)); br.ReadBytes(headerRecordLength - 3); break; } } //Close file br.Close(); fs.Close(); //Get projection GetProjection(_imageNavigation.Projection_Name); int tNL = _imageStructure.NL * _imageSegmentID.Total_No_Image_Segm; double[] x = new double[XNum]; double[] y = new double[tNL]; double cof = Math.Pow(2, -16); double CFAC_d = _imageNavigation.CFAC * cof; double LFAC_d = _imageNavigation.LFAC * cof; double radius = 6378137.0; int i; for (i = 0; i < XNum; i++) { x[i] = (double)(i + 1 - _imageNavigation.COFF) / CFAC_d * radius / 10; } for (i = 0; i < tNL; i++) { y[i] = (double)(i + 1 - _imageNavigation.LOFF) / LFAC_d * radius / 10; } Dimension xdim = new Dimension(DimensionType.X); xdim.SetValues(x); this.XDimension = xdim; Dimension ydim = new Dimension(DimensionType.Y); ydim.SetValues(y); this.YDimension = ydim; //Set variable list varList = new List <string>(); varList.Add("var"); Variable var = new Variable(); var.Name = "var"; var.SetDimension(ydim); var.SetDimension(xdim); List <Variable> variables = new List <Variable>(); variables.Add(var); this.Variables = variables; }
/// <summary> /// Constructor /// </summary> /// <param name="br">binary reader</param> public GRIB1GridDefineSection(BinaryReader br) { byte[] bytes = br.ReadBytes(3); Length = Bytes2Number.Uint3(bytes[0], bytes[1], bytes[2]); br.BaseStream.Seek(-3, SeekOrigin.Current); bytes = br.ReadBytes(Length); NV = Convert.ToInt32(bytes[3]); P_VorL = Convert.ToInt32(bytes[4]); GridType = Convert.ToInt32(bytes[5]); double checkSum = GridType; if (GridType != 50) //Values same up to resolution { NX = Bytes2Number.Uint2(bytes[6], bytes[7]); if (NX >= 65535) { ThinnedGrid = true; } checkSum = 7 * checkSum + NX; NY = Bytes2Number.Uint2(bytes[8], bytes[9]); checkSum = 7 * checkSum + NY; Lat1 = Bytes2Number.Int3(bytes[10], bytes[11], bytes[12]) / 1000.0; checkSum = 7 * checkSum + Lat1; Lon1 = Bytes2Number.Int3(bytes[13], bytes[14], bytes[15]) / 1000.0; checkSum = 7 * checkSum + Lon1; Resolution = Convert.ToInt32(bytes[16]); } switch (GridType) { case 0: // Standard Lat/Lon grid, no rotation case 4: //Gaussian Lat/Lon grid case 10: // Rotated Lat/Lon grid case 201: //Arkawa semi-staggered E-grid on rotated lat/lon grid case 202: //Arakawa filled E -grid on rotated lat/lon grid Lat2 = Bytes2Number.Int3(bytes[17], bytes[18], bytes[19]) / 1000.0; checkSum = 7 * checkSum + Lat2; Lon2 = Bytes2Number.Int3(bytes[20], bytes[21], bytes[22]) / 1000.0; checkSum = 7 * checkSum + Lon2; //Increments given if (Resolution == 128) { DX = Bytes2Number.Uint2(bytes[23], bytes[24]) / 1000.0; //if (ThinnedGrid) //{ // NX = 73; // DX = 1.25; //} if (GridType == 4) { NP = Bytes2Number.Uint2(bytes[25], bytes[26]); DY = NP / 1000.0; //try for error data } else { DY = Bytes2Number.Uint2(bytes[25], bytes[26]) / 1000.0; } ScanMode = Convert.ToInt32(bytes[27]); if ((ScanMode & 128) != 0) { DX = -DX; } //if ((ScanMode & 64) != 64 && Lat2 < Lat1) // DY = -DY; //if ((ScanMode & 64) != 64 || Lat2 < Lat1) // DY = -DY; if (Lat2 < Lat1) { DY = -DY; } } else { //Calculate increments DX = (Lon2 - Lon1) / (NX - 1); DY = (Lat2 - Lat1) / (NY - 1); } if (DX < 0) { XReverse = true; } if (DY < 0) { YReverse = true; } if (ThinnedGrid) { ThinnedXNums = new int[NY]; ThinnedGridNum = 0; for (int i = 0; i < NY; i++) { ThinnedXNums[i] = Bytes2Number.Int2(bytes[32 + i * 2], bytes[33 + i * 2]); ThinnedGridNum += ThinnedXNums[i]; if (i == 0) { NX = ThinnedXNums[i]; } else { if (NX < ThinnedXNums[i]) { NX = ThinnedXNums[i]; } } } DX = Math.Abs(Lon2 - Lon1) / (NX - 1); } if (GridType == 10) { // Rotated Lat/Lon grid, Lat (octets 33-35), Lon (octets 36-38), rotang (octets 39-42) Latsp = Bytes2Number.Int3(bytes[32], bytes[33], bytes[34]) / 1000.0; Lonsp = Bytes2Number.Int3(bytes[35], bytes[36], bytes[37]) / 1000.0; Rotang = Bytes2Number.Int4(bytes[38], bytes[39], bytes[40], bytes[41]) / 1000.0; } break; case 1: //Mercator projection Lat2 = Bytes2Number.Int3(bytes[17], bytes[18], bytes[19]) / 1000.0; checkSum = 7 * checkSum + Lat2; Lon2 = Bytes2Number.Int3(bytes[20], bytes[21], bytes[22]) / 1000.0; checkSum = 7 * checkSum + Lon2; Latin1 = Bytes2Number.Int3(bytes[23], bytes[24], bytes[25]) / 1000.0; checkSum = 7 * checkSum + Latin1; ScanMode = bytes[27]; DX = Bytes2Number.Int3(bytes[28], bytes[29], bytes[30]); DY = Bytes2Number.Int3(bytes[31], bytes[32], bytes[33]); break; case 3: //Lambert projection Lov = Bytes2Number.Int3(bytes[17], bytes[18], bytes[19]) / 1000.0; checkSum = 7 * checkSum + Lov; DX = Bytes2Number.Int3(bytes[20], bytes[21], bytes[22]); DY = Bytes2Number.Int3(bytes[23], bytes[24], bytes[25]); Proj_Center = bytes[26]; ScanMode = bytes[27]; Latin1 = Bytes2Number.Int3(bytes[28], bytes[29], bytes[30]) / 1000.0; checkSum = 7 * checkSum + Latin1; Latin2 = Bytes2Number.Int3(bytes[31], bytes[32], bytes[33]) / 1000.0; checkSum = 7 * checkSum + Latin2; Latsp = Bytes2Number.Int3(bytes[34], bytes[35], bytes[36]) / 1000.0; checkSum = 7 * checkSum + Latsp; Lonsp = Bytes2Number.Int3(bytes[37], bytes[38], bytes[39]) / 1000.0; checkSum = 7 * checkSum + Lonsp; break; case 5: //Polar stereographic projection case 87: Lov = Bytes2Number.Int3(bytes[17], bytes[18], bytes[19]) / 1000.0; checkSum = 7 * checkSum + Lov; if (GridType == 87) { Lon2 = Bytes2Number.Int3(bytes[20], bytes[21], bytes[22]) / 1000.0; checkSum = 7 * checkSum + Lon2; } DX = Bytes2Number.Int3(bytes[20], bytes[21], bytes[22]); DY = Bytes2Number.Int3(bytes[23], bytes[24], bytes[25]); Proj_Center = bytes[26]; ScanMode = bytes[27]; break; default: break; } // This switch uses the grid_type to define how to handle the // southpole information. switch (GridType) { case 0: // Standard Lat/Lon grid, no rotation Latsp = -90.0; Lonsp = 0.0; Rotang = 0.0; break; default: // No knowledge yet // NEED to fix this later, if supporting other grid types Latsp = Double.NaN; Lonsp = Double.NaN; Rotang = Double.NaN; break; } }