/// <summary> /// Read grid data - LonLat /// </summary> /// <param name="timeIdx">Time index</param> /// <param name="varIdx">Variable index</param> /// <param name="levelIdx">Level index</param> /// <returns>Grid data</returns> public GridData GetGridData_LonLat(int timeIdx, int varIdx, int levelIdx) { FileStream fs = new FileStream(this.FileName, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); //Read byte data br.BaseStream.Seek(_primaryHeader.Total_Header_Length, SeekOrigin.Begin); int length = (int)(br.BaseStream.Length - br.BaseStream.Position); byte[] imageBytes = br.ReadBytes(length); br.Close(); fs.Close(); //Get grid data int i, j; int tNL = _imageStructure.NL * _imageSegmentID.Total_No_Image_Segm; GridData gridData = new GridData(); double[] x = new double[XNum]; double[] y = new double[YNum]; double cof = Math.Pow(2, -16); double CFAC_d = _imageNavigation.CFAC * cof; double LFAC_d = _imageNavigation.LFAC * cof; double radius = 6378137.0; for (i = 0; i < XNum; i++) { x[i] = (double)(i + 1 - _imageNavigation.COFF) / CFAC_d * radius / 10; } int stNL = tNL - _imageSegmentID.Line_No_Image_Segm + 1 - YNum; for (i = 0; i < YNum; i++) { y[i] = (double)(stNL + i - _imageNavigation.LOFF) / LFAC_d * radius / 10; } gridData.X = x; gridData.Y = y; double[,] gData = new double[YNum, XNum]; for (i = 0; i < YNum; i++) { for (j = 0; j < XNum; j++) { gData[YNum - i - 1, j] = Bytes2Number.Uint2(imageBytes[i * XNum * 2 + j * 2], imageBytes[1 * XNum * 2 + j * 2 + 1]); } } gridData.Data = gData; return(gridData); }
/// <summary> /// Constructor /// </summary> /// <param name="br">binary reader</param> public GRIB1ProductDefineSection(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); TableVersion = Convert.ToInt32(bytes[3]); CenterID = Convert.ToInt32(bytes[4]); TypeGenProcess = Convert.ToInt32(bytes[5]); GridID = Convert.ToInt32(bytes[6]); int ifExists = Convert.ToInt32(bytes[7]); GDSExist = (ifExists & 128) == 128; BMSExist = (ifExists & 64) == 64; ParameterIndicator = Convert.ToInt32(bytes[8]); Parameter = GRIBParameterTable.GetDefaultParameter(ParameterIndicator); LevelType = Convert.ToInt32(bytes[9]); LevelValue = Bytes2Number.Uint2(bytes[10], bytes[11]); int year = Convert.ToInt32(bytes[12]); int month = Convert.ToInt32(bytes[13]); int day = Convert.ToInt32(bytes[14]); int hour = Convert.ToInt32(bytes[15]); int minute = Convert.ToInt32(bytes[16]); ForecastTimeUnit = Convert.ToInt32(bytes[17]); P1 = Convert.ToInt32(bytes[18]); P2 = Convert.ToInt32(bytes[19]); TimeRangeIndicator = Convert.ToInt32(bytes[20]); AveInclude = Bytes2Number.Int2(bytes[21], bytes[22]); NumMissing = Convert.ToInt32(bytes[23]); InitialCentral = Convert.ToInt32(bytes[24]); BaseTime = new DateTime((InitialCentral - 1) * 100 + year, month, day, hour, minute, 0); SubCenterID = Convert.ToInt32(bytes[25]); DecimalScale = Bytes2Number.Int2(bytes[26], bytes[27]); //octets 27-28 }
/// <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> /// 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; } }