/// <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); } } } } } } } } }