Ejemplo n.º 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);
                                }
                            }
                        }
                    }
                }
            }
        }
        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);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }