public Grib1BitMapSection(FileStream fs) { long position = fs.Position; int[] bitmask = new int[] { 128, 64, 32, 16, 8, 4, 2, 1 }; // octet 1-3 (length of section) _sectionLength = GribNumberHelper.Uint3(fs); // octet 4 unused bits int unused = fs.ReadByte(); // octets 5-6 int bm = GribNumberHelper.Int2(fs); sbyte[] data = new sbyte[_sectionLength - 6]; StreamReadHelper.ReadInput(fs, data, 0, data.Length); // 创建新位图, octet 4包含末尾使用过的位数 _bitmap = new bool[(_sectionLength - 6) * 8 - unused]; // 填充位图 for (int i = 0; i < _bitmap.Length; i++) { _bitmap[i] = (data[i / 8] & bitmask[i % 8]) != 0; } fs.Seek(position + _sectionLength, SeekOrigin.Begin); }
public GRIB2DataRepresentationSection(FileStream fs) { _sectionHeader = new GRIB2SectionHeader(fs); _dataPoints = GribNumberHelper.Int4(fs); _dataTemplate = (int)GribNumberHelper.Uint2(fs); SetOtherAttributeByDataTemplateNo(fs); }
/// <summary> /// 构造函数 /// </summary> /// <param name="fs">文件读取参数对象</param> public Grib1GridDefinitionSection(FileStream fs) { _position = fs.Position; int reserved; // 用于读取空白 _sectionLength = GribNumberHelper.Uint3(fs); // GDS的长度 if (_sectionLength == 0) { // PDS与GDS间额外的一个字节 fs.Seek(-2, SeekOrigin.Current); _sectionLength = (int)GribNumberHelper.Uint3(fs); } int NV = fs.ReadByte(); // PL the location (octet number) of the list of numbers of points in each row _vorL = fs.ReadByte(); _gridType = fs.ReadByte(); // grid类型 _gridName = getGridName(_gridType); SetOtherAttribute(fs); //没有获取纬度方向上的分辨率 //如果为高斯等经纬度的话,无法从数据中读取纬度方向上的分辨率 if (_dy == 0) { _dy = _ny / Math.Abs(_latEndPoint - _latFirstPoint); } fs.Seek(_position + _sectionLength, SeekOrigin.Begin); }
private int _discipline; //学科 public GribIndicatorSection(FileStream fs) { long mark = fs.Position; //if Grib edition 1, get bytes for the gribLength fs.Seek(3, SeekOrigin.Current); // edition of GRIB specification _gribEdition = fs.ReadByte(); if (_gribEdition == 1) { // length of GRIB record // Reset to beginning, then read 3 bytes fs.Position = mark; _gribLength = (long)GribNumberHelper.Uint3(fs); // Skip next byte, edition already read fs.ReadByte(); _sectionLength = 8; } else if (_gribEdition == 2) { fs.Position = mark + 2; // length of GRIB record _discipline = fs.ReadByte(); fs.ReadByte(); _gribLength = GribNumberHelper.Int8(fs); _sectionLength = 16; } else { throw new NotSupportedException("GRIB edition " + _gribEdition + " is not yet supported"); } }
public GRIB2IdentificationSection(FileStream fs) { //段长度,段号 long position = fs.Position; _sectionHeader = new GRIB2SectionHeader(fs); if (_sectionHeader.SectionNo != 1) { return; } _centerId = GribNumberHelper.Int2(fs); _subcenterId = GribNumberHelper.Int2(fs); _masterTableVersionNo = fs.ReadByte(); _locationTableVersion = fs.ReadByte(); _significanceOfRT = fs.ReadByte(); int year = GribNumberHelper.Int2(fs); int month = fs.ReadByte(); int day = fs.ReadByte(); int hour = fs.ReadByte(); int minute = fs.ReadByte(); int second = fs.ReadByte(); _referenceTime = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc); _productStatus = fs.ReadByte(); _productType = fs.ReadByte(); fs.Seek(position + _sectionHeader.SectionLength, SeekOrigin.Begin); }
private int _nb; //Number of contributing spectral bands(Template 30) public GRIB2ProductDefinitionSection(FileStream fs) { _sectionHeader = new GRIB2SectionHeader(fs); _coordinates = GribNumberHelper.Int2(fs); _productDefinitionTemplateNo = GribNumberHelper.Int2(fs); SetOtherAttributeByProductDefinition(fs); }
private void SetTimeRange(int p1, int p2) { switch (_timeRangeValue) { case 0: _timeRange = "product valid at RT + P1"; _forecastTime = p1; break; case 1: _timeRange = "product valid for RT, P1=0"; _forecastTime = 0; break; case 2: _timeRange = "product valid from (RT + P1) to (RT + P2)"; _forecastTime = p2; break; case 3: _timeRange = "product is an average between (RT + P1) to (RT + P2)"; _forecastTime = p2; break; case 4: _timeRange = "product is an accumulation between (RT + P1) to (RT + P2)"; _forecastTime = p2; break; case 5: _timeRange = "product is the difference (RT + P2) - (RT + P1)"; _forecastTime = p2; break; case 6: _timeRange = "product is an average from (RT - P1) to (RT - P2)"; _forecastTime = -p2; break; case 7: _timeRange = "product is an average from (RT - P1) to (RT + P2)"; _forecastTime = p2; break; case 10: _timeRange = "product valid at RT + P1"; // p1 really consists of 2 bytes p1 and p2 _forecastTime = GribNumberHelper.Int2(p1, p2); break; case 51: _timeRange = "mean value from RT to (RT + P2)"; _forecastTime = p2; break; default: break; } }
private void SetOtherAttributeByDataTemplateNo(FileStream fs) { _referenceValue = GribNumberHelper.IEEEfloat4(fs); _binaryScaleFactor = GribNumberHelper.Int2(fs); _decimalScaleFactor = GribNumberHelper.Int2(fs); _numberOfBits = fs.ReadByte(); _originalType = fs.ReadByte(); switch (_dataTemplate) { case 0: //0 - Grid point data - simple packing case 1: //1 - Matrix values - simple packing { break; } case 2: case 3: { _splittingMethod = fs.ReadByte(); // octet 23 _missingValueManagement = fs.ReadByte(); // octet 24 - 27 _primaryMissingValue = GribNumberHelper.IEEEfloat4(fs); // octet 28 - 31 _secondaryMissingValue = GribNumberHelper.IEEEfloat4(fs); // octet 32 - 35 _numberOfGroups = GribNumberHelper.Int4(fs); // octet 36 _referenceGroupWidths = fs.ReadByte(); // octet 37 _bitsGroupWidths = fs.ReadByte(); // according to documentation subtract referenceGroupWidths _bitsGroupWidths = _bitsGroupWidths - _referenceGroupWidths; // octet 38 - 41 _referenceGroupLength = GribNumberHelper.Int4(fs); // octet 42 _lengthIncrement = fs.ReadByte(); // octet 43 - 46 _lengthLastGroup = GribNumberHelper.Int4(fs); // octet 47 _bitsScaledGroupLength = fs.ReadByte(); if (_dataTemplate == 3) { // case 3 // complex packing & spatial differencing _orderSpatial = fs.ReadByte(); _descriptorSpatial = fs.ReadByte(); } break; } case 4: case 4000: { _compressionMethod = fs.ReadByte(); _compressionRatio = fs.ReadByte(); break; } } }
/// <summary> /// 构造函数 /// </summary> /// <param name="raf">with PDS content</param> public Grib1ProductDefinitionSection(FileStream fs) { // octets 1-3 PDS length _sectionLength = (int)GribNumberHelper.Uint3(fs); // Paramter table octet 4 _tableVersion = fs.ReadByte(); // Center octet 5 _centerId = fs.ReadByte(); // octet 6 Generating Process - See Table A _processId = fs.ReadByte(); // octet 7 (id of grid type) - not supported yet _gridId = fs.ReadByte(); //octet 8 (flag for presence of GDS and BMS) SetGdsBmsExits(fs.ReadByte()); // octet 9 (parameter and unit) _parameterNumber = fs.ReadByte(); // octets 10-12 (level) int levelType = fs.ReadByte(); int levelValue1 = fs.ReadByte(); int levelValue2 = fs.ReadByte(); _level = new GribPDSLevel(levelType, levelValue1, levelValue2); // octets 13-17 (base time for reference time)依次为year/month/day/hour/minute byte[] timeBytes = new Byte[5]; fs.Read(timeBytes, 0, 5); // octet 18 Forecast time unit _timeUnit = fs.ReadByte(); // octet 19 & 20 used to create Forecast time int p1 = fs.ReadByte(); int p2 = fs.ReadByte(); // octet 21 (time range indicator) _timeRangeValue = fs.ReadByte(); // forecast time is always at the end of the range SetTimeRange(p1, p2); // octet 22 & 23 int avgInclude = GribNumberHelper.Int2(fs); // octet 24 int avgMissing = fs.ReadByte(); // octet 25 int century = fs.ReadByte() - 1; // octet 26, sub center _subcenterId = fs.ReadByte(); // octets 27-28 (decimal scale factor) _decscale = GribNumberHelper.Int2(fs); SetReferenceTime(timeBytes, century); _parameterTable = GribPDSParamTable.GetParameterTable(_centerId, _subcenterId, _tableVersion); _parameter = _parameterTable.GetParameter(_parameterNumber); }
public GRIB2DataRepresentationSection(FileStream fs) { long position = fs.Position; _sectionHeader = new GRIB2SectionHeader(fs); _dataPoints = GribNumberHelper.Int4(fs); _dataTemplate = (int)GribNumberHelper.Uint2(fs); SetOtherAttributeByDataTemplateNo(fs); fs.Seek(position + _sectionHeader.SectionLength, SeekOrigin.Begin); }
private int _nb; //Number of contributing spectral bands(Template 30) public GRIB2ProductDefinitionSection(FileStream fs) { long position = fs.Position; _sectionHeader = new GRIB2SectionHeader(fs); _coordinates = GribNumberHelper.Int2(fs); _productDefinitionTemplateNo = GribNumberHelper.Int2(fs); SetOtherAttributeByProductDefinition(fs); fs.Seek(position + _sectionHeader.SectionLength, SeekOrigin.Begin); }
private float _dstart; //Dstart ― offset from origin to inner bound public GRIB2GridDefinitionSection(FileStream fs) { _sectionHeader = new GRIB2SectionHeader(fs); _source = fs.ReadByte(); _pointsNumber = GribNumberHelper.Int4(fs); _olon = fs.ReadByte(); _iolon = fs.ReadByte(); _gridTemplateNo = GribNumberHelper.Int2(fs); _gridName = GetGridNameByGridNo(); SetAttributeByGridTemplateNo(fs); }
private void AdjustAttributes(byte[] array) { if (this.Resolution == 128) { _dx = (double)GribNumberHelper.Uint2(array[23], array[24]) / 1000.0; if (this.GridType == 4) { _np = GribNumberHelper.Uint2(array[25], array[26]); _dy = (double)_np / 1000.0; } else { _dy = (double)GribNumberHelper.Uint2(array[25], array[26]) / 1000.0; } _scanMode = Convert.ToInt32(array[27]); } else { _dx = (_lonEndPoint - _lonFirstPoint) / (double)(_nx - 1); _dy = (_latEndPoint - _latFirstPoint) / (double)(_ny - 1); } if ((_scanMode & 128) != 0) { _xReverse = true; } if (_latEndPoint < _latFirstPoint) { _yReverse = true; } if (_thinnedGrid) { _thinnedXNums = new int[_ny]; _thinnedGridNum = 0; for (int i = 0; i < _ny; i++) { _thinnedXNums[i] = GribNumberHelper.Int2(array[32 + i * 2], array[33 + i * 2]); _thinnedGridNum += this.ThinnedXNums[i]; if (i == 0) { _nx = this.ThinnedXNums[i]; } else { if (_nx < this.ThinnedXNums[i]) { //取格点数最多那行的格点数为宽 _nx = this.ThinnedXNums[i]; } } } _dx = Math.Abs(_lonEndPoint - _lonFirstPoint) / (double)(_nx - 1); } }
private float _dstart; //Dstart ― offset from origin to inner bound public GRIB2GridDefinitionSection(FileStream fs) { long position = fs.Position; _sectionHeader = new GRIB2SectionHeader(fs); _source = fs.ReadByte(); _pointsNumber = GribNumberHelper.Int4(fs); _olon = fs.ReadByte(); _iolon = fs.ReadByte(); _gridTemplateNo = GribNumberHelper.Int2(fs); _gridName = GetGridNameByGridNo(); SetAttributeByGridTemplateNo(fs); fs.Seek(position + _sectionHeader.SectionLength, SeekOrigin.Begin); }
public GRIB2IndicatorSection(FileStream fs) { //if Grib edition 1, get bytes for the gribLength int[] data = new int[3]; for (int i = 0; i < 3; i++) { data[i] = fs.ReadByte(); } _gribEdition = fs.ReadByte(); if (_gribEdition == 2) { _discipline = data[2]; _gribLength = GribNumberHelper.Int8(fs); _sectionLength = 16; } }
/// <summary> /// 构造函数 /// </summary> /// <param name="fs">文件读取参数对象</param> public Grib1GridDefinitionSection(FileStream fs) { int reserved; // 用于读取空白 _sectionLength = GribNumberHelper.Uint3(fs); // GDS的长度 if (_sectionLength == 0) { // PDS与GDS间额外的一个字节 fs.Seek(-2, SeekOrigin.Current); _sectionLength = (int)GribNumberHelper.Uint3(fs); } int NV = fs.ReadByte(); // PL the location (octet number) of the list of numbers of points in each row _vorL = fs.ReadByte(); _gridType = fs.ReadByte(); // grid类型 _gridName = getGridName(_gridType); SetOtherAttribute(fs); }
private void ReadToDataProvider() { if (string.IsNullOrEmpty(_fileName) || !File.Exists(_fileName)) { return; } long startOffset = -1; GribIndicatorSection iSection; Grib1ProductDefinitionSection pds; Grib1GridDefinitionSection gds = null; _fs = new FileStream(_fileName, FileMode.Open, FileAccess.Read); if (SeekHeader(_fs, _fs.Length, out startOffset)) { iSection = new GribIndicatorSection(_fs); long EOR = _fs.Position + iSection.GribLength - iSection.SectionLength; pds = new Grib1ProductDefinitionSection(_fs); if (pds.GdsExists()) { gds = new Grib1GridDefinitionSection(_fs); _scanMode = gds.ScanMode; } if (pds.Center == 98) { int length = (int)GribNumberHelper.Uint3(_fs); if ((length + _fs.Position) < EOR) { _dataOffset = _fs.Position - 3; } else { _dataOffset = _fs.Position - 2; } } else { _dataOffset = _fs.Position; } SetAttributes(gds, pds); _edition = iSection.GribEdition; } }
public GRIB2SectionHeader(FileStream fs) { _sectionLength = GribNumberHelper.Int4(fs); _sectionNo = fs.ReadByte(); }
private void ReadToDataProvider() { if (string.IsNullOrEmpty(_fileName) || !File.Exists(_fileName)) { return; } long gdsOffset = 0; // GDS offset from start of file bool startAtHeader = true; // otherwise skip to GDS bool processGDS = true; FileStream _fs = new FileStream(_fileName, FileMode.Open, FileAccess.Read); GRIB2IndicatorSection iSection = null; GRIB2IdentificationSection idSection = null; GRIB2LocalUseSection lus = null; GRIB2GridDefinitionSection gds = null; while (_fs.Position < _fs.Length) { if (startAtHeader) { // begining of record if (!SeekHeader(_fs, _fs.Length)) { goto setAttributes; } // Read Section 0 Indicator Section iSection = new GRIB2IndicatorSection(_fs); // section 0 _discipline = iSection.Displine; // Read other Sections idSection = new GRIB2IdentificationSection(_fs); // Section 1 _referenceTime = idSection.ReferenceTime; } // end startAtHeader if (processGDS) { // check for Local Use Section 2 lus = new GRIB2LocalUseSection(_fs); // obtain GDS offset in the file for this record gdsOffset = _fs.Position; // Section 3 gds = new GRIB2GridDefinitionSection(_fs); } // obtain PDS offset in the file for this record long pdsOffset = _fs.Position; IGRIB2ProductDefinitionSection pds = new GRIB2ProductDefinitionSection(_fs); // Section 4 IGRIB2DataRepresentationSection drs = new GRIB2DataRepresentationSection(_fs); // Section 5 IGribBitMapSection bms = new GRIB2BitMapSection(_fs, gds.PointsNumber); // Section 6 long dataOffset = _fs.Position + 5; GRIB2DataSection ds = new GRIB2DataSection(_fs, dataOffset); //Section 7 GRIB2Record record = new GRIB2Record(iSection.Displine, gds, pds, drs, bms, ds, gdsOffset, pdsOffset, dataOffset); _records.Add(record); _parameterList.Add(record.ParameterName); if (_fs.Position > _fs.Length) { _fs.Seek(0, System.IO.SeekOrigin.Begin); goto setAttributes; } int ending = GribNumberHelper.Int4(_fs); if (ending == 926365495) { // record ending string 7777 as a number startAtHeader = true; processGDS = true; } else { //_fs.Seek(4, SeekOrigin.Current); int section = _fs.ReadByte(); // check if GDS or PDS section, 3 or 4 //reset back to begining of section _fs.Seek(_fs.Position - 5, System.IO.SeekOrigin.Begin); if (section == 3) { startAtHeader = false; processGDS = true; } else if (section == 4) { startAtHeader = false; processGDS = false; } else { GribEndSection es = new GribEndSection(_fs); if (es.IsEndFound) { startAtHeader = true; processGDS = true; } else { goto setAttributes; } } } } setAttributes: SetAttribute(gds); }
public float[] Read(int xoffset, int yoffset, int width, int height) { try { if (_fileStream == null) { return(null); } if (width > _width | height > _height) { return(null); } if (_isBmsExist) { throw new NotSupportedException("不支持BitMapSection存在情况下的数据读取"); } _fileStream.Seek(_dataoffset, SeekOrigin.Begin); int sectionBytesLength = GribNumberHelper.Uint3(_fileStream); //整个区段的字节长度 int flagsAndUnusedbits = _fileStream.ReadByte(); if ((flagsAndUnusedbits & 192) != 0) //&1100,取前两位,仅支持是flag[0],flag[1]都是0的情况 { throw new NotSupportedException("BDS: (octet 4, 1st half) not grid point data and simple packing "); } int unusedbits = flagsAndUnusedbits & 15; //&1111,取后四位的数值 _binScale = GribNumberHelper.Int2(_fileStream); _refValue = ComputeReferenceValue(_fileStream); //GribNumberHelper.Float4(_fileStream); _numBits = _fileStream.ReadByte(); if (_numBits == 0) { _isConstant = true; return(null); } float refRenamed = (float)(Math.Pow(10.0, -_decscale) * _refValue); float scale = (float)(Math.Pow(10.0, -_decscale) * Math.Pow(2.0, _binScale)); //long firstOffset = _fileStream.Position; //points = new GRIB_Point[((dataLength - 11) * 8 - unusedbits) / numbits]; //当前情况下,整个数据区域的大小 var bufRetDatas = new float[height * width]; var allDataBytesLength = (int)Math.Ceiling(((sectionBytesLength - 11) * 8 - unusedbits) / 8d); //当前情况下,整个二进制数据所占用的字节数 int realDataLength = width * height * _numBits / 8 + 1; var bufferBytes = new byte[allDataBytesLength]; //new byte[Math.Max(allDataBytesLength, realDataLength)]; // _fileStream.Read(bufferBytes, 0, allDataBytesLength); uint val; using (BitStream bs = new BitStream(new MemoryStream(bufferBytes))) { bs.Position = 0; if (_thinnedGrid) { return(ReadDataWithThinnedValue(sectionBytesLength, unusedbits, refRenamed, scale, width, height, xoffset, yoffset, bs)); } for (int j = yoffset; j < yoffset + height; j++) //缓存数据,上下调整前的第j行 { if (_firstlat < _lastlat) //记录方向为从南到北 { bs.Position = ((_height - j - 1) * _width + xoffset) * _numBits; // +bitOffset; for (int i = xoffset; i < xoffset + width; i++) { bs.Read(out val, 0, _numBits); if (_firstlon == 0 && _lastlon > 300) //最大经度超过180在地图上将实际在西半球,经度为大于-180,但日本C数据最大为200°,不再分区域显示,故将界限定为300,影响X区域和Y区域的数据存储 { int halfLon = (int)((_lastlon - _firstlon) / _xresolution); if (i < halfLon) { bufRetDatas[halfLon + i + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6); } else { bufRetDatas[i - halfLon + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6); } } else { bufRetDatas[i + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6); } } } else { if (j == yoffset) { //_fileStream.Seek((_width * yoffset + xoffset) * _numBits / 8, SeekOrigin.Current); //起始位置字节流向后偏移的位置,(_width*yoffset+xoffset)表示偏移的点个数 //numbits表示每个点的数值所占的位数,除以8表示每个点占的字节数,seek(函数以字节为单位) bs.Position += (_width * yoffset + xoffset) * _numBits; } else { //_fileStream.Seek((_width - width) * _numBits / 8, SeekOrigin.Current); bs.Position += (_width - width) * _numBits; } for (int i = xoffset; i < xoffset + width; i++) { bs.Read(out val, 0, _numBits); if (_firstlon == 0 && _lastlon > 300) { int halfLon = (int)((_lastlon - 180 + _xresolution) / _xresolution); if (i < halfLon) { bufRetDatas[halfLon + i + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6); } else { bufRetDatas[i - halfLon + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6); } } else { bufRetDatas[i + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6); } } } } } ScanModeApplier.ApplyScanMode(_scanMode, width, ref bufRetDatas); //if (_thinnedGrid) //{ // return ReadDataWithThinnedValue(bufRetDatas, width, height); //} return(bufRetDatas); } finally { _fileStream.Seek(0, SeekOrigin.Begin); } }
private void SetOtherAttributeByProductDefinition(FileStream fs) { // octet 10 _parameterCategory = fs.ReadByte(); // octet 11 _parameterNumber = fs.ReadByte(); switch (_productDefinitionTemplateNo) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: { // octet 12 _typeGenProcess = fs.ReadByte(); // octet 13 _backGenProcess = fs.ReadByte(); // octet 14 _analysisGenProcess = fs.ReadByte(); // octet 15-16 _hoursAfter = GribNumberHelper.Int2(fs); // octet 17 _minutesAfter = fs.ReadByte(); // octet 18 _timeRangeUnit = fs.ReadByte(); // octet 19-22 _forecastTime = GribNumberHelper.Int4(fs); // octet 23 _typeFirstFixedSurface = fs.ReadByte(); // octet 24 int scaleFirstFixedSurface = fs.ReadByte(); // octet 25-28 int valueFirstFixedSurface = GribNumberHelper.Int4(fs); _firstFixedSurfaceValue = (float)((scaleFirstFixedSurface == 0 || valueFirstFixedSurface == 0) ? valueFirstFixedSurface : System.Math.Pow(valueFirstFixedSurface, -scaleFirstFixedSurface)); // octet 29 _typeSecondFixedSurface = fs.ReadByte(); // octet 30 int scaleSecondFixedSurface = fs.ReadByte(); // octet 31-34 int valueSecondFixedSurface = GribNumberHelper.Int4(fs); _secondFixedSurfaceValue = (float)((scaleSecondFixedSurface == 0 || valueSecondFixedSurface == 0) ? valueSecondFixedSurface : System.Math.Pow(valueSecondFixedSurface, -scaleSecondFixedSurface)); if (_productDefinitionTemplateNo == 8) { // 35-41 bytes int year = GribNumberHelper.Int2(fs); int month = (fs.ReadByte()) - 1; int day = fs.ReadByte(); int hour = fs.ReadByte(); int minute = fs.ReadByte(); int second = fs.ReadByte(); // 42 - 46 int timeRanges = fs.ReadByte(); int missingDataValues = GribNumberHelper.Int4(fs); // 47 - 48 int outmostTimeRange = fs.ReadByte(); int missing = fs.ReadByte(); // 49 - 53 int statisticalProcess = fs.ReadByte(); int timeIncrement = GribNumberHelper.Int4(fs); // 54 - 58 int indicatorTR = fs.ReadByte(); int lengthTR = GribNumberHelper.Int4(fs); } break; } case 20: { _typeGenProcess = fs.ReadByte(); // octet 13 _backGenProcess = fs.ReadByte(); // octet 14 _analysisGenProcess = fs.ReadByte(); // octet 15-16 _hoursAfter = GribNumberHelper.Int2(fs); // octet 17 _minutesAfter = fs.ReadByte(); // octet 18 _timeRangeUnit = fs.ReadByte(); // octet 19-22 _forecastTime = GribNumberHelper.Int4(fs); break; } case 30: { // octet 12 _typeGenProcess = fs.ReadByte(); // octet 13 _backGenProcess = fs.ReadByte(); // octet 14 _nb = fs.ReadByte(); fs.Seek(10 * _nb, SeekOrigin.Current); break; } case 254: { break; } } }
private void SetAttributeByGridTemplateNo(FileStream fs) { int scaleFactorRadius, scaleDvalueRadius, scaleFactorMajor, scaleDvalueMajor, scaleFactorMinor, scaleDvalueMinor; float ratio; if ((_gridTemplateNo >= 50 && _gridTemplateNo <= 53) || _gridTemplateNo == 100 || _gridTemplateNo == 120) { if (_gridTemplateNo >= 50 && _gridTemplateNo <= 53) { _j = GribNumberHelper.IEEEfloat4(fs); _k = GribNumberHelper.IEEEfloat4(fs); _m = GribNumberHelper.IEEEfloat4(fs); _method = fs.ReadByte(); _mode = fs.ReadByte(); if (_gridTemplateNo == 51) { _spLat = GribNumberHelper.Int4(fs) * TenToNegSix; _spLon = GribNumberHelper.Int4(fs) * TenToNegSix; _rotationAngle = GribNumberHelper.IEEEfloat4(fs); } else if (_gridTemplateNo == 52) { _poleLat = GribNumberHelper.Int4(fs) * TenToNegSix; _poleLon = GribNumberHelper.Int4(fs) * TenToNegSix; _factor = GribNumberHelper.Int4(fs); } else if (_gridTemplateNo == 53) { _spLat = GribNumberHelper.Int4(fs) * TenToNegSix; _spLon = GribNumberHelper.Int4(fs) * TenToNegSix; _rotationAngle = GribNumberHelper.IEEEfloat4(fs); _poleLat = GribNumberHelper.Int4(fs) * TenToNegSix; _poleLon = GribNumberHelper.Int4(fs) * TenToNegSix; _factor = GribNumberHelper.Int4(fs); } } else if (_gridTemplateNo == 100) { _n2 = fs.ReadByte(); _n3 = fs.ReadByte(); _ni = GribNumberHelper.Int2(fs); _nd = fs.ReadByte(); _poleLat = GribNumberHelper.Int4(fs) * TenToNegSix; _poleLon = GribNumberHelper.Int4(fs) * TenToNegSix; _lonofcenter = GribNumberHelper.Int4(fs); _position = fs.ReadByte(); _order = fs.ReadByte(); _scanMode = fs.ReadByte(); _nt = GribNumberHelper.Int4(fs); } else { _nb = GribNumberHelper.Int4(fs); _nr = GribNumberHelper.Int4(fs); _latFirstPoint = GribNumberHelper.Int4(fs); _lonFirstPoint = GribNumberHelper.Int4(fs); _dx = GribNumberHelper.Int4(fs); _dstart = GribNumberHelper.IEEEfloat4(fs); _scanMode = fs.ReadByte(); } } else { _shape = fs.ReadByte(); scaleFactorRadius = fs.ReadByte(); scaleDvalueRadius = GribNumberHelper.Int4(fs); scaleFactorMajor = fs.ReadByte(); scaleDvalueMajor = GribNumberHelper.Int4(fs); scaleFactorMinor = fs.ReadByte(); scaleDvalueMinor = GribNumberHelper.Int4(fs); _nx = GribNumberHelper.Int4(fs); _ny = GribNumberHelper.Int4(fs); switch (_gridTemplateNo) { // Latitude/Longitude Grid case 0: case 1: case 2: case 3: { _angle = GribNumberHelper.Int4(fs); _subDivisionsAngle = GribNumberHelper.Int4(fs); if (_angle == 0) { ratio = TenToNegSix; } else { ratio = _angle / _subDivisionsAngle; } _latFirstPoint = (float)(GribNumberHelper.Int4(fs) * ratio); _lonFirstPoint = (float)(GribNumberHelper.Int4(fs) * ratio); _resolutionFlag = fs.ReadByte(); _latEndPoint = (float)(GribNumberHelper.Int4(fs) * ratio); _lonEndPoint = (float)(GribNumberHelper.Int4(fs) * ratio); _dx = (float)(GribNumberHelper.Int4(fs) * ratio); _dy = (float)(GribNumberHelper.Int4(fs) * ratio); _scanMode = fs.ReadByte(); // 1, 2, and 3 needs checked if (_gridTemplateNo == 1) { //Rotated Latitude/longitude _spLat = GribNumberHelper.Int4(fs) * TenToNegSix; _spLon = GribNumberHelper.Int4(fs) * TenToNegSix; _rotationAngle = GribNumberHelper.IEEEfloat4(fs); } else if (_gridTemplateNo == 2) { //Stretched Latitude/longitude _poleLat = GribNumberHelper.Int4(fs) * TenToNegSix; _poleLon = GribNumberHelper.Int4(fs) * TenToNegSix; _factor = GribNumberHelper.Int4(fs); } else if (_gridTemplateNo == 3) { //Stretched and Rotated Latitude/longitude _spLat = GribNumberHelper.Int4(fs) * TenToNegSix; _spLon = GribNumberHelper.Int4(fs) * TenToNegSix; _rotationAngle = GribNumberHelper.IEEEfloat4(fs); _poleLat = GribNumberHelper.Int4(fs) * TenToNegSix; _poleLon = GribNumberHelper.Int4(fs) * TenToNegSix; _factor = GribNumberHelper.Int4(fs); } break; } case 10: // Mercator { _latFirstPoint = GribNumberHelper.Int4(fs) * TenToNegSix; _lonFirstPoint = GribNumberHelper.Int4(fs) * TenToNegSix; _resolutionFlag = fs.ReadByte(); _latD = GribNumberHelper.Int4(fs) * TenToNegSix; _latEndPoint = GribNumberHelper.Int4(fs) * TenToNegSix; _lonEndPoint = GribNumberHelper.Int4(fs) * TenToNegSix; _scanMode = fs.ReadByte(); _angle = GribNumberHelper.Int4(fs); _dx = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _dy = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); break; } case 20: // Polar stereographic projection { _latFirstPoint = GribNumberHelper.Int4(fs) * TenToNegSix; _lonFirstPoint = GribNumberHelper.Int4(fs) * TenToNegSix; _resolutionFlag = fs.ReadByte(); _latD = GribNumberHelper.Int4(fs) * TenToNegSix; _lov = GribNumberHelper.Int4(fs) * TenToNegSix; _dx = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _dy = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _projectionCenter = fs.ReadByte(); _scanMode = fs.ReadByte(); break; } case 30: // Lambert Conformal { _latFirstPoint = (float)(GribNumberHelper.Int4(fs) * TenToNegSix); _lonFirstPoint = (float)(GribNumberHelper.Int4(fs) * TenToNegSix); _resolutionFlag = fs.ReadByte(); _latD = (float)(GribNumberHelper.Int4(fs) * TenToNegSix); _lov = (float)(GribNumberHelper.Int4(fs) * TenToNegSix); _dx = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _dy = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _projectionCenter = fs.ReadByte(); _scanMode = fs.ReadByte(); _latin1 = (float)(GribNumberHelper.Int4(fs) * TenToNegSix); _latin2 = (float)(GribNumberHelper.Int4(fs) * TenToNegSix); _spLat = (float)(GribNumberHelper.Int4(fs) * TenToNegSix); _spLon = (float)(GribNumberHelper.Int4(fs) * TenToNegSix); break; } case 31: // Albers Equal Area { _latFirstPoint = GribNumberHelper.Int4(fs) * TenToNegSix; _lonFirstPoint = GribNumberHelper.Int4(fs) * TenToNegSix; _resolutionFlag = fs.ReadByte(); _latD = GribNumberHelper.Int4(fs) * TenToNegSix; _lov = GribNumberHelper.Int4(fs) * TenToNegSix; _dx = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _dy = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _projectionCenter = fs.ReadByte(); _scanMode = fs.ReadByte(); _latin1 = GribNumberHelper.Int4(fs) * TenToNegSix; _latin2 = GribNumberHelper.Int4(fs) * TenToNegSix; _spLat = GribNumberHelper.Int4(fs) * TenToNegSix; _spLon = GribNumberHelper.Int4(fs) * TenToNegSix; break; } case 40: case 41: case 42: case 43: // Gaussian latitude/longitude { _angle = GribNumberHelper.Int4(fs); _subDivisionsAngle = GribNumberHelper.Int4(fs); if (_angle == 0) { ratio = TenToNegSix; } else { ratio = _angle / _subDivisionsAngle; } _latFirstPoint = (float)(GribNumberHelper.Int4(fs) * ratio); _lonFirstPoint = (float)(GribNumberHelper.Int4(fs) * ratio); _resolutionFlag = fs.ReadByte(); _latEndPoint = (float)(GribNumberHelper.Int4(fs) * ratio); _lonEndPoint = (float)(GribNumberHelper.Int4(fs) * ratio); _dx = (float)(GribNumberHelper.Int4(fs) * ratio); _paralellNumber = fs.ReadByte(); _scanMode = fs.ReadByte(); if (_gridTemplateNo == 41) { _spLat = GribNumberHelper.Int4(fs) * ratio; _spLon = GribNumberHelper.Int4(fs) * ratio; _rotationAngle = GribNumberHelper.IEEEfloat4(fs); } else if (_gridTemplateNo == 42) { _poleLat = GribNumberHelper.Int4(fs) * ratio; _poleLon = GribNumberHelper.Int4(fs) * ratio; _factor = GribNumberHelper.Int4(fs); } else if (_gridTemplateNo == 43) { _spLat = GribNumberHelper.Int4(fs) * ratio; _spLon = GribNumberHelper.Int4(fs) * ratio; _rotationAngle = GribNumberHelper.IEEEfloat4(fs); _poleLat = GribNumberHelper.Int4(fs) * ratio; _poleLon = GribNumberHelper.Int4(fs) * ratio; _factor = GribNumberHelper.Int4(fs); } break; } case 90: // Space view perspective or orthographic { _lap = GribNumberHelper.Int4(fs); _lop = GribNumberHelper.Int4(fs); _resolutionFlag = fs.ReadByte(); _dx = GribNumberHelper.Int4(fs); _dy = GribNumberHelper.Int4(fs); _xp = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _yp = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _scanMode = fs.ReadByte(); _angle = GribNumberHelper.Int4(fs); _altitude = GribNumberHelper.Int4(fs) * 1000000; _xo = GribNumberHelper.Int4(fs); _yo = GribNumberHelper.Int4(fs); break; } case 110: // Equatorial azimuthal equidistant projection { _latFirstPoint = GribNumberHelper.Int4(fs) * TenToNegSix; _lonFirstPoint = GribNumberHelper.Int4(fs) * TenToNegSix; _resolutionFlag = fs.ReadByte(); _dx = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _dy = (float)(GribNumberHelper.Int4(fs) * TenToNegThree); _projectionCenter = fs.ReadByte(); _scanMode = fs.ReadByte(); break; } } } }
private void SetOtherAttribute(FileStream fs) { if (_gridType != 50) { // Nx - 沿x轴的点数量 _nx = GribNumberHelper.Int2(fs); _nx = (_nx == -1) ? 1 : _nx; // Ny - 沿y轴的点数量 _ny = GribNumberHelper.Int2(fs); _ny = (_ny == -1) ? 1 : _ny; _latFirstPoint = GribNumberHelper.Int3(fs) / 1000.0; // La1 - 第一个格网点的纬度 _lonFirstPoint = GribNumberHelper.Int3(fs) / 1000.0; // Lo1 - 第一个格网点的经度 _resolution = fs.ReadByte(); //分辨率和组件标识 } switch (_gridType) { // Latitude/Longitude grids,Arakawa semi-staggered e-grid rotated // Arakawa filled e-grid rotated case 0: // Latitude/longitude grid case 4: //Gaussian latitude/longitude grid case 40: case 201: case 202: { _latEndPoint = GribNumberHelper.Int3(fs) / 1000.0; // La2 - 最后的格网点的纬度 _lonEndPoint = GribNumberHelper.Int3(fs) / 1000.0; // Lo2 - 最后的格网点的经度 _dx = GribNumberHelper.Int2(fs) / 1000.0; // Dx - 经度方向增加量 if (_gridType == 4) { _np = GribNumberHelper.Int2(fs); // Np-极点与赤道间的平行线 } else { _dy = GribNumberHelper.Int2(fs) / 1000.0; // Dy - 纬度方向增加量 } _scanMode = fs.ReadByte(); //扫描模式 //29-32 reserved fs.Seek(4, SeekOrigin.Current); if (_sectionLength > 32) { // Vertical coordinates (NV) and thinned grids (PL) not supported - skip this fs.Seek(_sectionLength - 32, SeekOrigin.Current); } break; } //Mercator projection case 1: _latEndPoint = GribNumberHelper.Int3(fs) / 1000.0; // La2 - 最后格网点的纬度 _lonEndPoint = GribNumberHelper.Int3(fs) / 1000.0; // Lo2 - 最后格网点的经度 // octets 24-26 (Latin - latitude where cylinder intersects the earth _latin1 = GribNumberHelper.Int3(fs) / 1000.0; // Latin -圆柱体与地球相交处的高程 fs.ReadByte(); _scanMode = fs.ReadByte(); //扫描模式 _dx = GribNumberHelper.Int3(fs); // Dx - 经度方向增加量 _dy = GribNumberHelper.Int3(fs); // Dy - 纬度方向增加量 fs.Seek(4, SeekOrigin.Current); if (_sectionLength > 42) { // Vertical coordinates (NV) and thinned grids (PL) not supported - skip this fs.Seek(_sectionLength - 42, SeekOrigin.Current); } break; //Lambert conformal, secant or tangent, conic or bi-polar, projection case 3: // Lov - Orientation of the grid - east lon parallel to y axis) _lov = GribNumberHelper.Int3(fs) / 1000.0; _dx = GribNumberHelper.Int3(fs); // Dx - X方向格网长度 _dy = GribNumberHelper.Int3(fs); // Dy - Y方向格网长度 _projetcenter = fs.ReadByte(); //投影中心标识 _scanMode = fs.ReadByte(); //扫描模式 // Latin1 - first lat where secant cone cuts spherical earth _latin1 = GribNumberHelper.Int3(fs) / 1000.0; // Latin2 - second lat where secant cone cuts spherical earth) _latin2 = GribNumberHelper.Int3(fs) / 1000.0; _latsp = GribNumberHelper.Int3(fs) / 1000.0; //南极点纬度 _lonsp = GribNumberHelper.Int3(fs) / 1000.0; //南极点经度 fs.Seek(2, SeekOrigin.Current); if (_sectionLength > 42) { // Vertical coordinates (NV) and thinned grids (PL) not supported - skip this fs.Seek(_sectionLength - 42, SeekOrigin.Current); } break; case 5: // Lov - Orientation of the grid - east lon parallel to y axis) _lov = GribNumberHelper.Int3(fs) / 1000.0; _dx = GribNumberHelper.Int3(fs); // Dx - 经度方向增加量 _dy = GribNumberHelper.Int3(fs); // Dy - 纬度方向增加量 _projetcenter = fs.ReadByte(); //投影中心标识 _scanMode = fs.ReadByte(); //扫描模式 fs.Seek(4, SeekOrigin.Current); if (_sectionLength > 32) { // Vertical coordinates (NV) and thinned grids (PL) not supported - skip this fs.Seek(_sectionLength - 32, SeekOrigin.Current); } break; default: break; } if ((_scanMode & 63) != 0) { throw new Exception("GDS: This scanning mode (" + _scanMode + ") is not supported."); } }
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); } }