public void RastAndProject <T>(Size outSize, H5T.H5Type ht5type, H5FileId fileId, string dataset, Action <int, string> progressCallback, int outWidth, int outHeight, int rowStep, IRasterDataProvider srcRaster, FilePrjSettings prjSettings, int bandnum, T fillValue, HDF5.Hdf5Operator ope) { T[,] data = new T[outSize.Height, outSize.Width]; // 定义数据集操作部分 long[] dims = new long[2]; dims[0] = Convert.ToInt64(outSize.Height); dims[1] = Convert.ToInt64(outSize.Width); H5DataSpaceId dspaceId = H5S.create_simple(2, dims); // Define datatype for the data in the file. H5DataTypeId dtypeId = H5T.copy(ht5type); // Create the data set DATASETNAME. H5DataSetId dsetId = H5D.create(fileId, dataset, dtypeId, dspaceId); for (int oRow = 0; oRow < outHeight; oRow += rowStep) { #region 分块读取数据集 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 * prjSettings.OutResolutionY; Parallel.For(0, rowStep, j => { double x; double y; int index; y = prjSettings.OutEnvelope.LeftTop.Y - j * prjSettings.OutResolutionY - oY; for (int i = 0; i < outWidth; i++) { x = prjSettings.OutEnvelope.LeftTop.Y + i * prjSettings.OutResolutionX; index = i + j * outWidth; xs[index] = x; ys[index] = y; } }); _projectionTransform.InverTransform(xs, ys); PrjEnvelope tEnvelope = PrjEnvelope.GetEnvelope(xs, ys, null); tEnvelope.Extend(srcRaster.ResolutionX, srcRaster.ResolutionY * 4); PrjEnvelope srcEnvelope = new PrjEnvelope(srcRaster.CoordEnvelope.MinX, srcRaster.CoordEnvelope.MaxX, srcRaster.CoordEnvelope.MinY, srcRaster.CoordEnvelope.MaxY); tEnvelope = PrjEnvelope.Intersect(tEnvelope, srcEnvelope); if (tEnvelope == null || tEnvelope.IsEmpty) { continue; } Size tSize = tEnvelope.GetSize(srcRaster.ResolutionX, srcRaster.ResolutionY); int tBeginRow = -1, tEndRow = -1, tBeginCol = -1, tEndCol = -1; int oBeginRow = -1, oEndRow = -1, oBeginCol = -1, oEndCol = -1; PrjBlockHelper.ComputeBeginEndRowCol(srcEnvelope, new Size(srcRaster.Width, srcRaster.Height), 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) / srcRaster.ResolutionX + 0.5); rows[index] = (UInt16)((srcStepLeftTopY - y) / srcRaster.ResolutionY + 0.5); } } }); xs = null; ys = null; #endregion //分块读取不同波段数据 ReadBandData <T>(srcBandData, bandnum, oBeginCol, oBeginRow, srcStepWidth, srcStepHeight, GetSysDataType(ht5type)); //投影不同分块的数据集 _rasterProjector.Project <T>(srcBandData, srcStepSize, rows, cols, outStepSize, dstBandData, fillValue, 0, null); for (int i = 0; i < outStepSize.Width; i++) { for (int j = 0; j < outStepSize.Height; j++) { int index = j * outStepSize.Width + i; data[j + oRow, i] = dstBandData[index]; } } rows = null; rows = null; srcBandData = null; dstBandData = null; } H5D.write(dsetId, dtypeId, new H5Array <T>(data)); //写数据集属性 //Dictionary<string, string> dsetkeyvalue = ope.GetAttributes(dataset); //foreach (string key in dsetkeyvalue.Keys) //{ // string value = dsetkeyvalue[key]; // HDFAttributeDef attrdef = new HDFAttributeDef(key, typeof(string), dsetkeyvalue[key].Length, value); // WriteHdfAttributes.WriteHdfAttribute(dsetId, attrdef); //} H5D.close(dsetId); }
/// <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); }