Example #1
0
        private float[] ReadGridPointBySimplePack(int xoffset, int yoffset, int width, int height)
        {
            uint val;

            float[] bufRetDatas;
            float   num;
            float   num2;

            bool[] bitmap;
            byte[] _bufferBytes;
            int    numberOfBits;
            float  referenceValue;

            GetFsValues(out bufRetDatas, out num, out num2, out bitmap, out _bufferBytes, out numberOfBits, out referenceValue);
            if (bitmap == null)
            {
                ReadDataWithoutBitmap(xoffset, yoffset, width, height, bufRetDatas, num, num2, _bufferBytes, numberOfBits, referenceValue);
            }
            else
            {
                ReadDataWithBitmap(xoffset, yoffset, bufRetDatas, num, num2, bitmap, _bufferBytes, numberOfBits, referenceValue);
            }

            int scanMode = _record.GDS.ScanMode;

            ScanModeApplier.ApplyScanMode(scanMode, width, ref bufRetDatas);
            return(bufRetDatas);
        }
Example #2
0
        public float[] Read(int xoffset, int yoffset, int width, int height)
        {
            try
            {
                if (_fileStream == null)
                {
                    return(null);
                }
                if (width > _width | height > _height)
                {
                    return(null);
                }
                if (_isBmsExist)
                {
                    throw new NotSupportedException("不支持BitMapSection存在情况下的数据读取");
                }

                _fileStream.Seek(_dataoffset, SeekOrigin.Begin);
                int sectionBytesLength = GribNumberHelper.Uint3(_fileStream);   //整个区段的字节长度
                int flagsAndUnusedbits = _fileStream.ReadByte();
                if ((flagsAndUnusedbits & 192) != 0)                            //&1100,取前两位,仅支持是flag[0],flag[1]都是0的情况
                {
                    throw new NotSupportedException("BDS: (octet 4, 1st half) not grid point data and simple packing ");
                }
                int unusedbits = flagsAndUnusedbits & 15;                       //&1111,取后四位的数值

                _binScale = GribNumberHelper.Int2(_fileStream);
                _refValue = ComputeReferenceValue(_fileStream); //GribNumberHelper.Float4(_fileStream);

                _numBits = _fileStream.ReadByte();
                if (_numBits == 0)
                {
                    _isConstant = true;
                    return(null);
                }
                float refRenamed = (float)(Math.Pow(10.0, -_decscale) * _refValue);
                float scale      = (float)(Math.Pow(10.0, -_decscale) * Math.Pow(2.0, _binScale));

                //long firstOffset = _fileStream.Position;
                //points = new GRIB_Point[((dataLength - 11) * 8 - unusedbits) / numbits];  //当前情况下,整个数据区域的大小
                var bufRetDatas        = new float[height * width];
                var allDataBytesLength = (int)Math.Ceiling(((sectionBytesLength - 11) * 8 - unusedbits) / 8d); //当前情况下,整个二进制数据所占用的字节数
                int realDataLength     = width * height * _numBits / 8 + 1;
                var bufferBytes        = new byte[allDataBytesLength];                                         //new byte[Math.Max(allDataBytesLength, realDataLength)]; //

                _fileStream.Read(bufferBytes, 0, allDataBytesLength);
                uint val;
                using (BitStream bs = new BitStream(new MemoryStream(bufferBytes)))
                {
                    bs.Position = 0;
                    if (_thinnedGrid)
                    {
                        return(ReadDataWithThinnedValue(sectionBytesLength, unusedbits, refRenamed, scale, width, height, xoffset, yoffset, bs));
                    }

                    for (int j = yoffset; j < yoffset + height; j++)                         //缓存数据,上下调整前的第j行
                    {
                        if (_firstlat < _lastlat)                                            //记录方向为从南到北
                        {
                            bs.Position = ((_height - j - 1) * _width + xoffset) * _numBits; // +bitOffset;
                            for (int i = xoffset; i < xoffset + width; i++)
                            {
                                bs.Read(out val, 0, _numBits);
                                if (_firstlon == 0 && _lastlon > 300) //最大经度超过180在地图上将实际在西半球,经度为大于-180,但日本C数据最大为200°,不再分区域显示,故将界限定为300,影响X区域和Y区域的数据存储
                                {
                                    int halfLon = (int)((_lastlon - _firstlon) / _xresolution);
                                    if (i < halfLon)
                                    {
                                        bufRetDatas[halfLon + i + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6);
                                    }
                                    else
                                    {
                                        bufRetDatas[i - halfLon + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6);
                                    }
                                }
                                else
                                {
                                    bufRetDatas[i + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6);
                                }
                            }
                        }
                        else
                        {
                            if (j == yoffset)
                            {
                                //_fileStream.Seek((_width * yoffset + xoffset) * _numBits / 8, SeekOrigin.Current);  //起始位置字节流向后偏移的位置,(_width*yoffset+xoffset)表示偏移的点个数
                                //numbits表示每个点的数值所占的位数,除以8表示每个点占的字节数,seek(函数以字节为单位)
                                bs.Position += (_width * yoffset + xoffset) * _numBits;
                            }
                            else
                            {
                                //_fileStream.Seek((_width - width) * _numBits / 8, SeekOrigin.Current);
                                bs.Position += (_width - width) * _numBits;
                            }
                            for (int i = xoffset; i < xoffset + width; i++)
                            {
                                bs.Read(out val, 0, _numBits);
                                if (_firstlon == 0 && _lastlon > 300)
                                {
                                    int halfLon = (int)((_lastlon - 180 + _xresolution) / _xresolution);
                                    if (i < halfLon)
                                    {
                                        bufRetDatas[halfLon + i + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6);
                                    }
                                    else
                                    {
                                        bufRetDatas[i - halfLon + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6);
                                    }
                                }
                                else
                                {
                                    bufRetDatas[i + width * (j - yoffset)] = (float)Math.Round(refRenamed + scale * val, 6);
                                }
                            }
                        }
                    }
                }
                ScanModeApplier.ApplyScanMode(_scanMode, width, ref bufRetDatas);
                //if (_thinnedGrid)
                //{
                //    return ReadDataWithThinnedValue(bufRetDatas, width, height);
                //}
                return(bufRetDatas);
            }
            finally
            {
                _fileStream.Seek(0, SeekOrigin.Begin);
            }
        }
Example #3
0
        private float[] ReadGridPointByComplexPack(int xOffset, int yOffset, int width, int height)
        {
            int   mvm = _record.DRS.MissingValueManagement;
            float pmv = _record.DRS.PrimaryMissingValue;
            int   NG  = _record.DRS.NumberOfGroups;

            // 6-xx  Get reference values for groups (X1's)
            int[] X1 = new int[NG];
            int   nb = _record.DRS.NumberOfBits;

            _bitPos = 0;
            _bitBuf = 0;
            for (int i = 0; i < NG; i++)
            {
                X1[i] = Bits2UInt(nb, _fs);
            }
            // [xx +1 ]-yy Get number of bits used to encode each group
            int[] NB = new int[NG];
            nb      = _record.DRS.BitsGroupWidths;
            _bitPos = 0;
            _bitBuf = 0;
            for (int i = 0; i < NG; i++)
            {
                NB[i] = Bits2UInt(nb, _fs);
            }
            // [yy +1 ]-zz Get the scaled group lengths using formula
            //     Ln = ref + Kn * len_inc, where n = 1-NG,
            //          ref = referenceGroupLength, and  len_inc = lengthIncrement
            int[] L           = new int[NG];
            int   countL      = 0;
            int   ref_Renamed = _record.DRS.ReferenceGroupLength;
            int   len_inc     = _record.DRS.LengthIncrement;

            nb      = _record.DRS.BitsScaledGroupLength;
            _bitPos = 0;
            _bitBuf = 0;
            for (int i = 0; i < NG; i++)
            {
                // NG
                L[i]    = ref_Renamed + (Bits2UInt(nb, _fs) * len_inc);
                countL += L[i];
            }
            // [zz +1 ]-nn get X2 values and calculate the results Y using formula
            //                Y * 10**D = R + (X1 + X2) * 2**E

            int   D  = _record.DRS.DecimalScaleFactor;
            float DD = (float)System.Math.Pow((double)10, (double)D);
            float R  = _record.DRS.ReferenceValue;
            int   E  = _record.DRS.BinaryScaleFactor;
            float EE = (float)System.Math.Pow((double)2.0, (double)E);

            float[] data  = new float[countL];
            int     count = 0;

            int[] bitsmv1 = new int[31];
            for (int i = 0; i < 31; i++)
            {
                bitsmv1[i] = (int)System.Math.Pow((double)2, (double)i) - 1;
            }
            int X2;

            _bitPos = 0;
            _bitBuf = 0;
            for (int i = 0; i < NG - 1; i++)
            {
                for (int j = 0; j < L[i]; j++)
                {
                    if (NB[i] == 0)
                    {
                        if (mvm == 0)
                        {
                            // X2 = 0
                            data[count++] = (R + X1[i] * EE) / DD;
                        }
                        else if (mvm == 1)
                        {
                            data[count++] = pmv;
                        }
                    }
                    else
                    {
                        X2 = Bits2UInt(NB[i], _fs);
                        if (mvm == 0)
                        {
                            data[count++] = (R + (X1[i] + X2) * EE) / DD;
                        }
                        else if (mvm == 1)
                        {
                            // X2 is also set to missing value is all bits set to 1's
                            if (X2 == bitsmv1[NB[i]])
                            {
                                data[count++] = pmv;
                            }
                            else
                            {
                                data[count++] = (R + (X1[i] + X2) * EE) / DD;
                            }
                        }
                    }
                }
            }
            // process last group
            int last = _record.DRS.LengthLastGroup;

            for (int j = 0; j < last; j++)
            {
                // last group
                if (NB[NG - 1] == 0)
                {
                    if (mvm == 0)
                    {
                        // X2 = 0
                        data[count++] = (R + X1[NG - 1] * EE) / DD;
                    }
                    else if (mvm == 1)
                    {
                        data[count++] = pmv;
                    }
                }
                else
                {
                    X2 = Bits2UInt(NB[NG - 1], _fs);
                    if (mvm == 0)
                    {
                        data[count++] = (R + (X1[NG - 1] + X2) * EE) / DD;
                    }
                    else if (mvm == 1)
                    {
                        // X2 is also set to missing value is all bits set to 1's
                        if (X2 == bitsmv1[NB[NG - 1]])
                        {
                            data[count++] = pmv;
                        }
                        else
                        {
                            data[count++] = (R + (X1[NG - 1] + X2) * EE) / DD;
                        }
                    }
                }
            } // end for j
            int scanMode = _record.GDS.ScanMode;

            ScanModeApplier.ApplyScanMode(scanMode, width, ref data);
            return(data);
        }
Example #4
0
        private float[] ReadGridPointByComplexPackAndSpatial(int xOffset, int yOffset, int width, int height)
        {
            int   mvm = _record.DRS.MissingValueManagement;
            float pmv = _record.DRS.PrimaryMissingValue;
            int   NG = _record.DRS.NumberOfGroups;
            int   g1 = 0, gMin = 0, h1 = 0, h2 = 0, hMin = 0;
            // [6-ww]   1st values of undifferenced scaled values and minimums
            int os = _record.DRS.OrderSpatial;
            int ds = _record.DRS.DescriptorSpatial;

            _bitPos = 0; _bitBuf = 0;
            int sign;

            // ds is number of bytes, convert to bits -1 for sign bit
            ds = ds * 8 - 1;
            if (os == 1)
            {
                // first order spatial differencing g1 and gMin
                sign = Bits2UInt(1, _fs);
                g1   = Bits2UInt(ds, _fs);
                if (sign == 1)
                {
                    g1 *= (-1);
                }
                sign = Bits2UInt(1, _fs);
                gMin = Bits2UInt(ds, _fs);
                if (sign == 1)
                {
                    gMin *= (-1);
                }
            }
            else if (os == 2)
            {
                //second order spatial differencing h1, h2, hMin
                sign = Bits2UInt(1, _fs);
                h1   = Bits2UInt(ds, _fs);
                if (sign == 1)
                {
                    h1 *= (-1);
                }
                sign = Bits2UInt(1, _fs);
                h2   = Bits2UInt(ds, _fs);
                if (sign == 1)
                {
                    h2 *= (-1);
                }
                sign = Bits2UInt(1, _fs);
                hMin = Bits2UInt(ds, _fs);
                if (sign == 1)
                {
                    hMin *= (-1);
                }
            }
            else
            {
                return(null);
            }
            // [ww +1]-xx  Get reference values for groups (X1's)
            int[] X1 = new int[NG];
            int   nb = _record.DRS.NumberOfBits;

            _bitPos = 0;
            _bitBuf = 0;
            for (int i = 0; i < NG; i++)
            {
                X1[i] = Bits2UInt(nb, _fs);
            }
            // [xx +1 ]-yy Get number of bits used to encode each group
            int[] NB = new int[NG];
            nb      = _record.DRS.BitsGroupWidths;
            _bitPos = 0;
            _bitBuf = 0;
            for (int i = 0; i < NG; i++)
            {
                NB[i] = Bits2UInt(nb, _fs);
            }
            // [yy +1 ]-zz Get the scaled group lengths using formula
            //     Ln = ref + Kn * len_inc, where n = 1-NG,
            //          ref = referenceGroupLength, and  len_inc = lengthIncrement
            int[] L           = new int[NG];
            int   countL      = 0;
            int   ref_Renamed = _record.DRS.ReferenceGroupLength;
            int   len_inc     = _record.DRS.LengthIncrement;

            nb      = _record.DRS.BitsScaledGroupLength;
            _bitPos = 0;
            _bitBuf = 0;
            for (int i = 0; i < NG; i++)
            {
                // NG
                L[i]    = ref_Renamed + (Bits2UInt(nb, _fs) * len_inc);
                countL += L[i];
            }
            // [zz +1 ]-nn get X2 values and add X1[ i ] + X2
            float[] data = new float[countL];
            // used to check missing values when X2 is packed with all 1's
            int[] bitsmv1 = new int[31];
            for (int i = 0; i < 31; i++)
            {
                bitsmv1[i] = (int)System.Math.Pow((double)2, (double)i) - 1;
            }
            int count = 0;
            int X2;

            _bitPos = 0;
            _bitBuf = 0;
            for (int i = 0; i < NG - 1; i++)
            {
                for (int j = 0; j < L[i]; j++)
                {
                    if (NB[i] == 0)
                    {
                        if (mvm == 0)
                        {
                            // X2 = 0
                            data[count++] = X1[i];
                        }
                        else if (mvm == 1)
                        {
                            data[count++] = pmv;
                        }
                    }
                    else
                    {
                        X2 = Bits2UInt(NB[i], _fs);
                        if (mvm == 0)
                        {
                            data[count++] = X1[i] + X2;
                        }
                        else if (mvm == 1)
                        {
                            // X2 is also set to missing value is all bits set to 1's
                            if (X2 == bitsmv1[NB[i]])
                            {
                                data[count++] = pmv;
                            }
                            else
                            {
                                data[count++] = X1[i] + X2;
                            }
                        }
                    }
                }
            }
            // process last group
            int last = _record.DRS.LengthLastGroup;

            for (int j = 0; j < last; j++)
            {
                // last group
                if (NB[NG - 1] == 0)
                {
                    if (mvm == 0)
                    {
                        // X2 = 0
                        data[count++] = X1[NG - 1];
                    }
                    else if (mvm == 1)
                    {
                        data[count++] = pmv;
                    }
                }
                else
                {
                    X2 = Bits2UInt(NB[NG - 1], _fs);
                    if (mvm == 0)
                    {
                        data[count++] = X1[NG - 1] + X2;
                    }
                    else if (mvm == 1)
                    {
                        // X2 is also set to missing value is all bits set to 1's
                        if (X2 == bitsmv1[NB[NG - 1]])
                        {
                            data[count++] = pmv;
                        }
                        else
                        {
                            data[count++] = X1[NG - 1] + X2;
                        }
                    }
                }
            }
            if (os == 1)
            {
                // g1 and gMin this coding is a sort of guess, no doc
                float sum = 0;
                if (mvm == 0)
                {
                    // no missing values
                    for (int i = 1; i < data.Length; i++)
                    {
                        data[i] += gMin; // add minimum back
                    }
                    data[0] = g1;
                    for (int i = 1; i < data.Length; i++)
                    {
                        sum    += data[i];
                        data[i] = data[i - 1] + sum;
                    }
                }
                else
                {
                    // contains missing values
                    float lastOne = pmv;
                    // add the minimum back and set g1
                    int idx = 0;
                    for (int i = 0; i < data.Length; i++)
                    {
                        if (data[i] != pmv)
                        {
                            if (idx == 0)
                            {
                                // set g1
                                data[i] = g1;
                                lastOne = data[i];
                                idx     = i + 1;
                            }
                            else
                            {
                                data[i] += gMin;
                            }
                        }
                    }
                    if (lastOne == pmv)
                    {
                        return(data);
                    }
                    for (int i = idx; i < data.Length; i++)
                    {
                        if (data[i] != pmv)
                        {
                            sum    += data[i];
                            data[i] = lastOne + sum;
                            lastOne = data[i];
                        }
                    }
                }
            }
            else if (os == 2)
            {
                //h1, h2, hMin
                float hDiff = h2 - h1;
                float sum   = 0;
                if (mvm == 0)
                {
                    // no missing values
                    for (int i = 2; i < data.Length; i++)
                    {
                        data[i] += hMin; // add minimum back
                    }
                    data[0] = h1;
                    data[1] = h2;
                    sum     = hDiff;
                    for (int i = 2; i < data.Length; i++)
                    {
                        sum    += data[i];
                        data[i] = data[i - 1] + sum;
                    }
                }
                else
                {
                    // contains missing values
                    int   idx     = 0;
                    float lastOne = pmv;
                    // add the minimum back and set h1 and h2
                    for (int i = 0; i < data.Length; i++)
                    {
                        if (data[i] != pmv)
                        {
                            if (idx == 0)
                            {
                                // set h1
                                data[i] = h1;
                                sum     = 0;
                                lastOne = data[i];
                                idx++;
                            }
                            else if (idx == 1)
                            {
                                // set h2
                                data[i] = h1 + hDiff;
                                sum     = hDiff;
                                lastOne = data[i];
                                idx     = i + 1;
                            }
                            else
                            {
                                data[i] += hMin;
                            }
                        }
                    }
                    if (lastOne == pmv)
                    {
                        return(data);
                    }
                    for (int i = idx; i < data.Length; i++)
                    {
                        if (data[i] != pmv)
                        {
                            sum    += data[i];
                            data[i] = lastOne + sum;
                            lastOne = data[i];
                        }
                    }
                }
            } // end h1, h2, hMin
            // formula used to create values,  Y * 10**D = R + (X1 + X2) * 2**E
            int   D  = _record.DRS.DecimalScaleFactor;
            float DD = (float)System.Math.Pow((double)10, (double)D);
            float R  = _record.DRS.ReferenceValue;
            int   E  = _record.DRS.BinaryScaleFactor;
            float EE = (float)System.Math.Pow((double)2.0, (double)E);

            if (mvm == 0)
            {
                // no missing values
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = (R + data[i] * EE) / DD;
                }
            }
            else
            {
                // missing value == 1
                for (int i = 0; i < data.Length; i++)
                {
                    if (data[i] != pmv)
                    {
                        data[i] = (R + data[i] * EE) / DD;
                    }
                }
            }
            int scanMode = _record.GDS.ScanMode;

            ScanModeApplier.ApplyScanMode(scanMode, width, ref data);
            return(data);
        }