Пример #1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="br">binary reader</param>
        public GRIB2BitMapSection(BinaryReader br)
        {
            long sectionEnd = br.BaseStream.Position;

            Length      = Bytes2Number.Int4(br);
            sectionEnd += Length;

            SectionNum      = br.ReadByte();
            BitMapIndicator = br.ReadByte();

            //No bit map
            if (BitMapIndicator != 0)
            {
                return;
            }

            //Get bit map data
            byte[] data = br.ReadBytes(Length - 6);
            Bitmap = new bool[(Length - 6) * 8];
            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;
            }

            //Set stream position to the section end
            br.BaseStream.Position = sectionEnd;
        }
Пример #2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="br">binary reader</param>
        public GRIB2IdentificationSection(BinaryReader br)
        {
            byte[] bytes = br.ReadBytes(4);
            Length = Bytes2Number.Int4(bytes[0], bytes[1], bytes[2], bytes[3]);

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

            SectionNum         = bytes[4];
            CenterID           = Bytes2Number.Int2(bytes[5], bytes[6]);
            SubCenterID        = Bytes2Number.Int2(bytes[7], bytes[8]);
            MasterTableVersion = bytes[9];
            LocalTableVersion  = bytes[10];
            SReferenceTime     = bytes[11];
            int year   = Bytes2Number.Int2(bytes[12], bytes[13]);
            int month  = bytes[14];
            int day    = bytes[15];
            int hour   = bytes[16];
            int minute = bytes[17];
            int second = bytes[18];

            BaseTime      = new DateTime(year, month, day, hour, minute, second);
            ProductStatus = bytes[19];
            ProductType   = bytes[20];
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="br">binary reader</param>
        public GRIB2LocalUseSection(BinaryReader br)
        {
            Length = Bytes2Number.Int4(br);

            br.BaseStream.Seek(-4, SeekOrigin.Current);
            byte[] bytes = br.ReadBytes(Length);

            SectionNum = bytes[4];
        }
Пример #4
0
        /// <summary>
        /// Constructor
        /// </summary>
        ///<param name="br">binary reader</param>
        ///<param name="gds">grid definition section</param>
        ///<param name="drs">data representation section</param>
        ///<param name="bms">bit map section</param>
        public GRIB2DataSection(BinaryReader br, GRIB2GridDefinitionSection gds,
                                GRIB2DataRepresentationSection drs, GRIB2BitMapSection bms)
        {
            for (int i = 0; i < 31; i++)
            {
                bitsmv1[i] = (int)Math.Pow((double)2, (double)i) - 1;
            }

            Length     = Bytes2Number.Int4(br);
            SectionNum = br.ReadByte();

            int dtn = drs.DataTemplateNum;

            if (dtn == 0)
            {  // 0: Grid point data - simple packing
                SimpleUnpacking(br, gds, drs, bms);
            }
            else if (dtn == 1)
            {
                // 1: Matrix values - simple packing
                Data = null;
                //logger.error("Matrix values - simple packing not implemented");
            }
            else if (dtn == 2)
            {                       // 2:Grid point data - complex packing
                ComplexUnpacking(br, gds, drs, bms);
            }
            else if (dtn == 3)
            {    // 3: complex packing with spatial differencing
                ComplexUnpackingWithSpatial(br, gds, drs, bms);
            }
            else if ((dtn == 40) || (dtn == 40000))
            {  // JPEG 2000 Stream Format
                jpeg2000Unpacking(br, gds, drs, bms);
                //MessageBox.Show("The packing method is not supported at present!", "Error");
            }
        }
Пример #5
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="br">binary reader</param>
        public GRIB2DataRepresentationSection(BinaryReader br)
        {
            long sectionEnd = br.BaseStream.Position;

            Length      = Bytes2Number.Int4(br);
            sectionEnd += Length;

            SectionNum      = br.ReadByte();
            DataPoints      = Bytes2Number.Int4(br);
            DataTemplateNum = Bytes2Number.Uint2(br);

            switch (DataTemplateNum)
            {       // Data Template Number
            case 0:
            case 1: // 0 - Grid point data - simple packing
                // 1 - Matrix values - simple packing
                //ReferenceValue = br.ReadSingle();
                ReferenceValue     = Bytes2Number.Float(br);
                BinaryScaleFactor  = Bytes2Number.Int2(br);
                DecimalScaleFactor = Bytes2Number.Int2(br);
                NumberOfBits       = br.ReadByte();
                //System.out.println( "DRS numberOfBits=" + numberOfBits );
                originalType = br.ReadByte();
                //System.out.println( "DRS originalType=" + originalType );

                if (DataTemplateNum == 0)
                {
                    break;
                }
                // case 1 not implememted
                //System.out.println("DRS dataTemplate=1 not implemented yet");
                break;

            case 2:
            case 3:      // Grid point data - complex packing
                //System.out.println( "DRS dataTemplate=" + dataTemplate );
                // octet 12 - 15
                //ReferenceValue = br.ReadSingle();
                ReferenceValue = Bytes2Number.Float(br);
                // octet 16 - 17
                BinaryScaleFactor = Bytes2Number.Int2(br);
                // octet 18 - 19
                DecimalScaleFactor = Bytes2Number.Int2(br);
                // octet 20
                NumberOfBits = br.ReadByte();
                //System.out.println( "DRS numberOfBits=" + numberOfBits );
                // octet 21
                originalType = br.ReadByte();
                //System.out.println( "DRS originalType=" + originalType );
                // octet 22
                splittingMethod = br.ReadByte();
                //System.out.println( "DRS splittingMethod=" +
                //     splittingMethod );
                // octet 23
                MissingValueManagement = br.ReadByte();
                //System.out.println( "DRS MissingValueManagement=" +
                //     MissingValueManagement );
                // octet 24 - 27
                PrimaryMissingValue = br.ReadSingle();
                // octet 28 - 31
                SecondaryMissingValue = br.ReadSingle();
                // octet 32 - 35
                NumberOfGroups = Bytes2Number.Int4(br);
                //System.out.println( "DRS numberOfGroups=" +
                //     numberOfGroups );
                // octet 36
                ReferenceGroupWidths = br.ReadByte();
                //System.out.println( "DRS referenceGroupWidths=" +
                //     referenceGroupWidths );
                // octet 37
                BitsGroupWidths = br.ReadByte();
                // according to documentation subtract referenceGroupWidths
                // TODO: check again and delete
                //bitsGroupWidths = bitsGroupWidths - referenceGroupWidths;
                //System.out.println( "DRS bitsGroupWidths=" +
                //     bitsGroupWidths );
                // octet 38 - 41
                ReferenceGroupLength = Bytes2Number.Int4(br);
                //System.out.println( "DRS referenceGroupLength=" +
                //     referenceGroupLength );
                // octet 42
                LengthIncrement = br.ReadByte();
                //System.out.println( "DRS lengthIncrement=" +
                //     lengthIncrement );
                // octet 43 - 46
                LengthLastGroup = Bytes2Number.Int4(br);
                //System.out.println( "DRS lengthLastGroup=" +
                //     lengthLastGroup );
                // octet 47
                BitsScaledGroupLength = br.ReadByte();
                //System.out.println( "DRS bitsScaledGroupLength=" +
                //     bitsScaledGroupLength );
                if (DataTemplateNum == 2)
                {
                    break;
                }

                // case 3 // complex packing & spatial differencing
                // octet 48
                OrderSpatial = br.ReadByte();
                //System.out.println( "DRS orderSpatial=" + orderSpatial);
                // octet 49
                DescriptorSpatial = br.ReadByte();
                //System.out.println( "DRS descriptorSpatial=" + descriptorSpatial);
                break;

            case 40:
            case 40000:      // Grid point data - JPEG 2000 Code Stream Format
                //System.out.println( "DRS dataTemplate=" + dataTemplate );
                //ReferenceValue = br.ReadSingle();
                ReferenceValue     = Bytes2Number.Float(br);
                BinaryScaleFactor  = Bytes2Number.Int2(br);
                DecimalScaleFactor = Bytes2Number.Int2(br);
                NumberOfBits       = br.ReadByte();
                //System.out.println( "DRS numberOfBits=" + numberOfBits );
                originalType = br.ReadByte();
                //System.out.println( "DRS originalType=" + originalType );
                compressionMethod = br.ReadByte();
                //System.out.println( "DRS compressionMethod=" + compressionMethod );
                compressionRatio = br.ReadByte();
                //System.out.println( "DRS compressionRatio=" + compressionRatio );
                break;

            default:
                break;
            }

            //Set stream position to the section end
            br.BaseStream.Position = sectionEnd;
        }
        ///// <summary>
        ///// check sum
        ///// </summary>
        //private String checksum = "";
        ///// <summary>
        ///// 4.0 indexes use this for the GDS key
        ///// </summary>
        //private int gdskey;

        #endregion

        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="br">binary reader</param>
        public GRIB2GridDefinitionSection(BinaryReader br)
        {
            float  ratio;
            double checkSum;
            int    scalefactorradius = 0;
            int    scaledvalueradius = 0;
            int    scalefactormajor  = 0;
            int    scaledvaluemajor  = 0;
            int    scalefactorminor  = 0;
            int    scaledvalueminor  = 0;

            long sectionEnd = br.BaseStream.Position;

            Length      = Bytes2Number.Int4(br);
            sectionEnd += Length;

            SectionNum    = br.ReadByte();
            SourceGridDef = br.ReadByte();
            NumPoints     = Bytes2Number.Int4(br);
            checkSum      = NumPoints;
            Olon          = br.ReadByte();
            Iolon         = br.ReadByte();
            TemplateNum   = Bytes2Number.Int2(br);
            GridName      = GetGridName(TemplateNum);

            switch (TemplateNum)
            {  // Grid Definition Template Number
            case 0:
            case 1:
            case 2:
            case 3:           // Latitude/Longitude Grid
                Shape = br.ReadByte();
                //System.out.println( "shape=" + shape );
                scalefactorradius = br.ReadByte();
                scaledvalueradius = Bytes2Number.Int4(br);
                scalefactormajor  = br.ReadByte();
                scaledvaluemajor  = Bytes2Number.Int4(br);
                scalefactorminor  = br.ReadByte();
                scaledvalueminor  = Bytes2Number.Int4(br);
                NX                = Bytes2Number.Int4(br);
                NY                = Bytes2Number.Int4(br);
                Angle             = Bytes2Number.Int4(br);
                SubdivisionsAngle = Bytes2Number.Int4(br);
                if (Angle == 0)
                {
                    ratio = tenToNegSix;
                }
                else
                {
                    ratio = Angle / SubdivisionsAngle;
                }
                la1        = (float)(Bytes2Number.Int4(br) * ratio);
                checkSum   = 7 * checkSum + la1;
                lo1        = (float)(Bytes2Number.Int4(br) * ratio);
                checkSum   = 7 * checkSum + lo1;
                resolution = br.ReadByte();
                la2        = (float)(Bytes2Number.Int4(br) * ratio);
                checkSum   = 7 * checkSum + la2;
                lo2        = (float)(Bytes2Number.Int4(br) * ratio);
                checkSum   = 7 * checkSum + lo2;
                dx         = (float)(Bytes2Number.Int4(br) * ratio);
                //checkSum = 7 * checkSum + dx;
                dy = (float)(Bytes2Number.Int4(br) * ratio);

                grid_units = "degrees";

                //checkSum = 7 * checkSum + dy;
                ScanMode = br.ReadByte();

                //  1, 2, and 3 needs checked
                if (TemplateNum == 1)
                {             //Rotated Latitude/longitude
                    spLat         = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + spLat;
                    spLon         = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + spLon;
                    rotationangle = br.ReadSingle();
                }
                else if (TemplateNum == 2)
                {      //Stretched Latitude/longitude
                    poleLat  = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum = 7 * checkSum + poleLat;
                    poleLon  = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum = 7 * checkSum + poleLon;
                    factor   = Bytes2Number.Int4(br);
                }
                else if (TemplateNum == 3)
                {      //Stretched and Rotated
                    // Latitude/longitude
                    spLat         = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + spLat;
                    spLon         = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + spLon;
                    rotationangle = br.ReadSingle();
                    poleLat       = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + poleLat;
                    poleLon       = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + poleLon;
                    factor        = Bytes2Number.Int4(br);
                }
                break;

            case 10:      // Mercator
                // la1, lo1, lad, la2, and lo2 need checked
                Shape = br.ReadByte();
                //System.out.println( "shape=" + shape );
                scalefactorradius = br.ReadByte();
                scaledvalueradius = Bytes2Number.Int4(br);
                scalefactormajor  = br.ReadByte();
                scaledvaluemajor  = Bytes2Number.Int4(br);
                scalefactorminor  = br.ReadByte();
                scaledvalueminor  = Bytes2Number.Int4(br);
                NX = Bytes2Number.Int4(br);
                //System.out.println( "nx=" + nx);
                NY = Bytes2Number.Int4(br);
                //System.out.println( "ny=" + ny);
                la1        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + la1;
                lo1        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + lo1;
                resolution = br.ReadByte();
                lad        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + lad;
                la2        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + la2;
                lo2        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + lo2;
                ScanMode   = br.ReadByte();
                Angle      = Bytes2Number.Int4(br);
                dx         = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                //checkSum = 7 * checkSum + dx;
                dy = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                //checkSum = 7 * checkSum + dy;
                grid_units = "m";

                break;

            case 20:      // Polar stereographic projection
                // la1, lo1, lad, and lov need checked
                Shape = br.ReadByte();
                //System.out.println( "shape=" + shape );
                scalefactorradius = br.ReadByte();
                scaledvalueradius = Bytes2Number.Int4(br);
                scalefactormajor  = br.ReadByte();
                scaledvaluemajor  = Bytes2Number.Int4(br);
                scalefactorminor  = br.ReadByte();
                scaledvalueminor  = Bytes2Number.Int4(br);
                NX = Bytes2Number.Int4(br);
                //System.out.println( "nx=" + nx);
                NY = Bytes2Number.Int4(br);
                //System.out.println( "ny=" + ny);
                la1        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + la1;
                lo1        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + lo1;
                resolution = br.ReadByte();
                lad        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + lad;
                lov        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + lov;
                dx         = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                //checkSum = 7 * checkSum + dx;
                dy         = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                grid_units = "m";
                //checkSum = 7 * checkSum + dy;
                projectionCenter = br.ReadByte();
                ScanMode         = br.ReadByte();

                break;

            case 30:      // Lambert Conformal
                Shape = br.ReadByte();
                //System.out.println( "shape=" + shape );
                scalefactorradius = br.ReadByte();
                scaledvalueradius = Bytes2Number.Int4(br);
                scalefactormajor  = br.ReadByte();
                scaledvaluemajor  = Bytes2Number.Int4(br);
                scalefactorminor  = br.ReadByte();
                scaledvalueminor  = Bytes2Number.Int4(br);
                NX = Bytes2Number.Int4(br);
                //System.out.println( "nx=" + nx);
                NY = Bytes2Number.Int4(br);
                //System.out.println( "ny=" + ny);
                la1      = (float)(Bytes2Number.Int4(br) * tenToNegSix);
                checkSum = 7 * checkSum + la1;
                //System.out.println( "la1=" + la1 );
                lo1      = (float)(Bytes2Number.Int4(br) * tenToNegSix);
                checkSum = 7 * checkSum + lo1;
                //System.out.println( "lo1=" + lo1);
                resolution = br.ReadByte();
                lad        = (float)(Bytes2Number.Int4(br)
                                     * tenToNegSix);
                checkSum = 7 * checkSum + lad;
                lov      = (float)(Bytes2Number.Int4(br)
                                   * tenToNegSix);
                checkSum = 7 * checkSum + lov;
                dx       = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                //checkSum = 7 * checkSum + dx;
                dy = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                //checkSum = 7 * checkSum + dy;
                grid_units = "m";

                projectionCenter = br.ReadByte();
                ScanMode         = br.ReadByte();
                latin1           = (float)(Bytes2Number.Int4(br)
                                           * tenToNegSix);
                checkSum = 7 * checkSum + latin1;
                latin2   = (float)(Bytes2Number.Int4(br)
                                   * tenToNegSix);
                checkSum = 7 * checkSum + latin2;
                //System.out.println( "latin1=" + latin1);
                //System.out.println( "latin2=" + latin2);
                spLat    = (float)(Bytes2Number.Int4(br) * tenToNegSix);
                checkSum = 7 * checkSum + spLat;
                spLon    = (float)(Bytes2Number.Int4(br) * tenToNegSix);
                checkSum = 7 * checkSum + spLon;
                //System.out.println( "spLat=" + spLat);
                //System.out.println( "spLon=" + spLon);

                break;

            case 31:      // Albers Equal Area
                // la1, lo1, lad, and lov need checked
                Shape = br.ReadByte();
                //System.out.println( "shape=" + shape );
                scalefactorradius = br.ReadByte();
                scaledvalueradius = Bytes2Number.Int4(br);
                scalefactormajor  = br.ReadByte();
                scaledvaluemajor  = Bytes2Number.Int4(br);
                scalefactorminor  = br.ReadByte();
                scaledvalueminor  = Bytes2Number.Int4(br);
                NX = Bytes2Number.Int4(br);
                //System.out.println( "nx=" + nx);
                NY = Bytes2Number.Int4(br);
                //System.out.println( "ny=" + ny);
                la1      = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum = 7 * checkSum + la1;
                //System.out.println( "la1=" + la1 );
                lo1      = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum = 7 * checkSum + lo1;
                //System.out.println( "lo1=" + lo1);
                resolution = br.ReadByte();
                lad        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + lad;
                lov        = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum   = 7 * checkSum + lov;
                dx         = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                //checkSum = 7 * checkSum + dx;
                dy = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                //checkSum = 7 * checkSum + dy;
                grid_units = "m";

                projectionCenter = br.ReadByte();
                ScanMode         = br.ReadByte();
                latin1           = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum         = 7 * checkSum + latin1;
                latin2           = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum         = 7 * checkSum + latin2;
                //System.out.println( "latin1=" + latin1);
                //System.out.println( "latin2=" + latin2);
                spLat    = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum = 7 * checkSum + spLat;
                spLon    = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum = 7 * checkSum + spLon;
                //System.out.println( "spLat=" + spLat);
                //System.out.println( "spLon=" + spLon);

                break;

            case 40:
            case 41:
            case 42:
            case 43:      // Gaussian latitude/longitude
                // octet 15
                Shape = br.ReadByte();
                //System.out.println( "shape=" + shape );
                // octet 16
                scalefactorradius = br.ReadByte();
                // octets 17-20
                scaledvalueradius = Bytes2Number.Int4(br);
                // octet 21
                scalefactormajor = br.ReadByte();
                // octets 22-25
                scaledvaluemajor = Bytes2Number.Int4(br);
                // octet 26
                scalefactorminor = br.ReadByte();
                // octets 27-30
                scaledvalueminor = Bytes2Number.Int4(br);
                // octets 31-34
                NX = Bytes2Number.Int4(br);
                //System.out.println( "nx=" + nx);
                // octets 35-38
                NY = Bytes2Number.Int4(br);
                //System.out.println( "ny=" + ny);
                // octets 39-42
                Angle = Bytes2Number.Int4(br);
                // octets 43-46
                SubdivisionsAngle = Bytes2Number.Int4(br);
                if (Angle == 0)
                {
                    ratio = tenToNegSix;
                }
                else
                {
                    ratio = Angle / SubdivisionsAngle;
                }
                //System.out.println( "ratio =" + ratio );
                // octets 47-50
                la1      = (float)(Bytes2Number.Int4(br) * ratio);
                checkSum = 7 * checkSum + la1;
                // octets 51-54
                lo1      = (float)(Bytes2Number.Int4(br) * ratio);
                checkSum = 7 * checkSum + lo1;
                // octet 55
                resolution = br.ReadByte();
                // octets 56-59
                la2      = (float)(Bytes2Number.Int4(br) * ratio);
                checkSum = 7 * checkSum + la2;
                // octets 60-63
                lo2      = (float)(Bytes2Number.Int4(br) * ratio);
                checkSum = 7 * checkSum + lo2;
                // octets 64-67
                dx = (float)(Bytes2Number.Int4(br) * ratio);
                //checkSum = 7 * checkSum + dx;
                grid_units = "degrees";

                // octet 68-71
                n = Bytes2Number.Int4(br);
                // octet 72
                ScanMode = br.ReadByte();

                if (TemplateNum == 41)
                {      //Rotated Gaussian Latitude/longitude
                    // octets 73-76
                    spLat    = Bytes2Number.Int4(br) * ratio;
                    checkSum = 7 * checkSum + spLat;
                    // octets 77-80
                    spLon    = Bytes2Number.Int4(br) * ratio;
                    checkSum = 7 * checkSum + spLon;
                    // octets 81-84
                    rotationangle = br.ReadSingle();
                }
                else if (TemplateNum == 42)
                {      //Stretched Gaussian
                    // Latitude/longitude
                    // octets 73-76
                    poleLat  = Bytes2Number.Int4(br) * ratio;
                    checkSum = 7 * checkSum + poleLat;
                    // octets 77-80
                    poleLon  = Bytes2Number.Int4(br) * ratio;
                    checkSum = 7 * checkSum + poleLon;
                    // octets 81-84
                    factor = Bytes2Number.Int4(br);
                }
                else if (TemplateNum == 43)
                {      //Stretched and Rotated Gaussian
                    // Latitude/longitude
                    // octets 73-76
                    spLat    = Bytes2Number.Int4(br) * ratio;
                    checkSum = 7 * checkSum + spLat;
                    // octets 77-80
                    spLon    = Bytes2Number.Int4(br) * ratio;
                    checkSum = 7 * checkSum + spLon;
                    // octets 81-84
                    rotationangle = br.ReadSingle();
                    // octets 85-88
                    poleLat  = Bytes2Number.Int4(br) * ratio;
                    checkSum = 7 * checkSum + poleLat;
                    // octets 89-92
                    poleLon  = Bytes2Number.Int4(br) * ratio;
                    checkSum = 7 * checkSum + poleLon;
                    // octets 93-96
                    factor = Bytes2Number.Int4(br);
                }
                break;

            case 50:
            case 51:
            case 52:
            case 53:                         // Spherical harmonic coefficients

                j          = br.ReadSingle();
                k          = br.ReadSingle();
                m          = br.ReadSingle();
                method     = br.ReadByte();
                mode       = br.ReadByte();
                grid_units = "";
                if (TemplateNum == 51)
                {             //Rotated Spherical harmonic coefficients
                    spLat         = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + spLat;
                    spLon         = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + spLon;
                    rotationangle = br.ReadSingle();
                }
                else if (TemplateNum == 52)
                {      //Stretched Spherical
                       // harmonic coefficients

                    poleLat  = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum = 7 * checkSum + poleLat;
                    poleLon  = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum = 7 * checkSum + poleLon;
                    factor   = Bytes2Number.Int4(br);
                }
                else if (TemplateNum == 53)
                {      //Stretched and Rotated
                       // Spherical harmonic coefficients

                    spLat         = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + spLat;
                    spLon         = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + spLon;
                    rotationangle = br.ReadSingle();
                    poleLat       = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + poleLat;
                    poleLon       = Bytes2Number.Int4(br) * tenToNegSix;
                    checkSum      = 7 * checkSum + poleLon;
                    factor        = Bytes2Number.Int4(br);
                }
                break;

            case 90:      // Space view perspective or orthographic
                Shape = br.ReadByte();
                //System.out.println( "shape=" + shape );
                scalefactorradius = br.ReadByte();
                scaledvalueradius = Bytes2Number.Int4(br);
                scalefactormajor  = br.ReadByte();
                scaledvaluemajor  = Bytes2Number.Int4(br);
                scalefactorminor  = br.ReadByte();
                scaledvalueminor  = Bytes2Number.Int4(br);
                NX = Bytes2Number.Int4(br);
                //System.out.println( "nx=" + nx);
                NY = Bytes2Number.Int4(br);
                //System.out.println( "ny=" + ny);
                lap        = Bytes2Number.Int4(br);
                checkSum   = 7 * checkSum + lap;
                lop        = Bytes2Number.Int4(br);
                checkSum   = 7 * checkSum + lop;
                resolution = br.ReadByte();
                dx         = Bytes2Number.Int4(br);
                //checkSum = 7 * checkSum + dx;
                dy = Bytes2Number.Int4(br);
                //checkSum = 7 * checkSum + dy;
                grid_units = "";
                xp         = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                checkSum   = 7 * checkSum + xp;
                yp         = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                checkSum   = 7 * checkSum + yp;
                ScanMode   = br.ReadByte();
                Angle      = Bytes2Number.Int4(br);
                //altitude = Bytes2Number.int4( raf ) * 1000000;
                byte[] bytes = br.ReadBytes(4);
                altitude = Bytes2Number.Int4(bytes[0], bytes[1], bytes[2], bytes[3]);
                altitude = (int)(altitude * 6.378169 - 6378169);
                if ((bytes[0] & 256) == 256 && (bytes[1] & 256) == 256 && (bytes[2] & 256) == 256 && (bytes[3] & 256) == 256)
                {
                    isOrtho = true;
                }
                //altitude = Bytes2Number.Int4(br);
                checkSum = 7 * checkSum + altitude;
                xo       = Bytes2Number.Int4(br);
                checkSum = 7 * checkSum + xo;
                yo       = Bytes2Number.Int4(br);
                checkSum = 7 * checkSum + yo;

                break;

            case 100:      // Triangular grid based on an icosahedron

                n2          = br.ReadByte();
                checkSum    = 7 * checkSum + n2;
                n3          = br.ReadByte();
                checkSum    = 7 * checkSum + n3;
                ni          = Bytes2Number.Int2(br);
                checkSum    = 7 * checkSum + ni;
                nd          = br.ReadByte();
                checkSum    = 7 * checkSum + nd;
                poleLat     = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum    = 7 * checkSum + poleLat;
                poleLon     = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum    = 7 * checkSum + poleLon;
                lonofcenter = Bytes2Number.Int4(br);
                position    = br.ReadByte();
                order       = br.ReadByte();
                ScanMode    = br.ReadByte();
                n           = Bytes2Number.Int4(br);
                grid_units  = "";
                break;

            case 110:      // Equatorial azimuthal equidistant projection
                Shape             = br.ReadByte();
                scalefactorradius = br.ReadByte();
                scaledvalueradius = Bytes2Number.Int4(br);
                scalefactormajor  = br.ReadByte();
                scaledvaluemajor  = Bytes2Number.Int4(br);
                scalefactorminor  = br.ReadByte();
                scaledvalueminor  = Bytes2Number.Int4(br);
                NX               = Bytes2Number.Int4(br);
                NY               = Bytes2Number.Int4(br);
                la1              = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum         = 7 * checkSum + la1;
                lo1              = Bytes2Number.Int4(br) * tenToNegSix;
                checkSum         = 7 * checkSum + lo1;
                resolution       = br.ReadByte();
                dx               = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                dy               = (float)(Bytes2Number.Int4(br) * tenToNegThree);
                grid_units       = "";
                projectionCenter = br.ReadByte();
                ScanMode         = br.ReadByte();

                break;

            case 120:      // Azimuth-range Projection
                nb       = Bytes2Number.Int4(br);
                checkSum = 7 * checkSum + nb;
                nr       = Bytes2Number.Int4(br);
                checkSum = 7 * checkSum + nr;
                la1      = Bytes2Number.Int4(br);
                checkSum = 7 * checkSum + la1;
                lo1      = Bytes2Number.Int4(br);
                checkSum = 7 * checkSum + lo1;
                dx       = Bytes2Number.Int4(br);
                //checkSum = 7 * checkSum + dx;
                grid_units = "";
                dstart     = br.ReadSingle();
                ScanMode   = br.ReadByte();
                for (int i = 0; i < nr; i++)
                {
                    // get azi (33+4(Nr-1))-(34+4(Nr-1))
                    // get adelta (35+4(Nr-1))-(36+4(Nr-1))
                }

                break;

            case 204:      // Curvilinear orthographic
                Shape = br.ReadByte();
                //System.out.println( "shape=" + shape );
                scalefactorradius = br.ReadByte();
                scaledvalueradius = Bytes2Number.Int4(br);
                scalefactormajor  = br.ReadByte();
                scaledvaluemajor  = Bytes2Number.Int4(br);
                scalefactorminor  = br.ReadByte();
                scaledvalueminor  = Bytes2Number.Int4(br);
                NX = Bytes2Number.Int4(br);
                NY = Bytes2Number.Int4(br);
                // octets 39 - 54 not used, set to 0
                br.ReadBytes(16);
                resolution = br.ReadByte();
                // octets 56 - 71 not used
                br.ReadBytes(16);
                ScanMode   = br.ReadByte();
                grid_units = "";
                break;

            default:
                break;
            }  // end switch

            // calculate earth radius
            if (((TemplateNum < 50) || (TemplateNum > 53)) && (TemplateNum != 100) && (TemplateNum != 120))
            {
                if (Shape == 0)
                {
                    earthRadius = 6367470;
                }
                else if (Shape == 1)
                {
                    earthRadius = scaledvalueradius;
                    if (scalefactorradius != 0)
                    {
                        earthRadius /= (float)Math.Pow(10, scalefactorradius);
                    }
                }
                else if (Shape == 2)
                {
                    majorAxis = (float)6378160.0;
                    minorAxis = (float)6356775.0;
                }
                else if (Shape == 3)
                {
                    majorAxis = scaledvaluemajor;
                    //System.out.println( "majorAxisScale =" + scalefactormajor );
                    //System.out.println( "majorAxisiValue =" + scaledvaluemajor );
                    majorAxis /= (float)Math.Pow(10, scalefactormajor);

                    minorAxis = scaledvalueminor;
                    //System.out.println( "minorAxisScale =" + scalefactorminor );
                    //System.out.println( "minorAxisValue =" + scaledvalueminor );
                    minorAxis /= (float)Math.Pow(10, scalefactorminor);
                }
                else if (Shape == 4)
                {
                    majorAxis = (float)6378137.0;
                    minorAxis = (float)6356752.314;
                }
                else if (Shape == 6)
                {
                    earthRadius = 6371229;
                }
            }
            // This is a quasi-regular grid, save the number of pts in each parallel
            if (Olon != 0)
            {
                //System.out.println( "olon ="+ olon +" iolon ="+ iolon );
                int numPts;
                if ((ScanMode & 32) == 0)
                {
                    numPts = NY;
                }
                else
                {
                    numPts = NX;
                }
                olonPts = new int[numPts];
                //int count = 0;
                maxPts = 0;
                if (Olon == 1)
                {
                    for (int i = 0; i < numPts; i++)
                    {
                        olonPts[i] = br.ReadByte();
                        if (maxPts < olonPts[i])
                        {
                            maxPts = olonPts[i];
                        }
                        //count += olonPts[ i ];
                        //System.out.println( "parallel =" + i +" number pts ="+ latPts );
                    }
                }
                else if (Olon == 2)
                {
                    for (int i = 0; i < numPts; i++)
                    {
                        olonPts[i] = br.ReadUInt16();
                        if (maxPts < olonPts[i])
                        {
                            maxPts = olonPts[i];
                        }
                        //count += olonPts[ i ];
                        //System.out.println( "parallel =" + i +" number pts ="+ latPts );
                    }
                }
                if ((ScanMode & 32) == 0)
                {
                    NX = maxPts;
                }
                else
                {
                    NY = maxPts;
                }
                //double lodiff = gds.getLo2() - gds.getLo1();
                dx = (float)(lo2 - lo1) / (NX - 0);
                //System.out.println( "total number pts ="+ count );
            }

            //gdskey = Double.ToString(checkSum).HashCode();
            //checksum = Integer.toString(gdskey);

            br.BaseStream.Position = sectionEnd;
        }
Пример #7
0
        /// <summary>
        /// Read data info
        /// </summary>
        /// <param name="aFile">file path</param>
        public override void ReadDataInfo(string aFile)
        {
            this.FileName = aFile;

            FileStream   fs = new FileStream(aFile, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);

            int headerType;
            int headerRecordLength;

            //Read primary header
            _primaryHeader.Header_Type          = br.ReadByte();
            _primaryHeader.Header_Record_Length = Bytes2Number.Uint2(br);
            _primaryHeader.File_Type_Code       = br.ReadByte();
            if (_primaryHeader.File_Type_Code != 0)
            {
                return;
            }

            _primaryHeader.Total_Header_Length = Bytes2Number.UInt(br.ReadBytes(4));
            _primaryHeader.Data_Field_Length   = Bytes2Number.UInt(br.ReadBytes(8));
            _dataLength = (int)(br.BaseStream.Length - br.BaseStream.Position);

            //Read secondary headers
            while (true)
            {
                headerType = br.ReadByte();
                if (br.BaseStream.Position > _primaryHeader.Total_Header_Length)
                {
                    break;
                }

                if (headerType > 132)
                {
                    break;
                }

                switch (headerType)
                {
                case 1:
                    //Read header type#1 - Image Structure
                    _imageStructure.Header_Type          = headerType;
                    _imageStructure.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2));
                    _imageStructure.NB = br.ReadByte();
                    _imageStructure.NC = Bytes2Number.UInt(br.ReadBytes(2));
                    _imageStructure.NL = Bytes2Number.UInt(br.ReadBytes(2));
                    _imageStructure.Compression_Flag = br.ReadByte();
                    break;

                case 2:
                    //Read header type#2 - Image Navigation
                    _imageNavigation.Header_Type          = headerType;
                    _imageNavigation.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2));
                    _imageNavigation.Projection_Name      = ASCIIEncoding.ASCII.GetString(br.ReadBytes(32)).Trim();
                    _imageNavigation.CFAC = Bytes2Number.Int4(br);
                    _imageNavigation.LFAC = Bytes2Number.Int4(br);
                    _imageNavigation.COFF = Bytes2Number.Int4(br);
                    _imageNavigation.LOFF = Bytes2Number.Int4(br);
                    //_imageNavigation.CFAC = BitConverter.ToInt32(br.ReadBytes(4), 0);
                    //_imageNavigation.LFAC = BitConverter.ToInt32(br.ReadBytes(4), 0);
                    //_imageNavigation.COFF = BitConverter.ToInt32(br.ReadBytes(4), 0);
                    //_imageNavigation.LOFF = BitConverter.ToInt32(br.ReadBytes(4), 0);
                    break;

                case 3:
                    //Read header type#3 - Image Data Function
                    _imageDataFunction.Header_Type           = headerType;
                    _imageDataFunction.Header_Record_Length  = Bytes2Number.UInt(br.ReadBytes(2));
                    _imageDataFunction.Data_Definition_Block = ASCIIEncoding.ASCII.GetString(br.ReadBytes(_imageDataFunction.Header_Record_Length - 3));
                    break;

                case 4:
                    //Read header type#4 - Annotation
                    _annotation.Header_Type          = headerType;
                    _annotation.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2));
                    _annotation.Annotation_Text      = ASCIIEncoding.ASCII.GetString(br.ReadBytes(_annotation.Header_Record_Length - 3));
                    break;

                case 5:
                    //Read header type#5 - Time Stamp
                    _timeStamp.Header_Type          = headerType;
                    _timeStamp.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2));
                    _timeStamp.CDS_P_Field          = br.ReadByte();
                    _timeStamp.CDS_T_Field          = Bytes2Number.UInt(br.ReadBytes(6));
                    break;

                case 128:
                    //Read header type#128 - Image Segment Identification
                    _imageSegmentID.Header_Type          = headerType;
                    _imageSegmentID.Header_Record_Length = Bytes2Number.UInt(br.ReadBytes(2));
                    _imageSegmentID.Image_Segm_Seq_No    = br.ReadByte();
                    _imageSegmentID.Total_No_Image_Segm  = br.ReadByte();
                    _imageSegmentID.Line_No_Image_Segm   = Bytes2Number.UInt(br.ReadBytes(2));
                    break;

                case 130:        //Read header type#130 - Image compensation information header
                    _imageCompInfo.Header_Type                    = headerType;
                    _imageCompInfo.Header_Record_Length           = Bytes2Number.UInt(br.ReadBytes(2));
                    _imageCompInfo.Image_Compensation_Information = ASCIIEncoding.ASCII.GetString(br.ReadBytes(_imageCompInfo.Header_Record_Length - 3));
                    break;

                case 131:        //Read header type#131 - Image observation time
                    _imageObsTime.Header_Type            = headerType;
                    _imageObsTime.Header_Record_Length   = Bytes2Number.UInt(br.ReadBytes(2));
                    _imageObsTime.Image_Observation_Time = ASCIIEncoding.ASCII.GetString(br.ReadBytes(_imageObsTime.Header_Record_Length - 3));
                    break;

                case 132:        //Read header type#132 - Image quality information
                    _imageQualityInfo.Header_Type               = headerType;
                    _imageQualityInfo.Header_Record_Length      = Bytes2Number.UInt(br.ReadBytes(2));
                    _imageQualityInfo.Image_Quality_Information = ASCIIEncoding.ASCII.GetString(br.ReadBytes(_imageQualityInfo.Header_Record_Length - 3));
                    break;

                default:
                    headerRecordLength = Bytes2Number.UInt(br.ReadBytes(2));
                    br.ReadBytes(headerRecordLength - 3);
                    break;
                }
            }

            //Close file
            br.Close();
            fs.Close();

            //Get projection
            GetProjection(_imageNavigation.Projection_Name);

            int tNL = _imageStructure.NL * _imageSegmentID.Total_No_Image_Segm;

            double[] x      = new double[XNum];
            double[] y      = new double[tNL];
            double   cof    = Math.Pow(2, -16);
            double   CFAC_d = _imageNavigation.CFAC * cof;
            double   LFAC_d = _imageNavigation.LFAC * cof;
            double   radius = 6378137.0;
            int      i;

            for (i = 0; i < XNum; i++)
            {
                x[i] = (double)(i + 1 - _imageNavigation.COFF) / CFAC_d * radius / 10;
            }

            for (i = 0; i < tNL; i++)
            {
                y[i] = (double)(i + 1 - _imageNavigation.LOFF) / LFAC_d * radius / 10;
            }

            Dimension xdim = new Dimension(DimensionType.X);

            xdim.SetValues(x);
            this.XDimension = xdim;
            Dimension ydim = new Dimension(DimensionType.Y);

            ydim.SetValues(y);
            this.YDimension = ydim;

            //Set variable list
            varList = new List <string>();
            varList.Add("var");
            Variable var = new Variable();

            var.Name = "var";
            var.SetDimension(ydim);
            var.SetDimension(xdim);
            List <Variable> variables = new List <Variable>();

            variables.Add(var);
            this.Variables = variables;
        }
        /// <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;
            }
        }