Пример #1
0
 internal void SetArgs(ISpatialReference spatialRef, PrjEnvelope prjEnvelope, float resolutionX, float resolutionY)
 {
     _spatialRef         = spatialRef;
     _prjEnvelope        = prjEnvelope;
     _resolutionX        = resolutionX;
     _resolutionY        = resolutionY;
     _piexlSize          = _prjEnvelope.GetSize(resolutionX, resolutionY);
     txtX.Text           = _prjEnvelope.CenterX.ToString();
     txtY.Text           = _prjEnvelope.CenterY.ToString();
     txtPixelSizeX.Text  = _piexlSize.Width.ToString();
     txtPixelSizeY.Text  = _piexlSize.Height.ToString();
     txtResolutionX.Text = resolutionX.ToString();
     txtResolutionY.Text = resolutionY.ToString();
 }
Пример #2
0
        private IRasterDataProvider CreateMosaicFile(IRasterDataProvider copyRaster, PrjEnvelope env, string filename)
        {
            ISpatialReference spatialRef = copyRaster.SpatialRef;
            string            bandNames  = BandNameString(copyRaster as ILdfDataProvider);
            Size outSize = env.GetSize(copyRaster.ResolutionX, copyRaster.ResolutionY);

            string[] options = new string[] {
                "INTERLEAVE=BSQ",
                "VERSION=LDF",
                "WITHHDR=TRUE",
                "SPATIALREF=" + spatialRef.ToProj4String(),
                "MAPINFO={" + 1 + "," + 1 + "}:{" + env.MinX + "," + env.MaxY + "}:{" + copyRaster.ResolutionX + "," + copyRaster.ResolutionY + "}",
                "BANDNAMES=" + bandNames
            };
            return(IdentifyOutFile(filename, copyRaster.BandCount, outSize, copyRaster.DataType, options));
        }
Пример #3
0
 public void SetGeoEnvelope(PrjEnvelope geoEnvelope)
 {
     try
     {
         BeginChangedValue();
         txtCenterLongitude.Text = geoEnvelope.CenterX.ToString();
         txtCenterLatitude.Text  = geoEnvelope.CenterY.ToString();
         Size size = geoEnvelope.GetSize(_resolutionX, _resolutionY);
         cmbSizeX.Text = size.Width.ToString();
         cmbSizeY.Text = size.Height.ToString();
     }
     finally
     {
         EndChangedValue();
     }
 }
Пример #4
0
        private AbstractWarpDataset CreateMosaicFile(string mosaicFilename, InputArg inArg)
        {
            SpatialReference spatialRef = fileRaster.SpatialRef;
            PrjEnvelope      env        = inArg.MosaicInputArg.Envelope.PrjEnvelope;
            //string bandNames = BandNameString(fileRaster as ILdfDataProvider);
            Size outSize = env.GetSize(fileRaster.ResolutionX, fileRaster.ResolutionY);

            string[] options = new string[] {
                "INTERLEAVE=BSQ",
                "VERSION=LDF",
                "WITHHDR=TRUE",
                "SPATIALREF=" + spatialRef.ExportToProj4(),
                "MAPINFO={" + 1 + "," + 1 + "}:{" + env.MinX + "," + env.MaxY + "}:{" + fileRaster.ResolutionX + "," + fileRaster.ResolutionY + "}",
                //"BANDNAMES="+ bandNames
            };
            return(CreateOutFile(mosaicFilename, fileRaster.BandCount, outSize, DataType.GDT_UInt16, env, spatialRef, options));
        }
Пример #5
0
 private void UpdatePrjenvelopeSet(float resolution)
 {
     if (resolution == 0f)
     {
         if (_dstSpatialRef == null || _dstSpatialRef.ProjectionCoordSystem == null)
         {
             resolution = 0.01f;
         }
         else
         {
             resolution = 1000f;
         }
     }
     if (_mosaicProjectionFileProvider.FileItems != null && _mosaicProjectionFileProvider.FileItems.Length != 0)
     {
         PrjEnvelope env  = _mosaicProjectionFileProvider.FileItems[0].Envelope;
         Size        size = env.GetSize(resolution, resolution);
         ucPrjEnvelopes1.SetValue(_dstSpatialRef, new PrjPoint(env.CenterX, env.CenterY), resolution, resolution, size);
     }
     else
     {
         ucPrjEnvelopes1.SetValue(_dstSpatialRef, null, resolution, resolution, new Size((int)resolution, (int)resolution));
     }
 }
Пример #6
0
        public void RastAndProject <T>(Size outSize, H5T.H5Type ht5type, H5FileId fileId, string dataset, Action <int, string> progressCallback, int outWidth, int outHeight, int rowStep, IRasterDataProvider srcRaster, FilePrjSettings prjSettings, int bandnum, T fillValue, HDF5.Hdf5Operator ope)
        {
            T[,] data = new T[outSize.Height, outSize.Width];
            // 定义数据集操作部分
            long[] dims = new long[2];
            dims[0] = Convert.ToInt64(outSize.Height);
            dims[1] = Convert.ToInt64(outSize.Width);
            H5DataSpaceId dspaceId = H5S.create_simple(2, dims);
            // Define datatype for the data in the file.
            H5DataTypeId dtypeId = H5T.copy(ht5type);
            // Create the data set DATASETNAME.

            H5DataSetId dsetId = H5D.create(fileId, dataset, dtypeId, dspaceId);

            for (int oRow = 0; oRow < outHeight; oRow += rowStep)
            {
                #region 分块读取数据集
                if (progressCallback != null)
                {
                    percent++;
                    progress = percent * 100 / progressCount;
                    progressCallback(progress, string.Format("投影完成{0}%", progress));
                }
                if (oRow + rowStep > outHeight)
                {
                    rowStep = outHeight - oRow;
                }
                Size     outStepSize = new Size(outWidth, rowStep);
                double[] xs          = new double[outWidth * rowStep];
                double[] ys          = new double[outWidth * rowStep];
                double   oY          = oRow * prjSettings.OutResolutionY;
                Parallel.For(0, rowStep, j =>
                {
                    double x;
                    double y;
                    int index;
                    y = prjSettings.OutEnvelope.LeftTop.Y - j * prjSettings.OutResolutionY - oY;
                    for (int i = 0; i < outWidth; i++)
                    {
                        x         = prjSettings.OutEnvelope.LeftTop.Y + i * prjSettings.OutResolutionX;
                        index     = i + j * outWidth;
                        xs[index] = x;
                        ys[index] = y;
                    }
                });
                _projectionTransform.InverTransform(xs, ys);
                PrjEnvelope tEnvelope = PrjEnvelope.GetEnvelope(xs, ys, null);
                tEnvelope.Extend(srcRaster.ResolutionX, srcRaster.ResolutionY * 4);
                PrjEnvelope srcEnvelope = new PrjEnvelope(srcRaster.CoordEnvelope.MinX, srcRaster.CoordEnvelope.MaxX, srcRaster.CoordEnvelope.MinY, srcRaster.CoordEnvelope.MaxY);
                tEnvelope = PrjEnvelope.Intersect(tEnvelope, srcEnvelope);
                if (tEnvelope == null || tEnvelope.IsEmpty)
                {
                    continue;
                }
                Size tSize = tEnvelope.GetSize(srcRaster.ResolutionX, srcRaster.ResolutionY);
                int  tBeginRow = -1, tEndRow = -1, tBeginCol = -1, tEndCol = -1;
                int  oBeginRow = -1, oEndRow = -1, oBeginCol = -1, oEndCol = -1;
                PrjBlockHelper.ComputeBeginEndRowCol(srcEnvelope, new Size(srcRaster.Width, srcRaster.Height), tEnvelope, tSize,
                                                     ref oBeginRow, ref oBeginCol, ref oEndRow, ref oEndCol,
                                                     ref tBeginRow, ref tBeginCol, ref tEndRow, ref tEndCol);
                int      srcStepWidth        = oEndCol - oBeginCol;
                int      srcStepHeight       = oEndRow - oBeginRow;
                Size     srcStepSize         = new Size(srcStepWidth, srcStepHeight);
                T[]      srcBandData         = new T[srcStepWidth * srcStepHeight];
                T[]      dstBandData         = new T[outWidth * rowStep];
                double   srcStepLeftTopX     = tEnvelope.MinX;
                double   srcStepLeftTopY     = tEnvelope.MaxY;
                double   srcStepRightBottomX = tEnvelope.MaxX;
                double   srcStepRightBottomY = tEnvelope.MinY;
                UInt16[] rows                = new UInt16[outWidth * rowStep]; //正向查找表
                UInt16[] cols                = new UInt16[outWidth * rowStep]; //正向查找表
                if (progressCallback != null)
                {
                    percent++;
                    progress = percent * 100 / progressCount;
                    progressCallback(progress, string.Format("投影完成{0}%", progress));
                }
                Parallel.For(0, rowStep, j =>
                {
                    double x;
                    double y;
                    int index;
                    for (int i = 0; i < outWidth; i++)
                    {
                        index = i + j * outWidth;
                        x     = xs[index];
                        y     = ys[index];
                        if (x >= srcStepLeftTopX && x <= srcStepRightBottomX && y <= srcStepLeftTopY && y >= srcStepRightBottomY)
                        {
                            cols[index] = (UInt16)((x - srcStepLeftTopX) / srcRaster.ResolutionX + 0.5);
                            rows[index] = (UInt16)((srcStepLeftTopY - y) / srcRaster.ResolutionY + 0.5);
                        }
                    }
                });
                xs = null;
                ys = null;
                #endregion
                //分块读取不同波段数据
                ReadBandData <T>(srcBandData, bandnum, oBeginCol, oBeginRow, srcStepWidth, srcStepHeight, GetSysDataType(ht5type));
                //投影不同分块的数据集
                _rasterProjector.Project <T>(srcBandData, srcStepSize, rows, cols, outStepSize, dstBandData, fillValue, 0, null);

                for (int i = 0; i < outStepSize.Width; i++)
                {
                    for (int j = 0; j < outStepSize.Height; j++)
                    {
                        int index = j * outStepSize.Width + i;
                        data[j + oRow, i] = dstBandData[index];
                    }
                }

                rows        = null;
                rows        = null;
                srcBandData = null;
                dstBandData = null;
            }
            H5D.write(dsetId, dtypeId, new H5Array <T>(data));
            //写数据集属性
            //Dictionary<string, string> dsetkeyvalue = ope.GetAttributes(dataset);
            //foreach (string key in dsetkeyvalue.Keys)
            //{
            //    string value = dsetkeyvalue[key];
            //    HDFAttributeDef attrdef = new HDFAttributeDef(key, typeof(string), dsetkeyvalue[key].Length, value);
            //    WriteHdfAttributes.WriteHdfAttribute(dsetId, attrdef);
            //}
            H5D.close(dsetId);
        }
Пример #7
0
        private void ProjectRaster <T>(IRasterDataProvider srcRaster, FilePrjSettings prjSettings, Action <int, string> progressCallback, IRasterDataProvider prdWriter, T fillValue, double dataWeight, float zoom)
        {
            enumDataType dataType       = prdWriter.DataType;
            PrjEnvelope  outEnvelope    = prjSettings.OutEnvelope;
            float        outResolutionX = prjSettings.OutResolutionX;
            float        outResolutionY = prjSettings.OutResolutionY;
            Size         outSize        = prjSettings.OutSize;
            int          outWidth       = outSize.Width;
            int          outHeight      = outSize.Height;
            int          outBandCount   = prjSettings.OutBandNos.Length;

            if (progressCallback != null)
            {
                progressCallback(_readyProgress++, "投影准备");
            }
            int         srcHeight       = srcRaster.Height;
            int         srcWidth        = srcRaster.Width;
            PrjPoint    outLeftTopPoint = outEnvelope.LeftTop;
            float       srcResolutionX  = srcRaster.ResolutionX;
            float       srcResolutionY  = srcRaster.ResolutionY;
            Size        srcSize         = new Size(srcWidth, srcHeight);
            double      outLtPointX     = outLeftTopPoint.X;
            double      outLtPointY     = outLeftTopPoint.Y;
            PrjEnvelope srcEnvelope     = new PrjEnvelope(srcRaster.CoordEnvelope.MinX, srcRaster.CoordEnvelope.MaxX, srcRaster.CoordEnvelope.MinY, srcRaster.CoordEnvelope.MaxY);
            long        mem             = MemoryHelper.GetAvalidPhyMemory();

#if !WIN64
            mem = mem < 800 * 1024 * 1024 ? mem : 800 * 1024 * 1024;
#endif
            long maxLimit = mem / (6 * 8 * 2);
            int  rowStep  = (int)(maxLimit / outWidth);
            if (rowStep == 0)
            {
                rowStep = 1;
            }
            if (rowStep > outHeight)
            {
                rowStep = outHeight;
            }
            int stepCount     = (int)(Math.Ceiling((double)outHeight / rowStep));
            int percent       = 0;
            int progress      = 0;
            int progressCount = outBandCount * stepCount + stepCount * 2;

            for (int oRow = 0; oRow < outHeight; oRow += rowStep)
            {
                if (progressCallback != null)
                {
                    percent++;
                    progress = percent * 100 / progressCount;
                    progressCallback(progress, string.Format("投影完成{0}%", progress));
                }
                if (oRow + rowStep > outHeight)
                {
                    rowStep = outHeight - oRow;
                }
                Size     outStepSize = new Size(outWidth, rowStep);
                double[] xs          = new double[outWidth * rowStep];
                double[] ys          = new double[outWidth * rowStep];
                double   oY          = oRow * outResolutionY;
                Parallel.For(0, rowStep, j =>
                {
                    double x;
                    double y;
                    int index;
                    y = outLtPointY - j * outResolutionY - oY;
                    for (int i = 0; i < outWidth; i++)
                    {
                        x         = outLtPointX + i * outResolutionX;
                        index     = i + j * outWidth;
                        xs[index] = x;
                        ys[index] = y;
                    }
                });
                _projectionTransform.InverTransform(xs, ys);
                PrjEnvelope tEnvelope = PrjEnvelope.GetEnvelope(xs, ys, null);
                tEnvelope.Extend(srcResolutionX, srcResolutionY * 4);
                tEnvelope = PrjEnvelope.Intersect(tEnvelope, srcEnvelope);
                if (tEnvelope == null || tEnvelope.IsEmpty)
                {
                    continue;
                }
                Size tSize = tEnvelope.GetSize(srcResolutionX, srcResolutionY);
                int  tBeginRow = -1, tEndRow = -1, tBeginCol = -1, tEndCol = -1;
                int  oBeginRow = -1, oEndRow = -1, oBeginCol = -1, oEndCol = -1;
                PrjBlockHelper.ComputeBeginEndRowCol(srcEnvelope, srcSize, tEnvelope, tSize,
                                                     ref oBeginRow, ref oBeginCol, ref oEndRow, ref oEndCol,
                                                     ref tBeginRow, ref tBeginCol, ref tEndRow, ref tEndCol);
                int      srcStepWidth        = oEndCol - oBeginCol;
                int      srcStepHeight       = oEndRow - oBeginRow;
                Size     srcStepSize         = new Size(srcStepWidth, srcStepHeight);
                T[]      srcBandData         = new T[srcStepWidth * srcStepHeight];
                T[]      dstBandData         = new T[outWidth * rowStep];
                double   srcStepLeftTopX     = tEnvelope.MinX;
                double   srcStepLeftTopY     = tEnvelope.MaxY;
                double   srcStepRightBottomX = tEnvelope.MaxX;
                double   srcStepRightBottomY = tEnvelope.MinY;
                UInt16[] rows                = new UInt16[outWidth * rowStep]; //正向查找表
                UInt16[] cols                = new UInt16[outWidth * rowStep]; //正向查找表
                if (progressCallback != null)
                {
                    percent++;
                    progress = percent * 100 / progressCount;
                    progressCallback(progress, string.Format("投影完成{0}%", progress));
                }
                Parallel.For(0, rowStep, j =>
                {
                    double x;
                    double y;
                    int index;
                    for (int i = 0; i < outWidth; i++)
                    {
                        index = i + j * outWidth;
                        x     = xs[index];
                        y     = ys[index];
                        if (x >= srcStepLeftTopX && x <= srcStepRightBottomX && y <= srcStepLeftTopY && y >= srcStepRightBottomY)
                        {
                            cols[index] = (UInt16)((x - srcStepLeftTopX) / srcResolutionX + 0.5);
                            rows[index] = (UInt16)((srcStepLeftTopY - y) / srcResolutionY + 0.5);
                        }
                    }
                });
                xs = null;
                ys = null;
                for (int b = 0; b < outBandCount; b++)
                {
                    if (progressCallback != null)
                    {
                        percent++;
                        progress = percent * 100 / progressCount;
                        progressCallback(progress, string.Format("投影完成{0}%", progress));
                    }
                    ReadBandData <T>(srcBandData, b, oBeginCol, oBeginRow, srcStepWidth, srcStepHeight, dataType);

                    //用于测试全图输出结果,用于查看插值的效果:
#if DebugEaseGrid
                    GCHandle hTe = GCHandle.Alloc(srcBandData, GCHandleType.Pinned);
                    try
                    { Random  random    = new Random(12);
                      IntPtr  bufferPtr = hTe.AddrOfPinnedObject();
                      Int16[] tmp       = new Int16[srcBandData.Length];
                      for (int i = 0; i < srcBandData.Length; i++)
                      {
                          tmp[i] = (Int16)random.Next(200, 255);
                      }
                      Marshal.Copy(tmp, 0, bufferPtr, tmp.Length); }
                    finally
                    {
                        hTe.Free();
                    }
#endif
                    _rasterProjector.Project <T>(srcBandData, srcStepSize, rows, cols, outStepSize, dstBandData, fillValue, 0, null);
                    if (dataWeight == 1)
                    {
                        WriteDataToLDF <T>(prdWriter, dataType, outWidth, rowStep, oRow, dstBandData, b);
                    }
                    else
                    {
                        WriteDataToLDF <T>(prdWriter, dataType, outWidth, rowStep, oRow, dstBandData, b, dataWeight, zoom);
                    }
                }
                rows        = null;
                rows        = null;
                srcBandData = null;
                dstBandData = null;
            }
        }
Пример #8
0
        /// <summary>
        ///数据集投影
        /// </summary>
        /// <typeparam name="T">数据集类型</typeparam>
        /// <param name="sourcedata">原始数据集</param>
        /// <param name="srcEnvelope">原始数据集坐标范围(正弦坐标系)</param>
        /// <param name="dstEnvelope">目标数据集坐标范围(品面坐标系)</param>
        /// <param name="outSize">输出范围</param>
        /// <param name="dstResoultion">输出分辨率</param>
        /// <param name="srcResoultionX">原始数据集分辨率X</param>
        /// <param name="srcResoultionY">原始数据集分辨率Y</param>
        /// <returns></returns>
        private static SDataByProject <T> GetDataByProject <T>(T[,] sourcedata, PrjEnvelope srcEnvelope, PrjEnvelope dstEnvelope, Size inSize,
                                                               Size outSize, float dstResoultion, float srcResoultionX, float srcResoultionY, T fillValue, ISpatialReference dstSpatialRef, out UInt16[] rows, out UInt16[] cols, out Size srcStepSize)
        {
            rows        = null;
            cols        = null;
            srcStepSize = Size.Empty;
            IProjectionTransform _projectionTransform;
            //初始化原始坐标系转化对象
            //ISpatialReference dstSpatialRef = SpatialReference.GetDefault();
            string            proj4str      = "proj4 = +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs";
            ISpatialReference srcSpatialRef = SpatialReference.FromProj4(proj4str);

            _projectionTransform = ProjectionTransformFactory.GetProjectionTransform(srcSpatialRef, dstSpatialRef);
            //坐标系转换
            int rowStep = outSize.Height;

            for (int oRow = 0; oRow < outSize.Height; oRow += rowStep)
            {
                if (oRow + rowStep > outSize.Height)
                {
                    rowStep = outSize.Height - oRow;
                }
                Size     outStepSize = new Size(outSize.Width, rowStep);
                double[] xs          = new double[outSize.Width * rowStep];
                double[] ys          = new double[outSize.Width * rowStep];
                double   oY          = oRow * dstResoultion;
                Parallel.For(0, rowStep, j =>
                {
                    double x;
                    double y;
                    int index;
                    y = dstEnvelope.LeftTop.Y - j * dstResoultion - oY;
                    for (int i = 0; i < outSize.Width; i++)
                    {
                        x         = dstEnvelope.LeftTop.X + i * dstResoultion;
                        index     = i + j * outSize.Width;
                        xs[index] = x;
                        ys[index] = y;
                    }
                });
                _projectionTransform.InverTransform(xs, ys);

                PrjEnvelope tEnvelope = PrjEnvelope.GetEnvelope(xs, ys, null);
                tEnvelope.Extend(srcResoultionX, srcResoultionY * 4);
                tEnvelope = PrjEnvelope.Intersect(tEnvelope, srcEnvelope);
                if (tEnvelope == null || tEnvelope.IsEmpty)
                {
                    continue;
                }
                Size tSize = tEnvelope.GetSize(srcResoultionX, srcResoultionY);
                int  tBeginRow = -1, tEndRow = -1, tBeginCol = -1, tEndCol = -1;
                int  oBeginRow = -1, oEndRow = -1, oBeginCol = -1, oEndCol = -1;
                PrjBlockHelper.ComputeBeginEndRowCol(srcEnvelope, new Size(inSize.Width, inSize.Height), tEnvelope, tSize,
                                                     ref oBeginRow, ref oBeginCol, ref oEndRow, ref oEndCol,
                                                     ref tBeginRow, ref tBeginCol, ref tEndRow, ref tEndCol);
                int srcStepWidth  = oEndCol - oBeginCol;
                int srcStepHeight = oEndRow - oBeginRow;
                srcStepSize = new Size(srcStepWidth, srcStepHeight);

                T[,] dstData = new T[outSize.Height, outSize.Width];
                //double srcStepLeftTopX = tEnvelope.MinX;
                //double srcStepLeftTopY = tEnvelope.MaxY;
                //double srcStepRightBottomX = tEnvelope.MaxX;
                //double srcStepRightBottomY = tEnvelope.MinY;
                double   srcStepLeftTopX     = srcEnvelope.MinX;
                double   srcStepLeftTopY     = srcEnvelope.MaxY;
                double   srcStepRightBottomX = srcEnvelope.MaxX;
                double   srcStepRightBottomY = srcEnvelope.MinY;
                UInt16[] rowTemps            = new UInt16[outSize.Width * rowStep]; //正向查找表
                UInt16[] colTemps            = new UInt16[outSize.Width * rowStep]; //正向查找表

                Parallel.For(0, rowStep, j =>
                {
                    double x;
                    double y;
                    int index;
                    for (int i = 0; i < outSize.Width; i++)
                    {
                        index = i + j * outSize.Width;
                        x     = xs[index];
                        y     = ys[index];
                        if (x >= srcStepLeftTopX && x <= srcStepRightBottomX && y <= srcStepLeftTopY && y >= srcStepRightBottomY)
                        {
                            colTemps[index] = (UInt16)((x - srcStepLeftTopX) / srcResoultionX + 0.5);
                            rowTemps[index] = (UInt16)((srcStepLeftTopY - y) / srcResoultionY + 0.5);
                        }
                    }
                });
                rows = rowTemps;
                cols = colTemps;
                return(DoProject <T>(sourcedata, fillValue, ref outStepSize, ref srcStepSize, dstData, rows, cols));
            }
            return(null);
        }
Пример #9
0
        protected void ProjectToLDF(Band[] srcBands, Band[] dstBands, int beginBandIndex, Action <int, string> progressCallback)
        {
            //progressCallback = progressCallback;
            if (srcBands == null || srcBands[0].XSize == 0 || srcBands[0].YSize == 0)
            {
                throw new Exception("投影数据失败:无法读取源数据,或者源数据高或宽为0。");
            }
            Size  srcImgSize        = new Size(srcBands[0].XSize, srcBands[0].YSize);
            Size  outSize           = _dstEnvelope.GetSize(_outResolutionX, _outResolutionY);
            float bufferResolutionX = 0f;
            float bufferResolutionY = 0f;
            float outXScale         = _srcImgResolution / _outResolutionX;
            float outYScale         = _srcImgResolution / _outResolutionY;

            if (outXScale > 1.5f || outYScale > 1.5f)
            {
                bufferResolutionX = _srcImgResolution;
                bufferResolutionY = _srcImgResolution;
            }
            else
            {
                bufferResolutionX = _outResolutionX;
                bufferResolutionY = _outResolutionY;
            }
            int blockXCount;
            int blockYCount;
            int blockWidth;
            int blockHeight;

            //后面投影需要的内存:(double)经纬度数据、(int16)原始通道数据、(int16)投影后通道、(int16)其他(如角度数据等)
            GetBlockNumber(outSize, _srcLocationSize, outXScale, outYScale, out blockXCount, out blockYCount, out blockWidth, out blockHeight);
            int imgLocationRatioX = srcImgSize.Width / _srcLocationSize.Width;
            int imgLocationRatioY = srcImgSize.Height / _srcLocationSize.Height;

            progressCount = blockYCount * blockXCount * (_dstBandCount + (_angleBands == null ? 0 : _angleBands.Length) + (_extSrcBands == null ? 0 : _extSrcBands.Length));
            progress      = 0;
            percent       = 0;
            Size bufferSize;

            #region 在需要分块的情况下,采样经纬度数据集
            int      bC        = 1;
            int      tmpWidth  = 0;
            int      tmpHeight = 0;
            double[] tmpxs     = null;
            double[] tmpys     = null;
            if (blockYCount * blockXCount > 1 && (_xs == null || _ys == null))
            {
                bC        = (int)Math.Sqrt(blockXCount * blockYCount) + 1;
                tmpWidth  = _srcLocationSize.Width / bC;
                tmpHeight = _srcLocationSize.Height / bC;
                tmpxs     = ReadSampleDatas(_longitudeBand, 0, 0, tmpWidth, tmpHeight);
                tmpys     = ReadSampleDatas(_latitudeBand, 0, 0, tmpWidth, tmpHeight);
                TryApplyGeoInterceptSlope(tmpxs, tmpys);
                _rasterProjector.Transform(SpatialReferenceFactory.CreateSpatialReference(4326), tmpxs, tmpys, _dstSpatialRef);
            }
            #endregion

            for (int blockXNo = 0; blockXNo < blockXCount; blockXNo++)
            {
                for (int blockYNo = 0; blockYNo < blockYCount; blockYNo++)
                {
                    //起始偏移,结束偏移
                    int beginX = blockWidth * blockXNo;
                    int beginY = blockHeight * blockYNo;
                    if (beginX >= outSize.Width || beginY >= outSize.Height)
                    {
                        continue;
                    }
                    if (beginX + blockWidth > outSize.Width)
                    {
                        blockWidth = outSize.Width - beginX;
                    }
                    if (beginY + blockHeight > outSize.Height)
                    {
                        blockHeight = outSize.Height - beginY;
                    }

                    //当前块的四角范围
                    double      blockMinX     = _dstEnvelope.MinX + beginX * _outResolutionX;
                    double      blockMaxX     = blockMinX + blockWidth * _outResolutionX;
                    double      blockMaxY     = _dstEnvelope.MaxY - beginY * _outResolutionY;
                    double      blockMinY     = blockMaxY - blockHeight * _outResolutionY;
                    PrjEnvelope blockEnvelope = new PrjEnvelope(blockMinX, blockMaxX, blockMinY, blockMaxY, _dstSpatialRef);
                    bufferSize = blockEnvelope.GetSize(bufferResolutionX, bufferResolutionY);
                    //根据当前输出块,反算出对应的源数据块(轨道)起始行列,为了减小后面需要读取的源数据大小
                    Block curOrbitblock = null;
                    //开始获取当前分块的经纬度数据集,计算轨道数据范围偏移
                    double[] srcBlockXs;
                    double[] srcBlockYs;
                    if (blockYCount == 1 && blockXCount == 1)                           //没分块的情况
                    {
                        curOrbitblock = _orbitBlock.Clone() as Block;
                        if (curOrbitblock.xBegin < _left)
                        {
                            curOrbitblock.xBegin = _left;
                        }
                        if (curOrbitblock.xEnd > _srcLocationSize.Width - 1 - _right)
                        {
                            curOrbitblock.xEnd = _srcLocationSize.Width - 1 - _right;
                        }
                        if (curOrbitblock.Width == _srcLocationSize.Width && curOrbitblock.Height == _srcLocationSize.Height)
                        {
                            if (_xs != null && _ys != null)
                            {
                                srcBlockXs = _xs;
                                srcBlockYs = _ys;
                            }
                            else
                            {
                                srcBlockXs = ReadBlockDatas(_longitudeBand, curOrbitblock.xBegin, curOrbitblock.yBegin, curOrbitblock.Width, curOrbitblock.Height);
                                srcBlockYs = ReadBlockDatas(_latitudeBand, curOrbitblock.xBegin, curOrbitblock.yBegin, curOrbitblock.Width, curOrbitblock.Height);

                                TryApplyGeoInterceptSlope(srcBlockXs, srcBlockYs);
                                _rasterProjector.Transform(SpatialReferenceFactory.CreateSpatialReference(4326), srcBlockXs, srcBlockYs, _dstSpatialRef);
                            }
                        }
                        else
                        {
                            if (_xs != null && _ys != null)
                            {
                                GetBlockDatas(_xs, _ys, _srcLocationSize.Width, _srcLocationSize.Height, curOrbitblock.xBegin, curOrbitblock.yBegin, curOrbitblock.Width, curOrbitblock.Height, out srcBlockXs, out srcBlockYs);
                            }
                            else
                            {
                                srcBlockXs = ReadBlockDatas(_longitudeBand, curOrbitblock.xBegin, curOrbitblock.yBegin, curOrbitblock.Width, curOrbitblock.Height);
                                srcBlockYs = ReadBlockDatas(_latitudeBand, curOrbitblock.xBegin, curOrbitblock.yBegin, curOrbitblock.Width, curOrbitblock.Height);
                                TryApplyGeoInterceptSlope(srcBlockXs, srcBlockYs);
                                _rasterProjector.Transform(SpatialReferenceFactory.CreateSpatialReference(4326), srcBlockXs, srcBlockYs, _dstSpatialRef);
                            }
                        }
                    }
                    else
                    {
                        if (_xs != null && _ys != null)
                        {
                            GetEnvelope(_xs, _ys, _srcLocationSize.Width, _srcLocationSize.Height, blockEnvelope, out curOrbitblock);
                        }
                        else
                        {
                            //计算偏移。
                            GetEnvelope(tmpxs, tmpys, tmpWidth, tmpHeight, blockEnvelope, out curOrbitblock);
                            curOrbitblock = curOrbitblock.Zoom(bC, bC);
                        }
                        if (curOrbitblock.Width <= 0 || curOrbitblock.Height <= 0)      //当前分块不在图像内部
                        {
                            progress += _dstBandCount;
                            continue;
                        }
                        if (curOrbitblock.xBegin < _left)
                        {
                            curOrbitblock.xBegin = _left;
                        }
                        if (curOrbitblock.xEnd > _srcLocationSize.Width - 1 - _right)
                        {
                            curOrbitblock.xEnd = _srcLocationSize.Width - 1 - _right;
                        }
                        if (_xs != null && _ys != null)
                        {
                            GetBlockDatas(_xs, _ys, _srcLocationSize.Width, _srcLocationSize.Height, curOrbitblock.xBegin, curOrbitblock.yBegin, curOrbitblock.Width, curOrbitblock.Height, out srcBlockXs, out srcBlockYs);
                        }
                        else
                        {
                            srcBlockXs = ReadBlockDatas(_longitudeBand, curOrbitblock.xBegin, curOrbitblock.yBegin, curOrbitblock.Width, curOrbitblock.Height);
                            srcBlockYs = ReadBlockDatas(_latitudeBand, curOrbitblock.xBegin, curOrbitblock.yBegin, curOrbitblock.Width, curOrbitblock.Height);
                            TryApplyGeoInterceptSlope(srcBlockXs, srcBlockYs);
                            _rasterProjector.Transform(SpatialReferenceFactory.CreateSpatialReference(4326), srcBlockXs, srcBlockYs, _dstSpatialRef);
                        }
                    }
                    int  srcBlockJdWidth      = curOrbitblock.Width;
                    int  srcBlockJdHeight     = curOrbitblock.Height;
                    int  srcBlockImgWidth     = curOrbitblock.Width * imgLocationRatioX;
                    int  srcBlockImgHeight    = curOrbitblock.Height * imgLocationRatioY;
                    Size srcBlockLocationSize = new Size(srcBlockJdWidth, srcBlockJdHeight);
                    Size srcBlockImgSize      = new Size(srcBlockImgWidth, srcBlockImgHeight);
                    //亮温订正,天顶角修正:下面获取用到的部分经纬度和太阳高度角修正系数数据,下面修改为从临时文件直接读取。
                    float[] solarZenithData = null;
                    if (_isRadRef && _isSolarZenith)
                    {
                        if (_solarZenithCacheRaster != null)    //太阳天顶角数据
                        {
                            ReadBandData(out solarZenithData, _solarZenithCacheRaster, 1, curOrbitblock.xBegin, curOrbitblock.yBegin, srcBlockJdWidth, srcBlockJdHeight);
                        }
                        //亮温临边变暗订正,读取卫星天顶角数据。
                        //if (_isSensorZenith)
                        //    ReadBandData(out _sensorZenithData, _sensorSenithBand, curOrbitblock.xOffset, curOrbitblock.yBegin, curOrbitblock.Width, curOrbitblock.Height);
                        TryReadZenithData(curOrbitblock.xBegin, curOrbitblock.yBegin, curOrbitblock.Width, curOrbitblock.Height);
                    }

                    //计算当前分块的投影查算表
                    UInt16[] dstRowLookUpTable = new UInt16[bufferSize.Width * bufferSize.Height];
                    UInt16[] dstColLookUpTable = new UInt16[bufferSize.Width * bufferSize.Height];
                    if (imgLocationRatioX == 1)
                    {
                        _rasterProjector.ComputeIndexMapTable(srcBlockXs, srcBlockYs, srcBlockImgSize, bufferSize, blockEnvelope, _maxPrjEnvelope,
                                                              out dstRowLookUpTable, out dstColLookUpTable, null);
                    }
                    else
                    {
                        _rasterProjector.ComputeIndexMapTable(srcBlockXs, srcBlockYs, srcBlockLocationSize, srcBlockImgSize, bufferSize, blockEnvelope, //_maxPrjEnvelope,
                                                              out dstRowLookUpTable, out dstColLookUpTable, null, 0);
                    }
                    //执行投影
                    UInt16[] srcBandData = null;
                    UInt16[] dstBandData = new UInt16[bufferSize.Width * bufferSize.Height];
                    for (int i = 0; i < srcBands.Length; i++)  //读取原始通道值,投影到目标区域
                    {
                        if (progressCallback != null)
                        {
                            progress++;
                            percent = (int)(progress * 100 / progressCount);
                            progressCallback(percent, string.Format("投影完成{0}%", percent));
                        }
                        ReadImgBand(srcBands[i], curOrbitblock.xBegin * imgLocationRatioX, curOrbitblock.yBegin * imgLocationRatioY, srcBlockImgWidth, srcBlockImgHeight,
                                    new Size(srcBlockImgWidth, srcBlockImgHeight), out srcBandData);
                        //ReadImgBand(out srcBandData, i, curOrbitblock.xOffset * imgLocationRatioX, curOrbitblock.yBegin * imgLocationRatioY, srcBlockImgWidth, srcBlockImgHeight);
                        Size angleSize = new Size(srcBlockJdWidth, srcBlockJdHeight);

                        DoRadiation(srcBands[i], srcBandData, solarZenithData, srcBlockImgSize, angleSize);

                        _rasterProjector.Project <UInt16>(srcBandData, srcBlockImgSize, dstRowLookUpTable, dstColLookUpTable, bufferSize, dstBandData, 0, null);
                        srcBandData = null;
                        Band band = dstBands[i];
                        unsafe
                        {
                            fixed(UInt16 *ptr = dstBandData)
                            {
                                IntPtr bufferPtr    = new IntPtr(ptr);
                                int    blockOffsetY = blockHeight * blockYNo;
                                int    blockOffsetX = blockWidth * blockXNo;

                                band.WriteRaster(blockOffsetX, blockOffsetY, blockWidth, blockHeight, bufferPtr, bufferSize.Width, bufferSize.Height, DataType.GDT_UInt16, 0, 0);
                            }
                        }
                    }
                    srcBandData = null;
                    dstBandData = null;
                    GC.Collect();
                    ReleaseZenithData();
                    Size srcBufferSize = new Size(srcBlockImgWidth, srcBlockImgHeight);
                    ProjectAngle(bufferSize, srcBufferSize, blockWidth, blockHeight, blockYNo, blockXNo, curOrbitblock, dstRowLookUpTable, dstColLookUpTable, progressCallback);
                    ProjectExtBands(bufferSize, srcBufferSize, blockWidth, blockHeight, blockYNo, blockXNo, curOrbitblock, dstRowLookUpTable, dstColLookUpTable, progressCallback);
                    dstRowLookUpTable = null;
                    dstColLookUpTable = null;
                }
            }
        }
Пример #10
0
        /// <summary>
        /// 0、先生成目标文件,以防止目标空间不足。
        /// 1、计算查找表
        /// 2、读取通道数据
        /// 3、计算通道数据亮温
        /// 4、投影通道。
        /// </summary>
        private void ProjectToLDF(IRasterDataProvider srcRaster, NOAA_PrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback)
        {
            string outFormat   = prjSettings.OutFormat;
            string outfilename = prjSettings.OutPathAndFileName;
            string dstProj4    = dstSpatialRef.ToProj4String();

            int[] outBandNos   = prjSettings.OutBandNos;
            int   dstBandCount = outBandNos.Length;
            Size  srcSize      = new Size(srcRaster.Width, srcRaster.Height);
            Size  dstSize      = prjSettings.OutSize;
            Size  srcJdSize    = srcSize;

            using (IRasterDataDriver drv = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver)
            {
                PrjEnvelope dstEnvelope = prjSettings.OutEnvelope;
                string[]    options     = new string[] {
                    "INTERLEAVE=BSQ",
                    "VERSION=LDF",
                    "WITHHDR=TRUE",
                    "SPATIALREF=" + dstSpatialRef.ToProj4String(),
                    "MAPINFO={" + 1 + "," + 1 + "}:{" + dstEnvelope.MinX + "," + dstEnvelope.MaxY + "}:{" + prjSettings.OutResolutionX + "," + prjSettings.OutResolutionY + "}"
                    , "BANDNAMES=" + BandNameString(prjSettings.OutBandNos)
                };
                if (progressCallback != null)
                {
                    progressCallback(6, "生成输出文件");
                }
                using (IRasterDataProvider prdWriter = drv.Create(outfilename, dstSize.Width, dstSize.Height, dstBandCount, enumDataType.UInt16, options) as IRasterDataProvider)
                {
                    float outResolutionX = prjSettings.OutResolutionX;
                    float outResolutionY = prjSettings.OutResolutionY;
                    Size  outSize        = dstEnvelope.GetSize(outResolutionX, outResolutionY);
                    int   blockXNum      = 0;
                    int   blockYNum      = 0;
                    int   blockWidth     = 0;
                    int   blockHeight    = 0;
                    GetBlockNumber(outSize, out blockXNum, out blockYNum, out blockWidth, out blockHeight);
                    Size     dstBlockSize   = new Size(blockWidth, blockHeight);
                    UInt16[] dstRowBlockLUT = new UInt16[blockWidth * blockHeight];
                    UInt16[] dstColBlockLUT = new UInt16[blockWidth * blockHeight];
                    int      blockCount     = blockYNum * blockXNum;
                    int      progress       = 0;
                    int      percent        = 0;
                    int      progressCount  = blockCount * dstBandCount;
                    for (int blockYIndex = 0; blockYIndex < blockYNum; blockYIndex++)
                    {
                        for (int blockXIndex = 0; blockXIndex < blockXNum; blockXIndex++)
                        {
                            PrjEnvelope blockEnvelope = null;
                            Block       orbitBlock    = null; //经纬度数据集,计算轨道数据范围偏移
                            double[]    blockOrbitXs  = null;
                            double[]    blockOrbitYs  = null;
                            if (blockCount == 1)            //没分块的情况
                            {
                                orbitBlock = _orbitBlock;
                                if (_orbitBlock.Width == srcJdSize.Width && _orbitBlock.Height == srcJdSize.Height)
                                {
                                    blockOrbitXs = _xs;
                                    blockOrbitYs = _ys;
                                }
                                else                        //源
                                {
                                    GetBlockDatas(_xs, _ys, srcJdSize.Width, srcJdSize.Height, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height, out blockOrbitXs, out blockOrbitYs);
                                }
                                blockEnvelope = dstEnvelope;
                            }
                            else
                            {
                                //当前块的四角范围
                                double blockMinX = dstEnvelope.MinX + blockWidth * outResolutionX * blockXIndex;
                                double blockMaxX = blockMinX + blockWidth * outResolutionX;
                                double blockMaxY = dstEnvelope.MaxY - blockHeight * outResolutionY * blockYIndex;
                                double blockMinY = blockMaxY - blockHeight * outResolutionY;
                                blockEnvelope = new PrjEnvelope(blockMinX, blockMaxX, blockMinY, blockMaxY);
                                //根据当前输出块,反推出对应的源数据块起始行列
                                GetEnvelope(_xs, _ys, srcJdSize.Width, srcJdSize.Height, blockEnvelope, out orbitBlock);
                                if (orbitBlock.Width <= 0 || orbitBlock.Height <= 0) //当前分块不在图像内部
                                {
                                    progress += dstBandCount;
                                    continue;
                                }
                                GetBlockDatas(_xs, _ys, srcJdSize.Width, srcJdSize.Height, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height, out blockOrbitXs, out blockOrbitYs);
                            }
                            float[] solarZenithData = null;
                            if (prjSettings.IsRadiation && prjSettings.IsSolarZenith)
                            {
                                if (File.Exists(_szDataFilename))
                                {
                                    ReadBandData(out solarZenithData, _solarZenithCacheRaster, 1, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height);
                                }
                                TryReadZenithData(orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height);
                            }
                            Size orbitBlockSize = new Size(orbitBlock.Width, orbitBlock.Height);
                            _rasterProjector.ComputeIndexMapTable(blockOrbitXs, blockOrbitYs, orbitBlockSize, dstBlockSize, blockEnvelope, _maxPrjEnvelope, out dstRowBlockLUT, out dstColBlockLUT, null);
                            //执行投影
                            UInt16[] srcBandData = new UInt16[orbitBlock.Width * orbitBlock.Height];
                            UInt16[] dstBandData = new UInt16[blockWidth * blockHeight];
                            for (int i = 0; i < dstBandCount; i++)      //读取原始通道值,投影到目标区域
                            {
                                if (progressCallback != null)
                                {
                                    progress++;
                                    percent = progress * 100 / progressCount;
                                    progressCallback(percent, string.Format("投影第{0}/{1}块,第{2}/{3}通道", blockXIndex + blockYIndex, blockCount, i + 1, dstBandCount));
                                }
                                int bandNo = outBandNos[i];
                                ReadBandData(srcBandData, srcRaster, bandNo, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height);
                                if (prjSettings.IsRadiation)
                                {
                                    DoRadiation(srcBandData, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Size, bandNo, prjSettings.IsRadiation, prjSettings.IsSolarZenith, solarZenithData);
                                }
                                _rasterProjector.Project <UInt16>(srcBandData, orbitBlock.Size, dstRowBlockLUT, dstColBlockLUT, dstBlockSize, dstBandData, 0, null);
                                IRasterBand band = prdWriter.GetRasterBand(i + 1);
                                {
                                    unsafe
                                    {
                                        fixed(UInt16 *ptr = dstBandData)
                                        {
                                            IntPtr bufferPtr    = new IntPtr(ptr);
                                            int    blockOffsetY = blockYIndex * dstBlockSize.Height;
                                            int    blockOffsetX = blockXIndex * dstBlockSize.Width;

                                            band.Write(blockOffsetX, blockOffsetY, blockWidth, blockHeight, bufferPtr, enumDataType.UInt16, blockWidth, blockHeight);
                                        }
                                    }
                                }
                            }
                            ReleaseZenithData();
                            srcBandData  = null;
                            dstBandData  = null;
                            blockOrbitXs = null;
                            blockOrbitYs = null;
                        }
                    }
                    dstRowBlockLUT = null;
                    dstColBlockLUT = null;
                }
            }
        }
        private void ProjectToLDF0500(IRasterDataProvider srcRaster, Size srcLocationSize, EOS_MODIS_PrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback)
        {
            if (srcRaster == null || srcRaster.Width == 0 || srcRaster.Height == 0)
            {
                throw new Exception("投影250米MERSI数据失败:无法读取源数据,或者源数据高或宽为0。");
            }
            Size           srcDataSize  = new Size(srcRaster.Width, srcRaster.Height);
            string         outFormat    = prjSettings.OutFormat;
            string         outfilename  = prjSettings.OutPathAndFileName;
            string         dstProj4     = dstSpatialRef.ToProj4String();
            List <BandMap> bandMaps     = prjSettings.BandMapTable;
            int            dstBandCount = bandMaps.Count;
            Size           dstSize      = prjSettings.OutSize;

            using (IRasterDataDriver drv = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver)
            {
                PrjEnvelope dstEnvelope = prjSettings.OutEnvelope;
                string      mapInfo     = "MAPINFO={" + 1 + "," + 1 + "}:{" + dstEnvelope.MinX + "," + dstEnvelope.MaxY + "}:{" + prjSettings.OutResolutionX + "," + prjSettings.OutResolutionY + "}";
                using (IRasterDataProvider prdWriter = drv.Create(outfilename, dstSize.Width, dstSize.Height, dstBandCount,
                                                                  enumDataType.UInt16, "INTERLEAVE=BSQ", "VERSION=LDF", "SPATIALREF=" + dstProj4, mapInfo, "WITHHDR=TRUE") as IRasterDataProvider)
                {
                    //考虑分块
                    float outResolutionX = prjSettings.OutResolutionX;
                    float outResolutionY = prjSettings.OutResolutionY;
                    Size  outSize        = dstEnvelope.GetSize(outResolutionX, outResolutionY);
                    #region 计算分块个数、分块高宽
                    int blockXNum;
                    int blockYNum;
                    int blockWidth;
                    int blockHeight;
                    GetBlockNumber(outSize, out blockXNum, out blockYNum, out blockWidth, out blockHeight);
                    #endregion
                    Size blockSize = new Size(blockWidth, blockHeight);
                    for (int blockYIndex = 0; blockYIndex < blockYNum; blockYIndex++)
                    {
                        for (int blockXIndex = 0; blockXIndex < blockXNum; blockXIndex++)
                        {
                            //当前块的四角范围
                            double      blockMinX         = dstEnvelope.MinX + blockWidth * outResolutionX * blockXIndex;
                            double      blockMaxX         = blockMinX + blockWidth * outResolutionX;
                            double      blockMaxY         = dstEnvelope.MaxY - blockHeight * outResolutionY * blockYIndex;
                            double      blockMinY         = blockMaxY - blockHeight * outResolutionY;
                            PrjEnvelope blockEnvelope     = new PrjEnvelope(blockMinX, blockMaxX, blockMinY, blockMaxY);
                            UInt16[]    dstRowLookUpTable = new UInt16[blockWidth * blockHeight];
                            UInt16[]    dstColLookUpTable = new UInt16[blockWidth * blockHeight];
                            _rasterProjector.ComputeIndexMapTable(_xs, _ys, srcLocationSize, srcDataSize, blockSize, blockEnvelope,
                                                                  out dstRowLookUpTable, out dstColLookUpTable, progressCallback);
                            //执行投影
                            UInt16[] srcBandData = null;
                            UInt16[] dstBandData = new UInt16[blockWidth * blockHeight];
                            for (int i = 0; i < dstBandCount; i++)  //读取原始通道值,投影到目标区域
                            {
                                BandMap bandMap = bandMaps[i];
                                ReadBandData(out srcBandData, bandMap.File, bandMap.DatasetName, bandMap.BandIndex, srcDataSize);
                                if (prjSettings.IsRadiation)        //亮温转换,这里处理的不好,如果是做了一个小块的分幅,这里花的代价太高,
                                {
                                    DoRadiation(srcBandData, srcDataSize, srcLocationSize, bandMap.DatasetName, bandMap.BandIndex, srcRaster, prjSettings.IsRadiation, prjSettings.IsSolarZenith);
                                }
                                _rasterProjector.Project <UInt16>(srcBandData, srcDataSize, dstRowLookUpTable, dstColLookUpTable, blockSize, dstBandData, 0, progressCallback);
                                using (IRasterBand band = prdWriter.GetRasterBand(i + 1))
                                {
                                    unsafe
                                    {
                                        fixed(UInt16 *ptr = dstBandData)
                                        {
                                            IntPtr bufferPtr    = new IntPtr(ptr);
                                            int    blockOffsetY = blockYIndex * blockSize.Height;
                                            int    blockOffsetX = blockWidth * blockXIndex;

                                            band.Write(blockOffsetX, blockOffsetY, blockWidth, blockHeight, bufferPtr, enumDataType.UInt16, blockWidth, blockHeight);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #12
0
        // 2
        private void ProjectRaster(AbstractWarpDataset srcRaster, FilePrjSettings prjSettings,
                                   AbstractWarpDataset prdWriter, Action <int, string> progressCallback, UInt16 fillValue, int beginBandIndex,
                                   double dataWeight, float zoom)
        {
            var timer = System.Diagnostics.Stopwatch.StartNew();

            //输出数据类型
            float outResolutionX = prjSettings.OutResolutionX;
            float outResolutionY = prjSettings.OutResolutionY;
            Size  outSize        = prjSettings.OutSize;
            int   outWidth       = outSize.Width;
            int   outHeight      = outSize.Height;
            int   outBandCount   = prjSettings.OutBandNos.Length;

            if (progressCallback != null)
            {
                progressCallback(_readyProgress++, "投影准备");
            }
            int      srcHeight       = srcRaster.Height;
            int      srcWidth        = srcRaster.Width;
            PrjPoint outLeftTopPoint = prjSettings.OutEnvelope.LeftTop;
            //源数据的分辨率
            float srcResolutionX = Convert.ToSingle(_srcGeoTrans[1]);
            float srcResolutionY = Math.Abs(Convert.ToSingle(_srcGeoTrans[5]));
            //输入数据的大小
            Size srcSize = new Size()
            {
                Width = srcWidth, Height = srcHeight
            };
            //输出数据的左上角地理坐标
            double outLtPointX = outLeftTopPoint.X;
            double outLtPointY = outLeftTopPoint.Y;
            //输入数据源的坐标范围
            PrjEnvelope srcEnvelope = new PrjEnvelope(_srcGeoTrans[0], _srcGeoTrans[0] + srcWidth * _srcGeoTrans[1],
                                                      _srcGeoTrans[3] + srcHeight * _srcGeoTrans[5], _srcGeoTrans[3], _srcSpatialRef);
            ulong mem = MemoryHelper.GetAvalidPhyMemory();

            mem = mem > 10.0 * 1024 * 1024 * 1024 ? Convert.ToUInt64(10.0 * 1024 * 1024 * 1024) : mem;
            ulong maxLimit = mem / (6 * 8);
            int   rowStep  = (int)(maxLimit / (UInt32)outWidth);

            if (rowStep == 0)
            {
                rowStep = 1;
            }
            if (rowStep > outHeight)
            {
                rowStep = outHeight;
            }
            int  stepCount             = (int)(Math.Ceiling((double)outHeight / rowStep));
            int  percent               = 0;
            int  progress              = 0;
            int  progressCount         = outBandCount * stepCount + stepCount * 2;
            long stepGeolocationTime   = 0,
                 stepReadDataTime      = 0,
                 stepRadiationTime     = 0,
                 stepProjectRasterTime = 0,
                 stepWriteDataTime     = 0;

            for (int oRow = 0; oRow < outHeight; oRow += rowStep)
            {
                if (progressCallback != null)
                {
                    percent++;
                    progress = percent * 100 / progressCount;
                    progressCallback(progress, string.Format("投影完成{0}%", progress));
                }

                if (oRow + rowStep > outHeight)
                {
                    rowStep = outHeight - oRow;
                }

                //经纬度数据
                double[] xs, ys;
                UInt16[] rows, cols;
                try
                {
                    xs   = new double[outWidth * rowStep];
                    ys   = new double[outWidth * rowStep];
                    rows = new UInt16[outWidth * rowStep];
                    cols = new UInt16[outWidth * rowStep];
                }
                catch (Exception ex)
                {
                    throw;
                }

                Size  srcStepSize = new Size();
                Block oBlock, tBlock;
                timer.Restart();

                #region 初始化查找表

                {
                    double oY = oRow * outResolutionY;
                    Parallel.For(0, rowStep, j =>
                    {
                        double x;
                        double y;
                        int index;
                        y = outLtPointY - j * outResolutionY - oY;
                        for (int i = 0; i < outWidth; i++)
                        {
                            x         = outLtPointX + i * outResolutionX;
                            index     = i + j * outWidth;
                            xs[index] = x;
                            ys[index] = y;
                        }
                    });
                    GeosInverCorrection(_dstSpatialRef, xs, ys);
                    _projectionTransform.InverTransform(xs, ys);
                    PrjEnvelope tEnvelope = PrjEnvelope.GetEnvelope(xs, ys, null);
                    tEnvelope.Extend(srcResolutionX, srcResolutionY * 4);
                    tEnvelope = PrjEnvelope.Intersect(tEnvelope, srcEnvelope);
                    if (tEnvelope == null || tEnvelope.IsEmpty)
                    {
                        continue;
                    }
                    Size tSize = tEnvelope.GetSize(srcResolutionX, srcResolutionY);
                    PrjBlockHelper.ComputeBlock(srcEnvelope, srcSize, tEnvelope, tSize, out oBlock, out tBlock);
                    int srcStepWidth  = oBlock.xEnd - oBlock.xBegin;
                    int srcStepHeight = oBlock.yEnd - oBlock.yBegin;
                    srcStepSize = new Size(srcStepWidth, srcStepHeight);

                    double srcStepLeftTopX     = tEnvelope.MinX;
                    double srcStepLeftTopY     = tEnvelope.MaxY;
                    double srcStepRightBottomX = tEnvelope.MaxX;
                    double srcStepRightBottomY = tEnvelope.MinY;

                    if (progressCallback != null)
                    {
                        percent++;
                        progress = percent * 100 / progressCount;
                    }

                    Parallel.For(0, rowStep, j =>
                    {
                        double x;
                        double y;
                        int index;
                        for (int i = 0; i < outWidth; i++)
                        {
                            index = i + j * outWidth;
                            x     = xs[index];
                            y     = ys[index];
                            if (x >= srcStepLeftTopX && x <= srcStepRightBottomX && y <= srcStepLeftTopY &&
                                y >= srcStepRightBottomY)
                            {
                                cols[index] = (UInt16)((x - srcStepLeftTopX) / srcResolutionX + 0.5);
                                rows[index] = (UInt16)((srcStepLeftTopY - y) / srcResolutionY + 0.5);
                            }
                        }
                    });
                    xs = null;
                    ys = null;
                }

                #endregion

                stepGeolocationTime += timer.ElapsedMilliseconds;

                //输入波段数据缓冲区
                UInt16[] srcBandData = new UInt16[srcStepSize.Width * srcStepSize.Height];
                //输出波段数据缓冲区
                UInt16[] dstBandData = new UInt16[outWidth * rowStep];
                //逐波段写入数据
                for (int b = beginBandIndex; b < outBandCount + beginBandIndex; b++)
                {
                    if (progressCallback != null)
                    {
                        percent++;
                        progress = percent * 100 / progressCount;
                    }

                    var bandNum = b - beginBandIndex;
                    timer.Restart();
                    ReadBandData <UInt16>(srcBandData, bandNum, oBlock.xBegin, oBlock.yBegin, srcStepSize.Width,
                                          srcStepSize.Height, DataType.GDT_UInt16);
                    stepReadDataTime += timer.ElapsedMilliseconds;

                    Size srcBlockSize = new Size(srcStepSize.Width, srcStepSize.Height);
                    //进行辐射定标
                    timer.Restart();
                    DoRadiation(srcRaster, bandNum, srcBandData, null, srcBlockSize, srcBlockSize);
                    stepRadiationTime += timer.ElapsedMilliseconds;

                    //用于测试全图输出结果,用于查看插值的效果:
#if DebugEaseGrid
                    GCHandle hTe = GCHandle.Alloc(srcBandData, GCHandleType.Pinned);
                    try
                    { Random  random    = new Random(12);
                      IntPtr  bufferPtr = hTe.AddrOfPinnedObject();
                      Int16[] tmp       = new Int16[srcBandData.Length];
                      for (int i = 0; i < srcBandData.Length; i++)
                      {
                          tmp[i] = (Int16)random.Next(200, 255);
                      }
                      Marshal.Copy(tmp, 0, bufferPtr, tmp.Length); }
                    finally
                    {
                        hTe.Free();
                    }
#endif
                    //Size outStepSize = new Size(outWidth, rowStep);
                    timer.Restart();
                    _rasterProjector.Project <UInt16>(srcBandData, srcStepSize, rows, cols, new Size(outWidth, rowStep),
                                                      dstBandData, fillValue, 0, null);
                    stepProjectRasterTime += timer.ElapsedMilliseconds;

                    timer.Restart();
                    if (dataWeight == 1)
                    {
                        WriteDataToLDF <UInt16>(prdWriter, DataType.GDT_UInt16, outWidth, rowStep, oRow, dstBandData, b);
                    }
                    else
                    {
                        WriteDataToLDF <UInt16>(prdWriter, DataType.GDT_UInt16, outWidth, rowStep, oRow, dstBandData, b,
                                                dataWeight, zoom);
                    }
                    stepWriteDataTime += timer.ElapsedMilliseconds;
                }

                rows        = null;
                rows        = null;
                srcBandData = null;
                dstBandData = null;
            }

            Console.WriteLine($"坐标投影转换:{stepGeolocationTime}ms");
            Console.WriteLine($"读取波段数据:{stepReadDataTime}ms");
            Console.WriteLine($"定标波段数据:{stepRadiationTime}ms");
            Console.WriteLine($"投影波段数据:{stepProjectRasterTime}ms");
            Console.WriteLine($"写入波段数据:{stepWriteDataTime}ms");
        }
Пример #13
0
        /// <summary>
        /// 0、先生成目标文件,以防止目标空间不足。
        /// 1、计算查找表
        /// 2、读取通道数据
        /// 3、计算通道数据亮温
        /// 4、投影通道。
        /// </summary>
        private void ProjectToLDF(IRasterDataProvider srcRaster, NOAA_PrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback)
        {
            string outFormat   = prjSettings.OutFormat;
            string outfilename = prjSettings.OutPathAndFileName;
            string dstProj4    = dstSpatialRef.ToProj4String();

            int[] outBandNos   = prjSettings.OutBandNos;
            int   dstBandCount = outBandNos.Length;
            Size  srcSize      = new Size(srcRaster.Width, srcRaster.Height);
            Size  dstSize      = prjSettings.OutSize;
            Size  srcJdSize    = srcSize;

            using (IRasterDataDriver drv = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver)
            {
                PrjEnvelope dstEnvelope = prjSettings.OutEnvelope;

                List <string> opts = new List <string>();
                opts.AddRange(new string[] {
                    "INTERLEAVE=BSQ",
                    "VERSION=LDF",
                    "WITHHDR=TRUE",
                    "SPATIALREF=" + dstSpatialRef.ToProj4String(),
                    "MAPINFO={" + 1 + "," + 1 + "}:{" + dstEnvelope.MinX + "," + dstEnvelope.MaxY + "}:{" + prjSettings.OutResolutionX + "," + prjSettings.OutResolutionY + "}",
                    "BANDNAMES=" + BandNameString(prjSettings.OutBandNos),
                    "SENSOR=AVHRR"
                });
                if (srcRaster.DataIdentify != null)
                {
                    string   satellite = srcRaster.DataIdentify.Satellite;
                    DateTime dt        = srcRaster.DataIdentify.OrbitDateTime;
                    bool     asc       = srcRaster.DataIdentify.IsAscOrbitDirection;
                    if (!string.IsNullOrWhiteSpace(satellite))
                    {
                        opts.Add("SATELLITE=" + satellite);
                    }
                    if (dt != DateTime.MinValue && dt != DateTime.MaxValue)
                    {
                        opts.Add("DATETIME=" + dt.ToString("yyyy/MM/dd HH:mm"));
                    }
                    opts.Add("ORBITDIRECTION=" + (asc ? "ASC" : "DESC"));
                }
                if (progressCallback != null)
                {
                    progressCallback(6, "生成输出文件");
                }
                using (IRasterDataProvider prdWriter = drv.Create(outfilename, dstSize.Width, dstSize.Height, dstBandCount, enumDataType.UInt16, opts.ToArray()) as IRasterDataProvider)
                {
                    float outResolutionX = prjSettings.OutResolutionX;
                    float outResolutionY = prjSettings.OutResolutionY;
                    Size  outSize        = dstEnvelope.GetSize(outResolutionX, outResolutionY);
                    int   blockXNum      = 0;
                    int   blockYNum      = 0;
                    int   blockWidth     = 0;
                    int   blockHeight    = 0;
                    GetBlockNumber(outSize, out blockXNum, out blockYNum, out blockWidth, out blockHeight);
                    Size     dstBlockSize   = new Size(blockWidth, blockHeight);
                    UInt16[] dstRowBlockLUT = new UInt16[blockWidth * blockHeight];
                    UInt16[] dstColBlockLUT = new UInt16[blockWidth * blockHeight];
                    int      blockCount     = blockYNum * blockXNum;
                    progress      = 0;
                    progressCount = blockCount * (dstBandCount + (_angleBands == null ? 0 : _angleBands.Length));
                    percent       = 0;
                    for (int blockYIndex = 0; blockYIndex < blockYNum; blockYIndex++)
                    {
                        for (int blockXIndex = 0; blockXIndex < blockXNum; blockXIndex++)
                        {
                            PrjEnvelope blockEnvelope = null;
                            Block       orbitBlock    = null; //经纬度数据集,计算轨道数据范围偏移
                            double[]    blockOrbitXs  = null;
                            double[]    blockOrbitYs  = null;
                            if (blockCount == 1)            //没分块的情况
                            {
                                orbitBlock = _orbitBlock;
                                if (_orbitBlock.Width == srcJdSize.Width && _orbitBlock.Height == srcJdSize.Height)
                                {
                                    blockOrbitXs = _xs;
                                    blockOrbitYs = _ys;
                                }
                                else                        //源
                                {
                                    GetBlockDatas(_xs, _ys, srcJdSize.Width, srcJdSize.Height, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height, out blockOrbitXs, out blockOrbitYs);
                                }
                                blockEnvelope = dstEnvelope;
                            }
                            else
                            {
                                //当前块的四角范围
                                double blockMinX = dstEnvelope.MinX + blockWidth * outResolutionX * blockXIndex;
                                double blockMaxX = blockMinX + blockWidth * outResolutionX;
                                double blockMaxY = dstEnvelope.MaxY - blockHeight * outResolutionY * blockYIndex;
                                double blockMinY = blockMaxY - blockHeight * outResolutionY;
                                blockEnvelope = new PrjEnvelope(blockMinX, blockMaxX, blockMinY, blockMaxY);
                                //根据当前输出块,反推出对应的源数据块起始行列
                                GetEnvelope(_xs, _ys, srcJdSize.Width, srcJdSize.Height, blockEnvelope, out orbitBlock);
                                if (orbitBlock.Width <= 0 || orbitBlock.Height <= 0) //当前分块不在图像内部
                                {
                                    progress += dstBandCount;
                                    continue;
                                }
                                GetBlockDatas(_xs, _ys, srcJdSize.Width, srcJdSize.Height, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height, out blockOrbitXs, out blockOrbitYs);
                            }
                            float[] solarZenithData = null;
                            if (prjSettings.IsRadiation && prjSettings.IsSolarZenith)
                            {
                                if (File.Exists(_szDataFilename))
                                {
                                    ReadBandData(out solarZenithData, _solarZenithCacheRaster, 1, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height);
                                }
                                TryReadZenithData(orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height);
                            }
                            Size orbitBlockSize = new Size(orbitBlock.Width, orbitBlock.Height);
                            _rasterProjector.ComputeIndexMapTable(blockOrbitXs, blockOrbitYs, orbitBlockSize, dstBlockSize, blockEnvelope, _maxPrjEnvelope, out dstRowBlockLUT, out dstColBlockLUT, null);
                            //执行投影
                            UInt16[] srcBandData = new UInt16[orbitBlock.Width * orbitBlock.Height];
                            UInt16[] dstBandData = new UInt16[blockWidth * blockHeight];
                            for (int i = 0; i < dstBandCount; i++)      //读取原始通道值,投影到目标区域
                            {
                                if (progressCallback != null)
                                {
                                    progress++;
                                    percent = progress * 100 / progressCount;
                                    progressCallback(percent, string.Format("投影完成{0}%", percent));
                                }
                                int bandNo = outBandNos[i];
                                ReadBandData(srcBandData, srcRaster, bandNo, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height);
                                if (prjSettings.IsRadiation)
                                {
                                    DoRadiation(srcBandData, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Size, bandNo, prjSettings.IsRadiation, prjSettings.IsSolarZenith, solarZenithData);
                                }
                                _rasterProjector.Project <UInt16>(srcBandData, orbitBlock.Size, dstRowBlockLUT, dstColBlockLUT, dstBlockSize, dstBandData, 0, null);
                                IRasterBand band = prdWriter.GetRasterBand(i + 1);
                                {
                                    unsafe
                                    {
                                        fixed(UInt16 *ptr = dstBandData)
                                        {
                                            IntPtr bufferPtr    = new IntPtr(ptr);
                                            int    blockOffsetY = blockYIndex * dstBlockSize.Height;
                                            int    blockOffsetX = blockXIndex * dstBlockSize.Width;

                                            band.Write(blockOffsetX, blockOffsetY, blockWidth, blockHeight, bufferPtr, enumDataType.UInt16, blockWidth, blockHeight);
                                        }
                                    }
                                }
                            }
                            ReleaseZenithData();
                            srcBandData  = null;
                            dstBandData  = null;
                            blockOrbitXs = null;
                            blockOrbitYs = null;
                            Size srcBufferSize = new Size(orbitBlock.Width, orbitBlock.Height);
                            ProjectAngle(dstBlockSize, srcBufferSize, blockWidth, blockHeight, blockYIndex, blockXIndex, orbitBlock, dstRowBlockLUT, dstColBlockLUT, progressCallback);
                        }
                    }
                    dstRowBlockLUT = null;
                    dstColBlockLUT = null;
                }
            }
        }