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); }
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); } }
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); }
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); }