示例#1
0
        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);
 }
示例#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);
        }
示例#4
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");
            }
        }
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#11
0
        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);
        }
示例#12
0
        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);
        }
示例#13
0
 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);
        }
示例#15
0
 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;
     }
 }
示例#16
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);
        }
示例#17
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;
            }
        }
示例#18
0
 public GRIB2SectionHeader(FileStream fs)
 {
     _sectionLength = GribNumberHelper.Int4(fs);
     _sectionNo     = fs.ReadByte();
 }
示例#19
0
        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);
        }
示例#20
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);
            }
        }
示例#21
0
        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;
                }
                }
            }
        }
示例#23
0
        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.");
            }
        }
示例#24
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);
            }
        }