// *** constructors *******************************************************

        /// <summary> Constructs a <tt>Grib1ProductDefinitionSection</tt> object from a raf.
        ///
        /// </summary>
        /// <param name="raf">with PDS content
        ///
        /// </param>
        /// <throws>  NotSupportedException  if raf contains no valid GRIB file </throws>
        //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'"
        internal Grib1ProductDefinitionSection(System.IO.Stream raf)
        {
            // octets 1-3 PDS length
            length = (int)GribNumbers.uint3(raf);


            // Paramter table octet 4
            table_version = raf.ReadByte();

            // Center  octet 5
            center_id = raf.ReadByte();

            // octet 6 Generating Process - See Table A
            process_id = raf.ReadByte();

            // octet 7 (id of grid type) - not supported yet
            grid_id = raf.ReadByte();

            //octet 8 (flag for presence of GDS and BMS)
            int exists = raf.ReadByte();

            //BKSystem.IO.BitStream s = new BKSystem.IO.BitStream(8);
//            s.WriteByte((byte)raf.ReadByte());
//            s.Position = 0;
//            sbyte exists;
//            s.Read(out exists);
//            bms_exists = (exists & 64) == 64;

            gds_exists = (exists & 128) == 128;
            bms_exists = (exists & 64) == 64;

            // octet 9 (parameter and unit)
            parameterNumber = raf.ReadByte();

            // octets 10-12 (level)
            int levelType   = raf.ReadByte();
            int levelValue1 = raf.ReadByte();
            int levelValue2 = raf.ReadByte();

            level = new GribPDSLevel(levelType, levelValue1, levelValue2);

            // octets 13-17 (base time for reference time)
            int year   = raf.ReadByte();
            int month  = raf.ReadByte();
            int day    = raf.ReadByte();
            int hour   = raf.ReadByte();
            int minute = raf.ReadByte();

            // get info for forecast time
            // octet 18 Forecast time unit
            timeUnit = raf.ReadByte();

            switch (timeUnit)
            {
            case 0:                     // minute
                tUnit = "minute";
                break;

            case 1:                     // hours
                tUnit = "hour";
                break;

            case 2:                     // day
                tUnit = "day";
                break;

            case 3:                     // month
                tUnit = "month";
                break;

            case 4:                     //1 year
                tUnit = "1year";
                break;

            case 5:                     // decade
                tUnit = "decade";
                break;

            case 6:                     // normal
                tUnit = "day";
                break;

            case 7:                     // century
                tUnit = "century";
                break;

            case 10:                     //3 hours
                tUnit = "3hours";
                break;

            case 11:                     // 6 hours
                tUnit = "6hours";
                break;

            case 12:                     // 12 hours
                tUnit = "12hours";
                break;

            case 254:                     // second
                tUnit = "second";
                break;


            default:
                Console.Error.WriteLine("PDS: Time Unit " + timeUnit + " is not yet supported");
                break;
            }

            // octet 19 & 20 used to create Forecast time
            p1 = raf.ReadByte();
            p2 = raf.ReadByte();

            // octet 21 (time range indicator)
            timeRangeValue = raf.ReadByte();
            // forecast time is always at the end of the range

            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 = p1 = GribNumbers.int2(p1, p2);
                p2           = 0;
                break;

            case 51:
                timeRange    = "mean value from RT to (RT + P2)";
                forecastTime = p2;
                break;

            default:
                Console.Error.WriteLine("PDS: Time Range Indicator " + timeRangeValue + " is not yet supported");
                break;
            }

            // octet 22 & 23
            int avgInclude = GribNumbers.int2(raf);

            // octet 24
            int avgMissing = raf.ReadByte();

            // octet 25
            int century = raf.ReadByte() - 1;

            // octet 26, sub center
            subcenter_id = raf.ReadByte();

            // octets 27-28 (decimal scale factor)
            decscale = GribNumbers.int2(raf);

            refTime       = new DateTime(century * 100 + year, month, day, hour, minute, 0, DateTimeKind.Utc);
            baseTime      = refTime;
            referenceTime = refTime.ToString(dateFormat);


            //(century * 100 + year) +"-" +
            //month + "-" + day + "T" + hour +":" + minute +":00Z" );


            // TODO

            /*
             * parameter_table = GribPDSParamTable.getParameterTable(center_id, subcenter_id, table_version);
             * parameter = parameter_table.getParameter(parameterNumber);
             */
            parameter = new Parameter();


            if (center_id == 7 && subcenter_id == 2)
            {
                CustomData = new int[0];

                // ensemble product
                epds = new Grib1Ensemble(raf, parameterNumber);
            }
            // Special handling of 2D Wave Spectra (single)
            else if (table_version == 140 && parameterNumber == 251)
            {
                CustomData = new int[0];

                SupportClass.Skip(raf, 12);
                int extDef = raf.ReadByte();                 // Extension definition

                // Read ECMWF extension for 2D wave spectra single
                if (extDef == 13)
                {
                    waveSpectra2DDirFreq = new Grib1WaveSpectra2DDirFreq(raf);
                }
            }
            else
            {
                // Ignore reserved bytes 29-40
                for (int i = 29; i <= Math.Min(length, 40); i++)
                {
                    raf.ReadByte();
                }

                // Try to read extra bytes
                CustomData = new int[Math.Max(length - 40, 0)];
                for (int i = 0; i < CustomData.Length; i++)
                {
                    CustomData[i] = raf.ReadByte();
                }
            }
        }         // end Grib1ProductDefinitionSection
Esempio n. 2
0
        /// <summary> Constructs a Grib1BinaryDataSection object from a raf.
        /// A bit map is defined.
        ///
        /// </summary>
        /// <param name="raf">raf with BDS content
        /// </param>
        /// <param name="decimalscale">the exponent of the decimal scale
        /// </param>
        /// <param name="bms">bit map section of GRIB record
        ///
        /// </param>
        /// <throws>  NotSupportedException  if stream contains no valid GRIB file </throws>
        //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'"
        internal Grib1BinaryDataSection(System.IO.Stream raf, int decimalscale, Grib1BitMapSection bms)
        {
            // octets 1-3 (section length)
            length = (int)GribNumbers.uint3(raf);


            // octet 4, 1st half (packing flag)
            int unusedbits = raf.ReadByte();

            // TODO Check this!!!
            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 = GribNumbers.int2(raf);

            // octets 7-10 (reference point = minimum value)
            float refvalue = GribNumbers.float4(raf);

            // octet 11 (number of bits per value)
            int numbits = raf.ReadByte();

            if (numbits == 0)
            {
                isConstant = true;
            }


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

            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float ref_Renamed = (float)(Math.Pow(10.0, -decimalscale) * refvalue);
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float scale = (float)(Math.Pow(10.0, -decimalscale) * Math.Pow(2.0, binscale));

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

                Values = new float[bitmap.Length];
                for (int i = 0; i < bitmap.Length; i++)
                {
                    if (bitmap[i])
                    {
                        if (!isConstant)
                        {
                            Values[i] = ref_Renamed + scale * bits2UInt(numbits, raf);
                        }
                        else
                        {
                            // rdg - added this to handle a constant valued parameter
                            Values[i] = ref_Renamed;
                        }
                    }
                    else
                    {
                        Values[i] = MissingValue;
                    }
                }
            }
            else
            {
                // bms is null
                if (!isConstant)
                {
                    //(((length - 11) * 8 - unusedbits) /  numbits));
                    Values = new float[((length - 11) * 8 - unusedbits) / numbits];

                    for (int i = 0; i < Values.Length; i++)
                    {
                        Values[i] = ref_Renamed + scale * bits2UInt(numbits, raf);
                    }
                }
                else
                {
                    // constant valued - same min and max
                    int x = 0, y = 0;
                    raf.Seek(raf.Position - 53, System.IO.SeekOrigin.Begin);                     // return to start of GDS
                    length = (int)GribNumbers.uint3(raf);
                    if (length == 42)
                    {
                        // Lambert/Mercator offset
                        SupportClass.Skip(raf, 3);
                        x = GribNumbers.int2(raf);
                        y = GribNumbers.int2(raf);
                    }
                    else
                    {
                        SupportClass.Skip(raf, 7);
                        length = (int)GribNumbers.uint3(raf);
                        if (length == 32)
                        {
                            // Polar sterographic
                            SupportClass.Skip(raf, 3);
                            x = GribNumbers.int2(raf);
                            y = GribNumbers.int2(raf);
                        }
                        else
                        {
                            x = y = 1;
                            Console.Out.WriteLine("BDS constant value, can't determine array size");
                        }
                    }

                    Values = new float[x * y];
                    for (int i = 0; i < Values.Length; i++)
                    {
                        Values[i] = ref_Renamed;
                    }
                }
            }
        }         // end Grib1BinaryDataSection
        /// <summary> Constructs a <tt>Grib1GridDefinitionSection</tt> object from a raf.
        ///
        /// </summary>
        /// <param name="raf">RandomAccessFile with GDS content
        ///
        /// </param>
        /// <throws>  NoValidGribException  if raf contains no valid GRIB info </throws>
        //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'"
        internal Grib1GridDefinitionSection(System.IO.Stream raf)
        {
            int reserved;             // used to read empty space

            // octets 1-3 (Length of GDS)
            length = (int)GribNumbers.uint3(raf);
            if (length == 0)
            {
                // there's a extra byte between PDS and GDS
                SupportClass.Skip(raf, -2);
                length = (int)GribNumbers.uint3(raf);
            }


            // TODO Fix Checksum stuff
            // get byte array for this gds, then reset raf to same position
            // calculate checksum for this gds via the byte array

            /*
             * long mark = raf.Position;
             * sbyte[] dst = new sbyte[length - 3];
             * SupportClass.ReadInput(raf, dst, 0, dst.Length);
             * raf.Seek(mark, System.IO.SeekOrigin.Begin);
             * //UPGRADE_ISSUE: Class 'java.util.zip.CRC32' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javautilzipCRC32'"
             * //UPGRADE_ISSUE: Constructor 'java.util.zip.CRC32.CRC32' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javautilzipCRC32'"
             * CRC32 cs = new CRC32();
             * //UPGRADE_ISSUE: Method 'java.util.zip.CRC32.update' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javautilzipCRC32'"
             * cs.update(dst);
             * //UPGRADE_ISSUE: Method 'java.util.zip.CRC32.getValue' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javautilzipCRC32'"
             * checksum = System.Convert.ToString(cs.getValue());
             *
             */

            // octets 4 NV
            int NV = raf.ReadByte();


            // octet 5 PL the location (octet number) of the list of numbers of points in each row
            P_VorL = raf.ReadByte();


            // octet 6 (grid type)
            type = raf.ReadByte();

            name = getName(type);

            if (type != 50)
            {
                // values same up to resolution

                // octets 7-8 (Nx - number of points along x-axis)
                nx = GribNumbers.int2(raf);
                nx = (nx == -1) ? 1 : nx;

                // octets 9-10 (Ny - number of points along y-axis)
                ny = GribNumbers.int2(raf);
                ny = (ny == -1) ? 1 : ny;

                // octets 11-13 (La1 - latitude of first grid point)
                lat1 = GribNumbers.int3(raf) / 1000.0;

                // octets 14-16 (Lo1 - longitude of first grid point)
                lon1 = GribNumbers.int3(raf) / 1000.0;

                // octet 17 (resolution and component flags).  See Table 7
                resolution = raf.ReadByte();
            }

            switch (type)
            {
            //  Latitude/Longitude  grids ,  Arakawa semi-staggered e-grid rotated
            //  Arakawa filled e-grid rotated
            case 0:
            case 4:
            case 40:
            case 201:
            case 202:

                // octets 18-20 (La2 - latitude of last grid point)
                lat2 = GribNumbers.int3(raf) / 1000.0;

                // octets 21-23 (Lo2 - longitude of last grid point)
                lon2 = GribNumbers.int3(raf) / 1000.0;

                // octets 24-25 (Dx - Longitudinal Direction Increment )
                dx = GribNumbers.int2(raf) / 1000.0;

                // octets 26-27 (Dy - Latitudinal Direction Increment )
                //               Np - parallels between a pole and the equator
                if (type == 4)
                {
                    np = GribNumbers.int2(raf);
                }
                else
                {
                    dy = GribNumbers.int2(raf) / 1000.0;
                }

                // octet 28 (Scanning mode)  See Table 8
                scan = raf.ReadByte();

                // octet 29-32 reserved
                reserved = GribNumbers.int4(raf);

                if (length > 32)
                {
                    // getP_VorL(raf);
                    // Vertical coordinates (NV) and thinned grids (PL) not supported - skip this
                    SupportClass.Skip(raf, length - 32);
                }

                break;                         // end Latitude/Longitude grids


            case 1:                     //  Mercator grids

                // octets 18-20 (La2 - latitude of last grid point)
                lat2 = GribNumbers.int3(raf) / 1000.0;

                // octets 21-23 (Lo2 - longitude of last grid point)
                lon2 = GribNumbers.int3(raf) / 1000.0;

                // octets 24-26 (Latin - latitude where cylinder intersects the earth
                latin1 = GribNumbers.int3(raf) / 1000.0;

                // octet 27 reserved
                reserved = raf.ReadByte();

                // octet 28 (Scanning mode)  See Table 8
                scan = raf.ReadByte();

                // octets 29-31 (Dx - Longitudinal Direction Increment )
                dx = GribNumbers.int3(raf);

                // octets 32-34 (Dx - Longitudinal Direction Increment )
                dy = GribNumbers.int3(raf);

                // octet 35-42 reserved
                reserved = GribNumbers.int4(raf);
                reserved = GribNumbers.int4(raf);

                if (length > 42)
                {
                    // getP_VorL(raf);
                    // Vertical coordinates (NV) and thinned grids (PL) not supported - skip this
                    SupportClass.Skip(raf, length - 42);
                }

                break;                         // end Mercator grids


            case 3:                     // Lambert Conformal

                // octets 18-20 (Lov - Orientation of the grid - east lon parallel to y axis)
                lov = GribNumbers.int3(raf) / 1000.0;

                // octets 21-23 (Dx - the X-direction grid length) See Note 2 of Table D
                dx = GribNumbers.int3(raf);

                // octets 24-26 (Dy - the Y-direction grid length) See Note 2 of Table D
                dy = GribNumbers.int3(raf);

                // octets 27 (Projection Center flag) See Note 5 of Table D
                proj_center = raf.ReadByte();

                // octet 28 (Scanning mode)  See Table 8
                scan = raf.ReadByte();

                // octets 29-31 (Latin1 - first lat where secant cone cuts spherical earth
                latin1 = GribNumbers.int3(raf) / 1000.0;

                // octets 32-34 (Latin2 - second lat where secant cone cuts spherical earth)
                latin2 = GribNumbers.int3(raf) / 1000.0;

                // octets 35-37 (lat of southern pole)
                latsp = GribNumbers.int3(raf) / 1000.0;

                // octets 38-40 (lon of southern pole)
                lonsp = GribNumbers.int3(raf) / 1000.0;

                // octets 41-42
                reserved = GribNumbers.int2(raf);

                if (length > 42)
                {
                    // getP_VorL(raf);
                    // Vertical coordinates (NV) and thinned grids (PL) not supported - skip this
                    SupportClass.Skip(raf, length - 42);
                }

                break;                         // end Lambert Conformal


            case 5:                     //  Polar Stereographic grids

                // octets 18-20 (Lov - Orientation of the grid - east lon parallel to y axis)
                lov = GribNumbers.int3(raf) / 1000.0;

                // octets 21-23 (Dx - Longitudinal Direction Increment )
                dx = GribNumbers.int3(raf);

                // octets 24-26(Dy - Latitudinal Direction Increment )
                dy = GribNumbers.int3(raf);

                // octets 27 (Projection Center flag) See Note 5 of Table D
                proj_center = raf.ReadByte();

                // octet 28 (Scanning mode)  See Table 8
                scan = raf.ReadByte();

                // octet 29-32 reserved
                reserved = GribNumbers.int4(raf);

                if (length > 32)
                {
                    // getP_VorL(raf);
                    // Vertical coordinates (NV) and thinned grids (PL) not supported - skip this
                    SupportClass.Skip(raf, length - 32);
                }

                break;                         // end Polar Stereographic grids


            default:
                Console.Out.WriteLine("Unknown Grid Type : " + type);
                break;
            }             // end switch grid_type


            if ((scan & 63) != 0)
            {
                throw new BadGribFormatException("GDS: This scanning mode (" + scan + ") is not supported.");
            }
        }         // end Grib1GridDefinitionSection( raf )