예제 #1
0
        public bool ComputeBeginEndRowCol(AbstractWarpDataset args, AbstractWarpDataset dstArgs, Size targetSize, ref int oBeginRow, ref int oBeginCol, ref int oEndRow, ref int oEndCol, ref int tBeginRow, ref int tBeginCol, ref int tEndRow, ref int tEndCol)
        {
            Envelope targetEnvelope = dstArgs.GetEnvelope();
            Geometry targetGeo      = targetEnvelope.GetGeometry();
            Geometry argGeo         = args.GetEnvelope().GetGeometry();

            Geometry innerEnvelopeGeo = targetGeo.Intersection(argGeo);

            if (innerEnvelopeGeo == null)
            {
                return(false);
            }
            double   tResolutionX = dstArgs.ResolutionX;
            double   tResolutionY = dstArgs.ResolutionY;
            double   oResolutionX = args.ResolutionX;
            double   oResolutionY = args.ResolutionY;
            Envelope oEnvelope    = args.GetEnvelope();

            //
            if (oEnvelope.MinX >= targetEnvelope.MinX)//左边界在目标图像内部
            {
                oBeginCol = 0;
                tBeginCol = (int)((oEnvelope.MinX - targetEnvelope.MinX) / tResolutionX + _errorValue);
            }
            else//左边界在目标图像外部
            {
                oBeginCol = (int)((targetEnvelope.MinX - oEnvelope.MinX) / oResolutionX + _errorValue);
                tBeginCol = 0;
            }
            if (oEnvelope.MaxX >= targetEnvelope.MaxX)//右边界在目标图像外部
            {
                oEndCol = (int)((targetEnvelope.MaxX - oEnvelope.MinX) / oResolutionX + _errorValue);
                tEndCol = targetSize.Width;
            }
            else//右边界在目标图像内部
            {
                oEndCol = (int)((args.GetEnvelope().MaxX - args.GetEnvelope().MinX) / oResolutionX + _errorValue);
                tEndCol = (int)((oEnvelope.MaxX - targetEnvelope.MinX) / tResolutionX + _errorValue);
            }
            if (oEnvelope.MaxY <= targetEnvelope.MaxY)//上边界在目标图像内部
            {
                oBeginRow = 0;
                tBeginRow = (int)((targetEnvelope.MaxY - oEnvelope.MaxY) / tResolutionY + _errorValue);
            }
            else//上边界在目标边界外部
            {
                oBeginRow = (int)((oEnvelope.MaxY - targetEnvelope.MaxY) / oResolutionY + _errorValue);
                tBeginRow = 0;
            }
            if (oEnvelope.MinY <= targetEnvelope.MinY)//下边界在目标图像外部
            {
                oEndRow = (int)((oEnvelope.MaxY - targetEnvelope.MinY) / oResolutionY + _errorValue);
                tEndRow = targetSize.Height;
            }
            else//下边界在目标图像内部
            {
                oEndRow = args.Height;
                tEndRow = (int)((targetEnvelope.MaxY - oEnvelope.MinY) / tResolutionY + _errorValue);
            }
            ////以下添加对偏移计算的纠正,取最小行列数。
            //int oWidth = oEndCol - oBeginCol;
            //int oHeight = oEndRow - oBeginRow;
            //int tWidth = tEndCol - tBeginCol;
            //int tHeight = tEndRow - tBeginRow;
            //oWidth = tWidth = Math.Min(oWidth, tWidth);
            //oHeight = tHeight = Math.Min(oHeight, tHeight);
            //oEndRow = oBeginRow + oHeight;
            //oEndCol = oBeginCol + oWidth;
            //tEndRow = tBeginRow + tHeight;
            //tEndCol = tBeginCol + tWidth;
            return(true);
        }
예제 #2
0
        /// <summary>
        /// 支持不同分辨率的拼接
        /// </summary>
        /// <param name="args"></param>
        /// <param name="dstArgs"></param>
        /// <param name="tSize"></param>
        /// <param name="oBeginRow"></param>
        /// <param name="oBeginCol"></param>
        /// <param name="oIntersectSize"></param>
        /// <param name="tBeginRow"></param>
        /// <param name="tBeginCol"></param>
        /// <param name="tIntersectSize"></param>
        /// <returns></returns>
        public static bool ComputeBeginEndRowCol(AbstractWarpDataset args, AbstractWarpDataset dstArgs,
                                                 ref int oBeginRow, ref int oBeginCol, ref Size oIntersectSize,
                                                 ref int tBeginRow, ref int tBeginCol, ref Size tIntersectSize)
        {
            Envelope oEnvelope = args.GetEnvelope();
            Envelope tEnvelope = dstArgs.GetEnvelope();
            Geometry oGeo      = oEnvelope.GetGeometry();
            Geometry tGeo      = tEnvelope.GetGeometry();

            Geometry inEnvGeo = oGeo.Intersection(tGeo);

            if (inEnvGeo == null)
            {
                return(false);
            }
            Envelope inEnv = new Envelope();

            inEnvGeo.GetEnvelope(inEnv);

            if (!IsInteractived(oEnvelope, tEnvelope))
            {
                return(false);
            }
            float oResolutionX = args.ResolutionX;
            float oResolutionY = args.ResolutionY;
            float tResolutionX = dstArgs.ResolutionX;
            float tResolutionY = dstArgs.ResolutionY;

            oIntersectSize = CoordEnvelopeToSize(inEnv, oResolutionX, oResolutionY);
            tIntersectSize = CoordEnvelopeToSize(inEnv, tResolutionX, tResolutionY);
            //
            if (oEnvelope.MinX >= tEnvelope.MinX)//左边界在目标图像内部
            {
                oBeginCol = 0;
                tBeginCol = (int)((oEnvelope.MinX - tEnvelope.MinX) / tResolutionX + _errorValue);
            }
            else//左边界在目标图像外部
            {
                oBeginCol = (int)((tEnvelope.MinX - oEnvelope.MinX) / oResolutionX + _errorValue);
                tBeginCol = 0;
            }
            if (oEnvelope.MaxY <= tEnvelope.MaxY)//上边界在目标图像内部
            {
                oBeginRow = 0;
                tBeginRow = (int)((tEnvelope.MaxY - oEnvelope.MaxY) / tResolutionY + _errorValue);
            }
            else//上边界在目标边界外部
            {
                oBeginRow = (int)((oEnvelope.MaxY - tEnvelope.MaxY) / oResolutionY + _errorValue);
                tBeginRow = 0;
            }
            Size oSize = new Size(args.Width, args.Height);
            Size tSize = new Size(dstArgs.Width, dstArgs.Height);

            //以下添加对偏移计算的纠正,取最小行列数
            if (oIntersectSize.Width + oBeginCol > oSize.Width)
            {
                oIntersectSize.Width = oSize.Width - oBeginCol;
            }
            if (oIntersectSize.Height + oBeginRow > oSize.Height)
            {
                oIntersectSize.Height = oSize.Height - oBeginRow;
            }
            if (tIntersectSize.Width + tBeginCol > tSize.Width)
            {
                tIntersectSize.Width = tSize.Width - tBeginCol;
            }
            if (tIntersectSize.Height + tBeginRow > tSize.Height)
            {
                tIntersectSize.Height = tSize.Height - tBeginRow;
            }
            return(true);
        }
예제 #3
0
        public AbstractWarpDataset[] Clip(AbstractWarpDataset srcRaster, BlockDef[] blockDefs, int samplePercent,
                                          string driver, string outdir, Action <int, string> progressCallback, params object[] options)
        {
            AbstractWarpDataset[] tProviders = new AbstractWarpDataset[blockDefs.Length];
            if (progressCallback != null)
            {
                progressCallback(0, "开始数据分幅");
            }
            for (int blockNums = 0; blockNums < blockDefs.Length; blockNums++)
            {
                if (progressCallback != null)
                {
                    progressCallback((int)((blockNums + 1.0) / blockDefs.Length * 100),
                                     string.Format("正在分幅第{0}/{1}个文件...", (blockNums + 1).ToString(), blockDefs.Length));
                }
                //位置映射参数
                int      tBeginRow = -1, tEndRow = -1, tBeginCol = -1, tEndCol = -1;
                int      oBeginRow = -1, oEndRow = -1, oBeginCol = -1, oEndCol = -1;
                Envelope oEnvelope = srcRaster.GetEnvelope();
                Envelope tEnvelope = blockDefs[blockNums].ToEnvelope();
                Size     oSize     = new Size(srcRaster.Width, srcRaster.Height);
                Size     tSize     =
                    ClipCutHelper.GetTargetSize(blockDefs[blockNums], srcRaster.ResolutionX, srcRaster.ResolutionY);
                bool isInternal = new RasterMoasicClipHelper().ComputeBeginEndRowCol(oEnvelope, oSize, tEnvelope, tSize,
                                                                                     ref oBeginRow, ref oBeginCol, ref oEndRow, ref oEndCol,
                                                                                     ref tBeginRow, ref tBeginCol, ref tEndRow, ref tEndCol);
                string blockFilename =
                    ClipCutHelper.GetBlockFilename(blockDefs[blockNums], srcRaster.fileName, outdir, driver);
                int   oWidth  = 0;
                int   oHeight = 0;
                float tResolutionX;
                float tResolutionY;
                if (samplePercent > 0 && samplePercent < 100)
                {
                    oHeight      = (int)(tSize.Width * samplePercent * 1f / 100 + 0.5);
                    oWidth       = (int)(tSize.Width * samplePercent * 1f / 100 + 0.5);
                    tResolutionX = srcRaster.ResolutionX * samplePercent * 1f / 100;
                    tResolutionY = srcRaster.ResolutionY * samplePercent * 1f / 100;
                }
                else
                {
                    oHeight      = tSize.Height;
                    oWidth       = tSize.Width;
                    tResolutionX = srcRaster.ResolutionX;
                    tResolutionY = srcRaster.ResolutionY;
                }

                string[] optionString = new string[]
                {
                    "INTERLEAVE=BSQ",
                    "VERSION=LDF",
                    "WITHHDR=TRUE",
                    "SPATIALREF=" + srcRaster.SpatialRef.ExportToProj4(),
                    "MAPINFO={" + 1 + "," + 1 + "}:{" + tEnvelope.MinX + "," + tEnvelope.MaxY + "}:{" + tResolutionX +
                    "," + tResolutionY + "}"
                };
                string[] _options = new string[] { "header_offset=128" };

                double[] geoTrans = new double[]
                {
                    tEnvelope.MinX, Convert.ToDouble(tResolutionX.ToString("f6")), 0, tEnvelope.MaxY, 0,
                    -Convert.ToDouble(tResolutionY.ToString("f6"))
                };
                var rDs = DatasetFactory.CreateRasterDataset(blockFilename, oWidth, oHeight, srcRaster.BandCount,
                                                             srcRaster.DataType, "ENVI", null);
                rDs.SetGeoTransform(geoTrans);
                rDs.SetProjection(srcRaster.SpatialRef.ExportToWkt());
                tProviders[blockNums] = new WarpDataset(rDs, blockFilename);
                int rowStep = ClipCutHelper.ComputeRowStep(srcRaster, oBeginRow, oEndRow);
                for (int oRow = oBeginRow; oRow < oEndRow; oRow += rowStep)
                {
                    if (oRow + rowStep > oEndRow)
                    {
                        rowStep = oEndRow - oRow;
                    }
                    for (int bandIndex = 1; bandIndex <= srcRaster.BandCount; bandIndex++)
                    {
                        int    sample     = (oEndCol - oBeginCol);
                        int    typeSize   = ClipCutHelper.GetSize(srcRaster.DataType);
                        int    bufferSize = sample * rowStep * typeSize;
                        byte[] databuffer = new byte[bufferSize];
                        unsafe
                        {
                            fixed(byte *ptr = databuffer)
                            {
                                IntPtr buffer = new IntPtr(ptr);

                                srcRaster.GetRasterBand(bandIndex).ReadRaster(oBeginCol, oRow, sample, rowStep, buffer,
                                                                              sample, rowStep, srcRaster.DataType, 0, 0);

                                if (samplePercent > 0 && samplePercent < 100)
                                {
                                    tProviders[blockNums].GetRasterBand(bandIndex).WriteRaster(
                                        (int)(tBeginCol * samplePercent * 1f / 100 + 0.5),
                                        (int)((tBeginRow + (oRow - oBeginRow)) * samplePercent * 1f / 100 + 0.5),
                                        (int)(sample * samplePercent * 1f / 100 + 0.5),
                                        (int)(rowStep * samplePercent * 1f / 100 + 0.5), buffer,
                                        (int)(sample * samplePercent * 1f / 100 + 0.5),
                                        (int)(rowStep * samplePercent * 1f / 100 + 0.5), srcRaster.DataType, 0, 0);
                                }
                                else
                                {
                                    tProviders[blockNums].GetRasterBand(bandIndex).WriteRaster(tBeginCol,
                                                                                               tBeginRow + (oRow - oBeginRow), sample, rowStep, buffer, sample, rowStep,
                                                                                               srcRaster.DataType, 0, 0);
                                }
                            }
                        }
                    }
                }
            }

            return(tProviders);
        }
예제 #4
0
        public void Do(InputArg inArg)
        {
            CheckAtg(inArg);
            string    projectionIdentify = inArg.ProjectionIdentify;
            OutputArg outArg             = new OutputArg();

            try
            {
                using (AbstractWarpDataset inputRaster = WarpDataset.Open(inArg.InputFilename))
                {
                    RasterDatasetInfo dsInfo =
                        mRasterSourceManager.GetInstance().GetRasterDatasetInfo(inArg.InputFilename);
                    DateTime?    dateTime     = mRasterSourceManager.GetInstance().GetImageTime(inArg.InputFilename);
                    DataIdentify dataIdentify = new DataIdentify();
                    outArg.OrbitFilename      = Path.GetFileName(inArg.InputFilename);
                    outArg.Satellite          = dsInfo.SatelliteID;
                    outArg.Sensor             = dsInfo.SensorID;
                    outArg.Level              = "L1";
                    outArg.ProjectionIdentify = projectionIdentify;
                    outArg.ObservationDate    = dateTime.HasValue ? dateTime.Value.ToString("yyyyMMdd") : "";
                    outArg.ObservationTime    = dateTime.HasValue ? dateTime.Value.ToString("HHmm") : "";
                    outArg.Station            = ParseStation(Path.GetFileName(inArg.InputFilename));
                    outArg.DayOrNight         = DayOrNight(inputRaster);
                    if (dateTime.HasValue)
                    {
                        outArg.OrbitIdentify = CalcOrbitIdentify(dateTime.Value, inArg.PervObservationDate,
                                                                 inArg.PervObservationTime, inArg.OrbitIdentify);
                    }
                    outArg.Length = new FileInfo(inArg.InputFilename).Length;
                    string validEnvelopeMsg = "";

                    #region 日夜检查

                    if (!string.IsNullOrWhiteSpace(inArg.DayNight))
                    {
                        if (inArg.DayNight != "daynight" && outArg.DayOrNight == "X")
                        {
                            outArg.LogLevel = "info";
                            outArg.LogInfo  = "未设定处理白天和晚上数据,白天晚上标记未知:X";
                        }
                        else if (inArg.DayNight == "day" && outArg.DayOrNight != "D")
                        {
                            outArg.LogLevel = "info";
                            outArg.LogInfo  = "设定为只处理白天数据,当前数据标记为晚上";
                        }
                        else if (inArg.DayNight == "night" && outArg.DayOrNight != "N")
                        {
                            outArg.LogLevel = "info";
                            outArg.LogInfo  = "设定为只处理晚上数据,当前数据标记为白天";
                        }
                        else if (inArg.DayNight == "notnight" && outArg.DayOrNight == "N")
                        {
                            outArg.LogLevel = "info";
                            outArg.LogInfo  = "设定为不处理晚上数据,当前数据标记为晚上";
                        }
                        else if (inArg.DayNight == "notday" && outArg.DayOrNight == "D")
                        {
                            outArg.LogLevel = "info";
                            outArg.LogInfo  = "设定为不处理白天数据,当前数据标记为白天";
                        }
                    }

                    #endregion 日夜检查

                    if (inArg.ValidEnvelopes == null || inArg.ValidEnvelopes.Length == 0)
                    {
                        outArg.LogLevel = "error";
                        outArg.LogInfo  = "参数错误:未正确设置ValidEnvelopes";
                    }
                    else if (!ValidEnvelope(inputRaster, inArg.ValidEnvelopes, out validEnvelopeMsg))
                    {
                        outArg.LogLevel = "info";
                        outArg.LogInfo  = validEnvelopeMsg;
                    }
                    else
                    {
                        PrjOutArg prjArg;
                        if (inArg.Envelopes == null || inArg.Envelopes.Length == 0)
                        {
                            prjArg = new PrjOutArg(projectionIdentify, null, inArg.ResolutionX, inArg.ResolutionY,
                                                   inArg.OutputDir);
                        }
                        else
                        {
                            prjArg = new PrjOutArg(projectionIdentify, inArg.Envelopes, inArg.ResolutionX,
                                                   inArg.ResolutionY, inArg.OutputDir);
                        }
                        //prjArg.Args = new string[] { "SolarZenith"};
                        if (inArg.Bands != null && inArg.Bands.Length != 0)
                        {
                            prjArg.SelectedBands = inArg.Bands;
                            Console.WriteLine("SelectedBands:" + string.Join(",", prjArg.SelectedBands));
                        }

                        //扩展参数
                        List <string> extArgs = new List <string>();
                        extArgs.Add("IsClearPrjCache");
                        if (inArg.ExtArgs != null)
                        {
                            extArgs.AddRange(inArg.ExtArgs);
                        }
                        prjArg.Args = extArgs.ToArray();
                        ProjectionFactory prjFactory = new ProjectionFactory();
                        string            retMessage = "";
                        string[]          files      = prjFactory.Project(inputRaster, prjArg, new Action <int, string>(OnProgress),
                                                                          out retMessage);
                        prjFactory = null;
                        //投影结束,执行拼接,如果有拼接节点
                        List <OutFileArg> fileArgs = new List <OutFileArg>();
                        for (int i = 0; i < files.Length; i++)
                        {
                            string file = files[i];
                            if (string.IsNullOrWhiteSpace(file) || !File.Exists(file))
                            {
                                continue;
                            }
                            OutFileArg fileArg = new OutFileArg();
                            Envelope   env     = null;
                            float      resolutionX;
                            float      resolutionY;
                            string     overViewFilename = "";
                            using (AbstractWarpDataset outfileRaster = WarpDataset.Open(file))
                            {
                                Console.WriteLine("生成缩略图开始");
                                overViewFilename = OverViewHelper.OverView(outfileRaster, _prjPngSize);
                                Console.WriteLine("生成缩略图结束");
                                env         = outfileRaster.GetEnvelope();
                                resolutionX = outfileRaster.ResolutionX;
                                resolutionY = outfileRaster.ResolutionY;
                                var dt = dateTime.HasValue ? dateTime.Value : DateTime.Now;
                                TryMosaicFile(inArg, outfileRaster, dsInfo, dt, outArg.DayOrNight);
                            }

                            fileArg.OutputFilename = Path.GetFileName(file);
                            fileArg.Thumbnail      =
                                (string.IsNullOrWhiteSpace(overViewFilename) && File.Exists(overViewFilename)
                                    ? ""
                                    : Path.GetFileName(overViewFilename));
                            string solarZenithFile = Path.Combine(Path.GetDirectoryName(file),
                                                                  Path.GetFileNameWithoutExtension(file) + ".SolarZenith.ldf");
                            string solarZenithHdrFile = Path.Combine(Path.GetDirectoryName(file),
                                                                     Path.GetFileNameWithoutExtension(file) + ".SolarZenith.hdr");
                            fileArg.ExtendFiles = Path.ChangeExtension(Path.GetFileName(file), "hdr") +
                                                  (string.IsNullOrWhiteSpace(solarZenithFile) &&
                                                   File.Exists(solarZenithFile)
                                                      ? ""
                                                      : "," + Path.GetFileName(solarZenithFile)) +
                                                  (string.IsNullOrWhiteSpace(solarZenithHdrFile) &&
                                                   File.Exists(solarZenithHdrFile)
                                                      ? ""
                                                      : "," + Path.GetFileName(solarZenithHdrFile));
                            fileArg.Envelope = new PrjEnvelopeItem("GBAL",
                                                                   env == null
                                    ? null
                                    : new RasterProject.PrjEnvelope(env.MinX, env.MaxX, env.MinY, env.MaxY,
                                                                    SpatialReferenceFactory.CreateSpatialReference(4326)));
                            fileArg.ResolutionX = resolutionX.ToString();
                            fileArg.ResolutionY = resolutionY.ToString();
                            fileArg.Length      = new FileInfo(file).Length;
                            fileArgs.Add(fileArg);
                            if (inArg.IsOnlySaveMosaicFile)
                            {
                                TryDeleteFile(file);
                            }
                        }

                        outArg.OutputFiles = fileArgs.ToArray();
                        outArg.LogLevel    = "info";
                        if (string.IsNullOrWhiteSpace(retMessage))
                        {
                            outArg.LogInfo = "投影成功";
                        }
                        else
                        {
                            outArg.LogInfo = retMessage;
                        }
                        if (string.IsNullOrWhiteSpace(validEnvelopeMsg))
                        {
                            outArg.LogInfo = outArg.LogInfo + validEnvelopeMsg;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                outArg.LogLevel = "error";
                Console.WriteLine(ex.StackTrace);
                outArg.LogInfo = ex.Message + ex.StackTrace;
                Console.WriteLine("PIE.Meteo.ProjectTool.Execute()", ex);
            }
            finally
            {
                //输出参数文件重新命名
                string inputFileName = Path.GetFileName(inArg.InputFilename);

                System.Text.RegularExpressions.Regex rex = new System.Text.RegularExpressions.Regex(@"_\d{4}M");
                if (rex.IsMatch(inputFileName))
                {
                    string oldResStr = rex.Match(inputFileName).Groups[0].Value;
                    if (inArg.ProjectionIdentify == "GLL")
                    {
                        inputFileName = inputFileName.Replace(oldResStr,
                                                              $"_{PrjFileName.GLLResolutionIdentify(inArg.ResolutionX)}");
                    }
                    else
                    {
                        inputFileName = inputFileName.Replace(oldResStr,
                                                              $"_{PrjFileName.ResolutionIdentify(inArg.ResolutionX)}");
                    }
                }

                string outXmlFilename = Path.Combine(inArg.OutputDir, inputFileName + ".xml");
                OutputArg.WriteXml(outArg, outXmlFilename);
            }
        }
예제 #5
0
        public AbstractWarpDataset Clip(AbstractWarpDataset srcRaster, BlockDef blockDefs, int samplePercent,
                                        string driver, string outdir, Action <int, string> progressCallback, out double validPercent,
                                        params object[] options)
        {
            AbstractWarpDataset tProviders = null;

            if (progressCallback != null)
            {
                progressCallback(0, "开始数据分幅");
            }
            //位置映射参数
            int      tBeginRow = -1, tEndRow = -1, tBeginCol = -1, tEndCol = -1;
            int      oBeginRow = -1, oEndRow = -1, oBeginCol = -1, oEndCol = -1;
            Envelope oEnvelope  = srcRaster.GetEnvelope();
            Envelope tEnvelope  = blockDefs.ToEnvelope();
            Size     oSize      = new Size(srcRaster.Width, srcRaster.Height);
            Size     tSize      = ClipCutHelper.GetTargetSize(blockDefs, srcRaster.ResolutionX, srcRaster.ResolutionY);
            bool     isInternal = new RasterMoasicClipHelper().ComputeBeginEndRowCol(oEnvelope, oSize, tEnvelope, tSize,
                                                                                     ref oBeginRow, ref oBeginCol, ref oEndRow, ref oEndCol,
                                                                                     ref tBeginRow, ref tBeginCol, ref tEndRow, ref tEndCol);
            string blockFilename = ClipCutHelper.GetBlockFilename(blockDefs, srcRaster.fileName, outdir, driver);
            int    oWidth        = 0;
            int    oHeight       = 0;
            float  tResolutionX;
            float  tResolutionY;

            if (samplePercent > 0 && samplePercent < 100)
            {
                oHeight      = (int)(tSize.Width * samplePercent * 1f / 100 + 0.5);
                oWidth       = (int)(tSize.Width * samplePercent * 1f / 100 + 0.5);
                tResolutionX = srcRaster.ResolutionX * samplePercent * 1f / 100;
                tResolutionY = srcRaster.ResolutionY * samplePercent * 1f / 100;
            }
            else
            {
                oHeight      = tSize.Height;
                oWidth       = tSize.Width;
                tResolutionX = srcRaster.ResolutionX;
                tResolutionY = srcRaster.ResolutionY;
            }

            string[] optionString = new string[]
            {
                "INTERLEAVE=BSQ",
                "VERSION=LDF",
                "WITHHDR=TRUE",
                "SPATIALREF=" + srcRaster.SpatialRef.ExportToProj4(),
                "MAPINFO={" + 1 + "," + 1 + "}:{" + tEnvelope.MinX + "," + tEnvelope.MaxY + "}:{" + tResolutionX + "," +
                tResolutionY + "}"
            };
            string[] _options = new string[] { "header_offset=128" };
            double[] geoTrans = new double[]
            {
                tEnvelope.MinX, Convert.ToDouble(tResolutionX.ToString("f6")), 0, tEnvelope.MaxY, 0,
                -Convert.ToDouble(tResolutionY.ToString("f6"))
            };
            var rDs = DatasetFactory.CreateRasterDataset(blockFilename, oWidth, oHeight, srcRaster.BandCount,
                                                         srcRaster.DataType, "ENVI", null);

            rDs.SetGeoTransform(geoTrans);
            rDs.SetProjection(srcRaster.SpatialRef.ExportToWkt());
            tProviders = new WarpDataset(rDs, blockFilename);
            int rowStep  = ClipCutHelper.ComputeRowStep(srcRaster, oBeginRow, oEndRow);
            int sample   = (oEndCol - oBeginCol);
            int typeSize = ClipCutHelper.GetSize(srcRaster.DataType);

            long allPixelByte   = sample * (oEndRow - oBeginRow) * typeSize * srcRaster.BandCount;
            long validPixelByte = 0;
            long validPer       = (int)(allPixelByte * 0.1f);
            int  stepCount      = (int)((oEndRow - oBeginRow) / rowStep + 0.5) * srcRaster.BandCount;
            int  step           = 0;
            int  percent        = 0;

            for (int oRow = oBeginRow; oRow < oEndRow; oRow += rowStep)
            {
                if (oRow + rowStep > oEndRow)
                {
                    rowStep = oEndRow - oRow;
                }
                for (int bandIndex = 0; bandIndex < srcRaster.BandCount; bandIndex++)
                {
                    step++;
                    percent = (int)(step * 1.0f / stepCount * 100);
                    if (progressCallback != null)
                    {
                        progressCallback(percent, "完成数据分幅" + percent + "%");
                    }
                    int    bufferSize = sample * rowStep * typeSize;
                    byte[] databuffer = new byte[bufferSize];
                    unsafe
                    {
                        fixed(byte *ptr = databuffer)
                        {
                            IntPtr buffer = new IntPtr(ptr);

                            srcRaster.GetRasterBand(bandIndex).ReadRaster(oBeginCol, oRow, sample, rowStep, buffer, sample,
                                                                          rowStep, srcRaster.DataType, 0, 0);
                            if (validPixelByte < validPer)
                            {
                                foreach (byte b in databuffer)
                                {
                                    if (b != 0)
                                    {
                                        validPixelByte++;
                                    }
                                }
                            }

                            if (validPixelByte == 0)
                            {
                                continue;
                            }
                            if (samplePercent > 0 && samplePercent < 100)
                            {
                                tProviders.GetRasterBand(bandIndex).WriteRaster(
                                    (int)(tBeginCol * samplePercent * 1f / 100 + 0.5),
                                    (int)((tBeginRow + (oRow - oBeginRow)) * samplePercent * 1f / 100 + 0.5),
                                    (int)(sample * samplePercent * 1f / 100 + 0.5),
                                    (int)(rowStep * samplePercent * 1f / 100 + 0.5), buffer,
                                    (int)(sample * samplePercent * 1f / 100 + 0.5),
                                    (int)(rowStep * samplePercent * 1f / 100 + 0.5), srcRaster.DataType, 0, 0);
                            }
                            else
                            {
                                tProviders.GetRasterBand(bandIndex).WriteRaster(tBeginCol, tBeginRow + (oRow - oBeginRow),
                                                                                sample, rowStep, buffer, sample, rowStep, srcRaster.DataType, 0, 0);
                            }
                        }
                    }
                }
            }

            validPercent = validPixelByte * 1.0d / allPixelByte;
            if (progressCallback != null)
            {
                progressCallback(100, "完成数据分幅");
            }
            return(tProviders);
        }