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); }
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"); } }
/// <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); }
/// <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); }
/// <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 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); } }
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); } }