/// <summary>
        /// Constructor
        /// </summary>
        /// <param name="br">binary reader</param>
        public GRIB1BitMapSection(BinaryReader br)
        {
            byte[] bytes = br.ReadBytes(3);
            Length = Bytes2Number.Uint3(bytes[0], bytes[1], bytes[2]);

            int unUsed = Convert.ToInt32(br.ReadByte());

            bytes = br.ReadBytes(2);
            int bm = Bytes2Number.Int2(bytes[0], bytes[1]);

            if (bm != 0)
            {
                if ((Length - 6) == 0)
                {
                    return;
                }

                br.ReadBytes(Length - 6);
                return;
            }

            byte[] data = br.ReadBytes(Length - 6);
            Bitmap = new bool[(Length - 6) * 8 - unUsed];
            int[] bitmask = { 128, 64, 32, 16, 8, 4, 2, 1 };
            for (int i = 0; i < Bitmap.Length; i++)
            {
                Bitmap[i] = (data[i / 8] & bitmask[i % 8]) != 0;
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="br">binary reader</param>
 public GRIB1IndicatorSection(BinaryReader br)
 {
     Length = 8;
     Title  = ASCIIEncoding.ASCII.GetString(br.ReadBytes(4));
     byte[] bytes = br.ReadBytes(3);
     RecordLength = Bytes2Number.Uint3(bytes[0], bytes[1], bytes[2]);
     Edition      = Convert.ToInt32(br.ReadByte());
 }
Esempio n. 3
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="br">binary reader</param>
        public GRIB1ProductDefineSection(BinaryReader br)
        {
            byte[] bytes = br.ReadBytes(3);
            Length = Bytes2Number.Uint3(bytes[0], bytes[1], bytes[2]);

            br.BaseStream.Seek(-3, SeekOrigin.Current);
            bytes = br.ReadBytes(Length);

            TableVersion   = Convert.ToInt32(bytes[3]);
            CenterID       = Convert.ToInt32(bytes[4]);
            TypeGenProcess = Convert.ToInt32(bytes[5]);
            GridID         = Convert.ToInt32(bytes[6]);
            int ifExists = Convert.ToInt32(bytes[7]);

            GDSExist           = (ifExists & 128) == 128;
            BMSExist           = (ifExists & 64) == 64;
            ParameterIndicator = Convert.ToInt32(bytes[8]);
            Parameter          = GRIBParameterTable.GetDefaultParameter(ParameterIndicator);
            LevelType          = Convert.ToInt32(bytes[9]);
            LevelValue         = Bytes2Number.Uint2(bytes[10], bytes[11]);
            int year   = Convert.ToInt32(bytes[12]);
            int month  = Convert.ToInt32(bytes[13]);
            int day    = Convert.ToInt32(bytes[14]);
            int hour   = Convert.ToInt32(bytes[15]);
            int minute = Convert.ToInt32(bytes[16]);

            ForecastTimeUnit = Convert.ToInt32(bytes[17]);
            P1 = Convert.ToInt32(bytes[18]);
            P2 = Convert.ToInt32(bytes[19]);
            TimeRangeIndicator = Convert.ToInt32(bytes[20]);
            AveInclude         = Bytes2Number.Int2(bytes[21], bytes[22]);
            NumMissing         = Convert.ToInt32(bytes[23]);
            InitialCentral     = Convert.ToInt32(bytes[24]);
            BaseTime           = new DateTime((InitialCentral - 1) * 100 + year, month, day, hour, minute, 0);
            SubCenterID        = Convert.ToInt32(bytes[25]);
            DecimalScale       = Bytes2Number.Int2(bytes[26], bytes[27]); //octets 27-28
        }
Esempio n. 4
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="br">binary reader</param>
        /// <param name="decimalscale">decimal scale</param>
        /// <param name="bms">GRIB 1 BMS</param>
        /// <param name="scanMode">scan mode</param>
        /// <param name="Xlength">X coordinate number</param>
        /// <param name="Ylength">Y coordinate number</param>
        public GRIB1BinaryDataSection(BinaryReader br, int decimalscale, GRIB1BitMapSection bms, int scanMode,
                                      int Xlength, int Ylength)
        {
            byte[] bytes = br.ReadBytes(3);
            Length = Bytes2Number.Uint3(bytes[0], bytes[1], bytes[2]);

            br.BaseStream.Seek(-3, SeekOrigin.Current);
            bytes = br.ReadBytes(11);    //Read before the data array.

            // octet 4, 1st half (packing flag)
            int unusedbits = Convert.ToInt32(bytes[3]);

            if ((unusedbits & 192) != 0)
            {
                throw new NotSupportedException(
                          "Grib1BinaryDataSection: (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;
            BinScale   = Bytes2Number.Int2(bytes[4], bytes[5]);
            RefValue   = Bytes2Number.Float4(bytes[6], bytes[7], bytes[8], bytes[9]);
            NumBits    = Convert.ToInt32(bytes[10]);
            if (NumBits == 0)
            {
                IsConstant = true;
            }

            // *** read values ************************************************************

            float refd  = (float)(Math.Pow(10.0, -decimalscale) * RefValue);
            float scale = (float)(Math.Pow(10.0, -decimalscale) * Math.Pow(2.0, BinScale));

            if (bms != null)
            {
                bool[] bitmap = bms.Bitmap;

                Data = new double[bitmap.Length];
                for (int i = 0; i < bitmap.Length; i++)
                {
                    if (bitmap[i])
                    {
                        if (!IsConstant)
                        {
                            Data[i] = refd + scale * Bits2UInt(NumBits, br);
                            if (Data[i] > MaxValue)
                            {
                                MaxValue = Data[i];
                            }
                            if (Data[i] < MinValue)
                            {
                                MinValue = Data[i];
                            }
                        }
                        else
                        {// rdg - added this to handle a constant valued parameter
                            Data[i] = refd;
                        }
                    }
                    else
                    {
                        Data[i] = UNDEF;
                    }
                }
                ScanningModeCheck(scanMode, Xlength);
            }
            else
            {
                if (!IsConstant)
                {
                    Data = new double[((Length - 11) * 8 - unusedbits) / NumBits];

                    for (int i = 0; i < Data.Length; i++)
                    {
                        Data[i] = refd + scale * Bits2UInt(NumBits, br);

                        if (Data[i] > MaxValue)
                        {
                            MaxValue = this.Data[i];
                        }
                        if (Data[i] < MinValue)
                        {
                            MinValue = this.Data[i];
                        }
                    }
                    ScanningModeCheck(scanMode, Xlength);
                }
                else
                { // constant valued - same min and max
                    Data     = new double[Xlength * Ylength];
                    MaxValue = refd;
                    MinValue = refd;
                    for (int i = 0; i < Data.Length; i++)
                    {
                        Data[i] = refd;
                    }
                }
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="br">binary reader</param>
        public GRIB1GridDefineSection(BinaryReader br)
        {
            byte[] bytes = br.ReadBytes(3);
            Length = Bytes2Number.Uint3(bytes[0], bytes[1], bytes[2]);

            br.BaseStream.Seek(-3, SeekOrigin.Current);
            bytes = br.ReadBytes(Length);

            NV       = Convert.ToInt32(bytes[3]);
            P_VorL   = Convert.ToInt32(bytes[4]);
            GridType = Convert.ToInt32(bytes[5]);
            double checkSum = GridType;

            if (GridType != 50) //Values same up to resolution
            {
                NX = Bytes2Number.Uint2(bytes[6], bytes[7]);
                if (NX >= 65535)
                {
                    ThinnedGrid = true;
                }

                checkSum   = 7 * checkSum + NX;
                NY         = Bytes2Number.Uint2(bytes[8], bytes[9]);
                checkSum   = 7 * checkSum + NY;
                Lat1       = Bytes2Number.Int3(bytes[10], bytes[11], bytes[12]) / 1000.0;
                checkSum   = 7 * checkSum + Lat1;
                Lon1       = Bytes2Number.Int3(bytes[13], bytes[14], bytes[15]) / 1000.0;
                checkSum   = 7 * checkSum + Lon1;
                Resolution = Convert.ToInt32(bytes[16]);
            }

            switch (GridType)
            {
            case 0:        // Standard Lat/Lon grid, no rotation
            case 4:        //Gaussian Lat/Lon grid
            case 10:       // Rotated Lat/Lon grid
            case 201:      //Arkawa semi-staggered E-grid on rotated lat/lon grid
            case 202:      //Arakawa filled E -grid on rotated lat/lon grid
                Lat2     = Bytes2Number.Int3(bytes[17], bytes[18], bytes[19]) / 1000.0;
                checkSum = 7 * checkSum + Lat2;
                Lon2     = Bytes2Number.Int3(bytes[20], bytes[21], bytes[22]) / 1000.0;
                checkSum = 7 * checkSum + Lon2;

                //Increments given
                if (Resolution == 128)
                {
                    DX = Bytes2Number.Uint2(bytes[23], bytes[24]) / 1000.0;
                    //if (ThinnedGrid)
                    //{
                    //    NX = 73;
                    //    DX = 1.25;
                    //}

                    if (GridType == 4)
                    {
                        NP = Bytes2Number.Uint2(bytes[25], bytes[26]);
                        DY = NP / 1000.0;        //try for error data
                    }
                    else
                    {
                        DY = Bytes2Number.Uint2(bytes[25], bytes[26]) / 1000.0;
                    }

                    ScanMode = Convert.ToInt32(bytes[27]);
                    if ((ScanMode & 128) != 0)
                    {
                        DX = -DX;
                    }
                    //if ((ScanMode & 64) != 64 && Lat2 < Lat1)
                    //    DY = -DY;
                    //if ((ScanMode & 64) != 64 || Lat2 < Lat1)
                    //    DY = -DY;
                    if (Lat2 < Lat1)
                    {
                        DY = -DY;
                    }
                }
                else
                {
                    //Calculate increments
                    DX = (Lon2 - Lon1) / (NX - 1);
                    DY = (Lat2 - Lat1) / (NY - 1);
                }
                if (DX < 0)
                {
                    XReverse = true;
                }
                if (DY < 0)
                {
                    YReverse = true;
                }

                if (ThinnedGrid)
                {
                    ThinnedXNums   = new int[NY];
                    ThinnedGridNum = 0;
                    for (int i = 0; i < NY; i++)
                    {
                        ThinnedXNums[i] = Bytes2Number.Int2(bytes[32 + i * 2], bytes[33 + i * 2]);
                        ThinnedGridNum += ThinnedXNums[i];
                        if (i == 0)
                        {
                            NX = ThinnedXNums[i];
                        }
                        else
                        {
                            if (NX < ThinnedXNums[i])
                            {
                                NX = ThinnedXNums[i];
                            }
                        }
                    }
                    DX = Math.Abs(Lon2 - Lon1) / (NX - 1);
                }

                if (GridType == 10)
                {
                    // Rotated Lat/Lon grid, Lat (octets 33-35), Lon (octets 36-38), rotang (octets 39-42)
                    Latsp  = Bytes2Number.Int3(bytes[32], bytes[33], bytes[34]) / 1000.0;
                    Lonsp  = Bytes2Number.Int3(bytes[35], bytes[36], bytes[37]) / 1000.0;
                    Rotang = Bytes2Number.Int4(bytes[38], bytes[39], bytes[40], bytes[41]) / 1000.0;
                }
                break;

            case 1:        //Mercator projection
                Lat2     = Bytes2Number.Int3(bytes[17], bytes[18], bytes[19]) / 1000.0;
                checkSum = 7 * checkSum + Lat2;
                Lon2     = Bytes2Number.Int3(bytes[20], bytes[21], bytes[22]) / 1000.0;
                checkSum = 7 * checkSum + Lon2;
                Latin1   = Bytes2Number.Int3(bytes[23], bytes[24], bytes[25]) / 1000.0;
                checkSum = 7 * checkSum + Latin1;
                ScanMode = bytes[27];
                DX       = Bytes2Number.Int3(bytes[28], bytes[29], bytes[30]);
                DY       = Bytes2Number.Int3(bytes[31], bytes[32], bytes[33]);
                break;

            case 3:        //Lambert projection
                Lov         = Bytes2Number.Int3(bytes[17], bytes[18], bytes[19]) / 1000.0;
                checkSum    = 7 * checkSum + Lov;
                DX          = Bytes2Number.Int3(bytes[20], bytes[21], bytes[22]);
                DY          = Bytes2Number.Int3(bytes[23], bytes[24], bytes[25]);
                Proj_Center = bytes[26];
                ScanMode    = bytes[27];
                Latin1      = Bytes2Number.Int3(bytes[28], bytes[29], bytes[30]) / 1000.0;
                checkSum    = 7 * checkSum + Latin1;
                Latin2      = Bytes2Number.Int3(bytes[31], bytes[32], bytes[33]) / 1000.0;
                checkSum    = 7 * checkSum + Latin2;
                Latsp       = Bytes2Number.Int3(bytes[34], bytes[35], bytes[36]) / 1000.0;
                checkSum    = 7 * checkSum + Latsp;
                Lonsp       = Bytes2Number.Int3(bytes[37], bytes[38], bytes[39]) / 1000.0;
                checkSum    = 7 * checkSum + Lonsp;
                break;

            case 5:        //Polar stereographic projection
            case 87:
                Lov      = Bytes2Number.Int3(bytes[17], bytes[18], bytes[19]) / 1000.0;
                checkSum = 7 * checkSum + Lov;

                if (GridType == 87)
                {
                    Lon2     = Bytes2Number.Int3(bytes[20], bytes[21], bytes[22]) / 1000.0;
                    checkSum = 7 * checkSum + Lon2;
                }

                DX          = Bytes2Number.Int3(bytes[20], bytes[21], bytes[22]);
                DY          = Bytes2Number.Int3(bytes[23], bytes[24], bytes[25]);
                Proj_Center = bytes[26];
                ScanMode    = bytes[27];
                break;

            default:

                break;
            }


            // This switch uses the grid_type to define how to handle the
            // southpole information.
            switch (GridType)
            {
            case 0:
                // Standard Lat/Lon grid, no rotation
                Latsp  = -90.0;
                Lonsp  = 0.0;
                Rotang = 0.0;
                break;

            default:
                // No knowledge yet
                // NEED to fix this later, if supporting other grid types
                Latsp  = Double.NaN;
                Lonsp  = Double.NaN;
                Rotang = Double.NaN;
                break;
            }
        }