public override void Project(AbstractWarpDataset srcRaster, FilePrjSettings prjSettings, SpatialReference dstSpatialRef, Action <int, string> progressCallback, double weight, float zoom) { SpatialReference srcSpatialRef = (srcRaster.SpatialRef); _projectionTransform = ProjectionTransformFactory.GetProjectionTransform(srcSpatialRef, dstSpatialRef); ArgsCheck(srcRaster, prjSettings, dstSpatialRef); ReadySession(srcRaster, prjSettings, dstSpatialRef, progressCallback); if (prjSettings.OutEnvelope == null || prjSettings.OutEnvelope == PrjEnvelope.Empty) { PrjEnvelope dstEnvelope = null; float srcResolutionX = srcRaster.ResolutionX; float srcResolutionY = srcRaster.ResolutionY; double srcLeftTopX = srcRaster.GetEnvelope().MinX; double srcLeftTopY = srcRaster.GetEnvelope().MaxY; int srcWidth = srcRaster.Width; int srcHeight = srcRaster.Height; Size srcSize = new Size(srcWidth, srcHeight); int wSample = 1; int hSample = 1; if (srcWidth > 1000) { wSample = srcWidth / 1000; } if (srcHeight > 1000) { hSample = srcHeight / 1000; } double[] xs = new double[(srcWidth / wSample) * (srcHeight / hSample)]; double[] ys = new double[(srcWidth / wSample) * (srcHeight / hSample)]; int index = 0;//非真实的索引号,采样后的 for (int rowInx = 0; rowInx <= (srcHeight - hSample); rowInx += hSample) { for (int colInx = 0; colInx <= (srcWidth - wSample); colInx += wSample) { xs[index] = srcLeftTopX + colInx * srcResolutionX; ys[index] = srcLeftTopY - rowInx * srcResolutionY; index++; } } _rasterProjector.ComputeDstEnvelope(srcSpatialRef, xs, ys, srcSize, dstSpatialRef, out dstEnvelope, null); prjSettings.OutEnvelope = dstEnvelope; } GC.Collect(); ProjectToLDF(srcRaster, prjSettings, dstSpatialRef, progressCallback, weight, zoom); }
public override AbstractWarpDataset Project(AbstractWarpDataset srcRaster, FilePrjSettings prjSettings, AbstractWarpDataset dstRaster, int beginBandIndex, Action <int, string> progressCallback) { if (dstRaster == null) { return(null); } try { ReadyArgs(srcRaster, prjSettings, (dstRaster.SpatialRef), progressCallback); _prjSettings.OutPathAndFileName = dstRaster.fileName; _outfilename = dstRaster.fileName; _outResolutionX = dstRaster.ResolutionX; _outResolutionY = dstRaster.ResolutionY; _dstEnvelope = _prjSettings.OutEnvelope = new PrjEnvelope( dstRaster.GetEnvelope().MinX, dstRaster.GetEnvelope().MaxX, dstRaster.GetEnvelope().MinY, dstRaster.GetEnvelope().MaxY, _dstSpatialRef); try { Size outSize = new Size(dstRaster.Width, dstRaster.Height); //角度输出,其中的BANDNAME需要在ReadyAngleFiles()方法中获取 string[] angleOptions = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + _dstSpatialRef.ExportToProj4(), "MAPINFO={" + 1 + "," + 1 + "}:{" + _prjSettings.OutEnvelope.MinX + "," + _prjSettings.OutEnvelope.MaxY + "}:{" + _outResolutionX + "," + _outResolutionY + "}" }; ReadyAngleFiles(_angleDataProvider, _outfilename, _prjSettings, outSize, angleOptions); UpdateNodataValue(dstRaster); ProjectToLDF(srcRaster, dstRaster, beginBandIndex, progressCallback); return(dstRaster); } catch (IOException ex) { if (ex.Message == "磁盘空间不足。\r\n" && File.Exists(_outfilename)) { File.Delete(_outfilename); } throw ex; } finally { if (dstRaster != null) { dstRaster.Dispose(); dstRaster = null; } } } catch { EndSession(); TryDeleteCurCatch(); throw; } finally { if (_curSession == null) { EndSession(); if (prjSettings.IsClearPrjCache) { TryDeleteCurCatch(); } } } }
/// <summary> /// 投影 /// </summary> /// <param name="srcRaster"></param> /// <param name="prjSettings"></param> /// <param name="dstRaster"></param> /// <param name="beginBandIndex"></param> /// <param name="progressCallback"></param> /// <returns></returns> public override AbstractWarpDataset Project(AbstractWarpDataset srcRaster, FilePrjSettings prjSettings, AbstractWarpDataset dstRaster, int beginBandIndex, Action <int, string> progressCallback) { if (dstRaster == null) { return(null); } try { _dstSpatialRef = dstRaster.SpatialRef; var coordEnv = dstRaster.GetEnvelope(); prjSettings.OutEnvelope = new PrjEnvelope() { Srs = _dstSpatialRef, MinX = coordEnv.MinX, MinY = coordEnv.MinY, MaxX = coordEnv.MaxX, MaxY = coordEnv.MaxY }; ReadyArgs(srcRaster, prjSettings, _dstSpatialRef, progressCallback); string outfilename = _prjSettings.OutPathAndFileName; try { Size outSize = new Size(dstRaster.Width, dstRaster.Height); string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + _dstSpatialRef.ExportToProj4(), "MAPINFO={" + 1 + "," + 1 + "}:{" + _prjSettings.OutEnvelope.MinX + "," + _prjSettings.OutEnvelope.MaxY + "}:{" + dstRaster.ResolutionX + "," + dstRaster.ResolutionY + "}" , "BANDNAMES=" + BandNameString(_prjSettings.OutBandNos) }; //ReadyAngleFiles(_angleDataProvider, outfilename, _prjSettings, outSize, options); ProjectRaster(srcRaster, dstRaster, beginBandIndex, progressCallback); return(dstRaster); } catch (IOException ex) { if (ex.Message == "磁盘空间不足。\r\n" && File.Exists(outfilename)) { File.Delete(outfilename); } throw ex; } finally { if (dstRaster != null) { dstRaster.Dispose(); dstRaster = null; } } } catch { EndSession(); TryDeleteCurCatch(); throw; } finally { if (_curSession == null) { EndSession(); if (prjSettings.IsClearPrjCache) { TryDeleteCurCatch(); } } } }
private void ProjectRaster <T>(AbstractWarpDataset srcRaster, FilePrjSettings prjSettings, Action <int, string> progressCallback, AbstractWarpDataset prdWriter, T fillValue, double dataWeight, float zoom) { DataType 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.GetEnvelope().MinX, srcRaster.GetEnvelope().MaxX, srcRaster.GetEnvelope().MinY, srcRaster.GetEnvelope().MaxY, null); ulong mem = MemoryHelper.GetAvalidPhyMemory(); #if !WIN64 mem = mem < 800 * 1024 * 1024 ? mem : 800 * 1024 * 1024; #endif ulong maxLimit = mem / (6 * 8 * 2); 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; 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; } }