Пример #1
0
        /// <summary>
        /// 0、先生成目标文件,以防止目标空间不足。
        /// 1、计算查找表
        /// 2、对所有波段执行投影
        /// </summary>
        private void ProjectToLDF(IRasterDataProvider srcRaster, FY3_VIRR_PrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback)
        {
            string         outFormat    = prjSettings.OutFormat;
            string         outfilename  = prjSettings.OutPathAndFileName;
            string         dstProj4     = dstSpatialRef.ToProj4String();
            List <BandMap> bandMaps     = prjSettings.BandMapTable;
            int            dstBandCount = bandMaps.Count;
            Size           srcSize      = new Size(srcRaster.Width, srcRaster.Height);
            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)
                {
                    //计算查找表
                    //ISpatialReference srcSpatialRef = srcRaster.SpatialRef;
                    UInt16[] dstRowLookUpTable = new UInt16[dstSize.Width * dstSize.Height];
                    UInt16[] dstColLookUpTable = new UInt16[dstSize.Width * dstSize.Height];
                    _rasterProjector.ComputeIndexMapTable(_xs, _ys, srcSize, dstSize, dstEnvelope, _maxPrjEnvelope,
                                                          out dstRowLookUpTable, out dstColLookUpTable, progressCallback);
                    //执行投影
                    UInt16[] srcBandData = new UInt16[srcSize.Width * srcSize.Height];
                    UInt16[] dstBandData = new UInt16[dstSize.Width * dstSize.Height];
                    int      progress    = 0;
                    for (int i = 0; i < dstBandCount; i++)      //读取原始通道值,投影到目标区域
                    {
                        if (progressCallback != null)
                        {
                            progress = (int)((i + 1) * 100 / dstBandCount);
                            progressCallback(progress, string.Format("投影第{0}共{1}通道", i + 1, dstBandCount));
                        }
                        BandMap bandMap = bandMaps[i];
                        ReadBandData(srcBandData, bandMap.File, bandMap.DatasetName, bandMap.BandIndex, srcSize);
                        if (prjSettings.IsRadiation)
                        {
                            DoRadiation(srcBandData, srcSize, bandMap.DatasetName, bandMap.BandIndex, prjSettings.IsSolarZenith);
                        }
                        _rasterProjector.Project <UInt16>(srcBandData, srcSize, dstRowLookUpTable, dstColLookUpTable, dstSize, dstBandData, 0, progressCallback);
                        using (IRasterBand band = prdWriter.GetRasterBand(i + 1))
                        {
                            unsafe
                            {
                                fixed(UInt16 *ptr = dstBandData)
                                {
                                    IntPtr bufferPtr = new IntPtr(ptr);

                                    band.Write(0, 0, band.Width, band.Height, bufferPtr, enumDataType.UInt16, band.Width, band.Height);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #2
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;
                }
            }
        }