private void GetBlockNumber(Size size, out int blockXNum, out int blockYNum, out int blockWidth, out int blockHeight) { uint mem = MemoryHelper.GetAvalidPhyMemory(); int w = size.Width; int h = size.Height; blockXNum = 1; blockYNum = 1; blockWidth = w; blockHeight = h; int MaxX = 8000; int MaxY = 2000; if (mem / 1024 / 1024 > 1500)//1.5GB以上 { MaxX = w; MaxY = 16000000 / w; } else if (mem / 1024 / 1024 > 800) { MaxX = w; MaxY = 8000000 / w; } else if (mem / 1024 / 1024 > 400) { MaxX = w; MaxY = 2000000 / w; } else if (mem / 1024 / 1024 > 200) { MaxX = w; MaxY = 1000000 / w; } else if (mem / 1024 / 1024 > 100) { MaxX = w; MaxY = 500000 / w; } else { throw new Exception("当前系统资源不足以完成该操作,请释放部分资源后再试。"); } if (size.Width * size.Height <= MaxX * MaxY) { return; } while (blockWidth > MaxX) { blockXNum++; blockWidth = (int)Math.Floor((double)w / blockXNum); } while (blockHeight > MaxY) { blockYNum++; blockHeight = (int)Math.Floor((double)h / blockYNum); } }
/// <summary> /// 限制当前进程内存, /// 剩余内存限制(系统可用内存最低限制) /// 已使用内存限制(系统已用内存最高限制) /// </summary> /// <param name="avalidPhyMemoryMin">(当前操作系统)剩余内存限制(MB)</param> /// <param name="usedMemMax">(当前应用程序)已使用内存限制(MB)</param> public static void MemoryNeed(int avalidPhyMemoryMin, int usedMemMax) { uint avalidPhyMemory = MemoryHelper.GetAvalidPhyMemory(); long usedMem = MemoryHelper.WorkingSet64(); if (avalidPhyMemory < avalidPhyMemoryMin * 1024 * 1024 || usedMem > usedMemMax * 1024 * 1024) { throw new Exception(string.Format("当前系统资源不足以完成该操作,请释放部分资源后再试,剩余{0}<{1},已使用{2}<{3}。", avalidPhyMemory / (1024f * 1024), avalidPhyMemoryMin, usedMem / (1024f * 1024), usedMemMax)); } }
private void GetBlockNumber(Size size, out int blockXNum, out int blockYNum, out int blockWidth, out int blockHeight) { int w = size.Width; int h = size.Height; blockXNum = 1; blockYNum = 1; blockWidth = w; blockHeight = h; int MaxX = 7000; int MaxY = 2000; uint mem = MemoryHelper.GetAvalidPhyMemory(); //系统剩余内存 long workingSet64 = MemoryHelper.WorkingSet64(); //为该进程已分配内存 if (mem < 200 * 1024.0f * 1024) { throw new Exception("当前系统资源不足以完成该操作,请释放部分资源后再试。"); } double usemem = mem;//; #if !WIN64 usemem = mem > 1800 * 1024.0f * 1024 - workingSet64 ? 1800 * 1024.0f * 1024 - workingSet64 : mem - workingSet64; #endif MaxY = (int)(usemem / 100 / w); MaxY = MaxY < 2000 ? 2000 : MaxY; if (size.Width * size.Height <= MaxX * MaxY) { return; } while (blockWidth > MaxX) { blockXNum++; blockWidth = (int)Math.Floor((double)w / blockXNum); } while (blockHeight > MaxY) { blockYNum++; blockHeight = (int)Math.Floor((double)h / blockYNum); } }
/// <summary> /// 投影操作-重载方法 /// </summary> /// <typeparam name="T">传递的数据集数据类型</typeparam> /// <param name="srcRaster">原始的数据驱动</param> /// <param name="prjSettings">投影设置类对象</param> /// <param name="progressCallback">回调</param> /// <param name="outhdf5name">导出的hdf5</param> /// <param name="fillValue">填充值?</param> private void ProjectRaster(IRasterDataProvider srcRaster, FilePrjSettings prjSettings, Action <int, string> progressCallback, Dictionary <string, H5T.H5Type> dataSets) { enumDataType dataType = enumDataType.UInt16; 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 progressCount = outBandCount * stepCount + stepCount * 2; H5FileId fileId = H5F.create(prjSettings.OutPathAndFileName, H5F.CreateMode.ACC_TRUNC); List <string> listdatasets = new List <string>(); foreach (string name in dataSets.Keys) { listdatasets.Add(name); } HDF5.Hdf5Operator oper = new HDF5.Hdf5Operator(srcRaster.fileName); for (int bandnum = 0; bandnum < outBandCount; bandnum++) { enumDataType systype = enumDataType.Unknow; H5T.H5Type h5filetype = dataSets[listdatasets[bandnum]]; systype = GetSysDataType(dataSets[listdatasets[bandnum]]); switch (systype) { case enumDataType.Int16: RastAndProject <Int16>(outSize, h5filetype, fileId, listdatasets[bandnum], progressCallback, outWidth, outHeight, rowStep, srcRaster, prjSettings, bandnum, 0, oper); break; case enumDataType.Int32: RastAndProject <Int32>(outSize, h5filetype, fileId, listdatasets[bandnum], progressCallback, outWidth, outHeight, rowStep, srcRaster, prjSettings, bandnum, 0, oper); break; case enumDataType.Int64: RastAndProject <Int64>(outSize, h5filetype, fileId, listdatasets[bandnum], progressCallback, outWidth, outHeight, rowStep, srcRaster, prjSettings, bandnum, 0, oper); break; case enumDataType.UInt16: RastAndProject <UInt16>(outSize, h5filetype, fileId, listdatasets[bandnum], progressCallback, outWidth, outHeight, rowStep, srcRaster, prjSettings, bandnum, 0, oper); break; case enumDataType.UInt32: RastAndProject <UInt32>(outSize, h5filetype, fileId, listdatasets[bandnum], progressCallback, outWidth, outHeight, rowStep, srcRaster, prjSettings, bandnum, 0, oper); break; case enumDataType.UInt64: RastAndProject <UInt64>(outSize, h5filetype, fileId, listdatasets[bandnum], progressCallback, outWidth, outHeight, rowStep, srcRaster, prjSettings, bandnum, 0, oper); break; case enumDataType.Double: RastAndProject <Double>(outSize, h5filetype, fileId, listdatasets[bandnum], progressCallback, outWidth, outHeight, rowStep, srcRaster, prjSettings, bandnum, 0, oper); break; case enumDataType.Float: RastAndProject <Single>(outSize, h5filetype, fileId, listdatasets[bandnum], progressCallback, outWidth, outHeight, rowStep, srcRaster, prjSettings, bandnum, 0, oper); break; case enumDataType.Byte: RastAndProject <Byte>(outSize, h5filetype, fileId, listdatasets[bandnum], progressCallback, outWidth, outHeight, rowStep, srcRaster, prjSettings, bandnum, 0, oper); break; default: break; } } Dictionary <string, string> filekeyvalue = oper.GetAttributes(); foreach (string key in filekeyvalue.Keys) { string value = filekeyvalue[key]; HDFAttributeDef attrdef = new HDFAttributeDef(key, typeof(string), filekeyvalue[key].Length, value); WriteHdfAttributes.WriteHdfAttribute(fileId, attrdef); } //写四角坐标信息 HDFAttributeDef lefttopx = new HDFAttributeDef("Left-Top Latitude", typeof(string), prjSettings.OutEnvelope.LeftTop.Y.ToString().Length, prjSettings.OutEnvelope.LeftTop.Y.ToString()); WriteHdfAttributes.WriteHdfAttribute(fileId, lefttopx); HDFAttributeDef lefttopy = new HDFAttributeDef("Left-Top Longtitude", typeof(string), prjSettings.OutEnvelope.LeftTop.X.ToString().Length, prjSettings.OutEnvelope.LeftTop.X.ToString()); WriteHdfAttributes.WriteHdfAttribute(fileId, lefttopy); HDFAttributeDef boottomrightx = new HDFAttributeDef("Bottom-Right Latitude", typeof(string), prjSettings.OutEnvelope.RightBottom.Y.ToString().Length, prjSettings.OutEnvelope.RightBottom.Y.ToString()); WriteHdfAttributes.WriteHdfAttribute(fileId, boottomrightx); HDFAttributeDef boottomrighty = new HDFAttributeDef("Bottom-Right Longtitude", typeof(string), prjSettings.OutEnvelope.RightBottom.X.ToString().Length, prjSettings.OutEnvelope.RightBottom.X.ToString()); WriteHdfAttributes.WriteHdfAttribute(fileId, boottomrighty); //投影信息 string projtype = "Geopraphic Latitude longtitude"; HDFAttributeDef projecttype = new HDFAttributeDef("Projection Type", typeof(string), projtype.Length, projtype); WriteHdfAttributes.WriteHdfAttribute(fileId, projecttype); H5F.close(fileId); }
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; } }