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);
        }
Beispiel #2
0
        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");
            }
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        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;
            }
        }
Beispiel #7
0
        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);
            }
        }
Beispiel #8
0
        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);
            }
        }