public unsafe void StatMinMax(GRIB_Point[] pts, out GRIB_Point minPoint, out GRIB_Point maxPoint)
        {
            minPoint = new GRIB_Point();
            maxPoint = new GRIB_Point();
            if (pts == null || pts.Length == 0)
            {
                return;
            }
            minPoint.Value = float.MaxValue;
            maxPoint.Value = float.MinValue;
            float invalidValue = _definition.InvalidValue;

            fixed(GRIB_Point *ptr0 = pts)
            {
                GRIB_Point *ptr = ptr0;
                int         n   = pts.Length;

                if (float.IsNaN(invalidValue))
                {
                    for (int i = 0; i < n; i++, ptr++)
                    {
                        if (ptr->Value < minPoint.Value)
                        {
                            minPoint.Value = ptr->Value;
                            minPoint.Index = ptr->Index;
                        }
                        if (ptr->Value > maxPoint.Value)
                        {
                            maxPoint.Value = ptr->Value;
                            maxPoint.Index = ptr->Index;
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < n; i++, ptr++)
                    {
                        if (Math.Abs(ptr->Value - invalidValue) < float.Epsilon)
                        {
                            continue;
                        }
                        if (ptr->Value < minPoint.Value)
                        {
                            minPoint.Value = ptr->Value;
                            minPoint.Index = ptr->Index;
                        }
                        if (ptr->Value > maxPoint.Value)
                        {
                            maxPoint.Value = ptr->Value;
                            maxPoint.Index = ptr->Index;
                        }
                    }
                }
            }
        }
        public unsafe GRIB_Point[] Read()
        {
            try
            {
                string[]     parts;
                char[]       SPLIT_CHARS = new char[] { ' ' };
                GRIB_Point[] pts         = new GRIB_Point[_definition.Width * _definition.Height];
                int          deepIdx     = Array.IndexOf(_deepValues, _currentDeepValue) + 1;
                int          featureIdx  = Array.IndexOf(_featureNames, _currentFeatureName) + 1; //skip deep column
                //只有水深为“0”的层才有"海流海面高度"
                if (_currentDeepValue != "0" && _currentFeatureName == "海流海面高度")
                {
                    return(pts);
                }
                int    step       = LAYER_COUNT + 1;
                int    firstPixel = deepIdx;
                string line       = null;
                int    rowIdx     = 0;
                float  v          = 0;
                int    pixelIdx   = 0;
                fixed(GRIB_Point *ptr0 = pts)
                {
                    GRIB_Point *ptr = ptr0;

                    while (!_stReader.EndOfStream)
                    {
                        while (deepIdx > 0)
                        {
                            _stReader.ReadLine();
                            deepIdx--;
                        }
                        line = _stReader.ReadLine();
                        if (rowIdx % step == 0)
                        {
                            parts = line.Split(SPLIT_CHARS, StringSplitOptions.RemoveEmptyEntries);
                            float.TryParse(parts[featureIdx], out v);
                            ptr->Value = v;
                            ptr->Index = pixelIdx;
                            ptr++;
                            pixelIdx++;
                        }
                        rowIdx++;
                    }
                }
                return(pts);
            }
            finally
            {
                _fs.Seek(0, SeekOrigin.Begin);
            }
        }