unsafe private void ReadWriteCustomizingRegion(FilePrdMap fpm, CoordEnvelope dstEnvelope, Size dstSize, IRasterDataProvider prdWriter, int offsetX, int offsetY, string dstFilename, List <int> bandNumTemp, IRasterDataDriver drv, IRasterBand band, int i, IntPtr ptr) { fpm.Prd.Read(offsetX, offsetY, dstSize.Width, dstSize.Height, ptr, fpm.Prd.DataType, dstSize.Width, dstSize.Height, 1, new int[] { fpm.BandNums[i] }, enumInterleave.BSQ); band = prdWriter.GetRasterBand(i + 1); band.Write(0, 0, band.Width, band.Height, ptr, fpm.Prd.DataType, band.Width, band.Height); bandNumTemp.Add(i + 1); }
private bool GetDstRegionInfos(ref Dictionary <string, FilePrdMap> filePrdMap, bool interpolation, out CoordEnvelope dstEnvelope, out double dstResoltion, out Size dstSize) { IRasterDataProvider prd = null; string file; FilePrdMap fpm = null; dstEnvelope = null; dstResoltion = 0; int dstWidth = 0; int dstHeight = 0; dstSize = Size.Empty; int startBand = 1; bool same = true; CoordEnvelope prdEnvelope = null; float lonRegion = 0f; float latRegion = 0f; foreach (string key in filePrdMap.Keys) { fpm = filePrdMap[key]; file = fpm.Filename; prd = GeoDataDriver.Open(file) as IRasterDataProvider; fpm.Prd = prd; fpm.StartBand += startBand; if (!SameRegion(prd, dstEnvelope, dstResoltion, dstWidth, dstHeight)) { lonRegion = prd.Width * prd.ResolutionX; latRegion = prd.Height * prd.ResolutionY; prdEnvelope = new CoordEnvelope(prd.CoordEnvelope.MinX, prd.CoordEnvelope.MinX + lonRegion, prd.CoordEnvelope.MinY, prd.CoordEnvelope.MinY + latRegion); //修改输出图像大小与源图像大小不符问题 by chennan 20120802 //dstEnvelope = prd.CoordEnvelope.Intersect(dstEnvelope == null ? prd.CoordEnvelope : dstEnvelope); dstEnvelope = prdEnvelope.Intersect(dstEnvelope == null ? prdEnvelope : dstEnvelope); //by chennan 20120922 修改文件没有任何相交时报错问题 if (dstEnvelope == null) { dstEnvelope = null; return(false); } // fpm.SameRegion = false; same = false; //dstResoltion = GetSimilarResolution(interpolation ? Math.Min(prd.ResolutionX, dstResoltion) : Math.Max(prd.ResolutionX, dstResoltion)); dstResoltion = interpolation ? Math.Min(prd.ResolutionX, dstResoltion) : Math.Max(prd.ResolutionX, dstResoltion); dstWidth = (int)Math.Floor(dstEnvelope.Width / dstResoltion); dstHeight = (int)Math.Floor(dstEnvelope.Height / dstResoltion); } fpm.BandCount = fpm.Prd.BandCount; startBand += fpm.BandCount; } dstSize = new Size(dstWidth, dstHeight); return(same); }
private IRasterDataProvider CreatDstDataProvider(FilePrdMap map, string dstFilename) { using (IRasterDataProvider srcDataProvider = map.Prd) { IRasterDataDriver driver = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver; if (driver == null) { throw new Exception("获取LDF栅格数据驱动时发生未知错误!"); } if (!dstFilename.ToLower().EndsWith(".ldf")) { dstFilename += ".ldf"; } enumDataType dstDataType = srcDataProvider.DataType; IRasterDataProvider dstDataProvider = driver.Create(dstFilename, srcDataProvider.Width, srcDataProvider.Height, srcDataProvider.BandCount, dstDataType, "SPATIALREF=" + GetSpatialRefString(srcDataProvider), GetMapInfoString(srcDataProvider.CoordEnvelope, srcDataProvider.Width, srcDataProvider.Height)); int blockRows = 100; int blockCount = (int)Math.Ceiling((float)srcDataProvider.Height / blockRows); //总块数 int bRow = 0, eRow = 0; int height = srcDataProvider.Height; int width = srcDataProvider.Width; int bufferRowCount = 0; UInt16[] srcBuffer = new UInt16[blockRows * srcDataProvider.Width]; UInt16[] dstBuffer = new UInt16[blockRows * srcDataProvider.Width]; GCHandle srcHandle = GCHandle.Alloc(srcBuffer, GCHandleType.Pinned); GCHandle dstHandle = GCHandle.Alloc(dstBuffer, GCHandleType.Pinned); try { for (int b = 1; b <= srcDataProvider.BandCount; b++) { IRasterBand srcBand = srcDataProvider.GetRasterBand(b); IRasterBand dstBand = dstDataProvider.GetRasterBand(b); bRow = 0; // for (int blocki = 0; blocki < blockCount; blocki++, bRow += blockRows) { eRow = Math.Min(height, bRow + blockRows); bufferRowCount = eRow - bRow; srcBand.Read(0, bRow, width, bufferRowCount, srcHandle.AddrOfPinnedObject(), srcDataProvider.DataType, width, bufferRowCount); // int count = bufferRowCount * width; for (int i = 0; i < count; i++) { dstBuffer[i] = srcBuffer[i]; } // dstBand.Write(0, bRow, width, bufferRowCount, dstHandle.AddrOfPinnedObject(), dstDataType, width, bufferRowCount); } } } finally { srcHandle.Free(); dstHandle.Free(); } return(dstDataProvider); } }
private unsafe bool GetSameSizeFilePrdMap(ref Dictionary <string, FilePrdMap> filePrdMap, bool interpolation) { if (filePrdMap == null || filePrdMap.Count == 0) { return(false); } FilePrdMap fpm = null; int startBand = 1; CoordEnvelope dstEnvelope = null; double dstResoltion = 0; Size dstSize = Size.Empty; string dstPath = GetTemplateFilePath(); bool same = GetDstRegionInfos(ref filePrdMap, interpolation, out dstEnvelope, out dstResoltion, out dstSize); if (dstEnvelope == null) { return(false); } if (!same) { int offsetX = 0; int offsetY = 0; string dstFilename; List <int> bandNumTemp = new List <int>(); using (IRasterDataDriver drv = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver) { foreach (string key in filePrdMap.Keys) { fpm = filePrdMap[key]; //if (!fpm.SameRegion) //{ IRasterBand band = null; offsetX = GetOffset(fpm.Prd.CoordEnvelope.MinX, dstEnvelope.MinX, fpm.Prd.ResolutionX); offsetY = GetOffset(fpm.Prd.CoordEnvelope.MaxY, dstEnvelope.MaxY, fpm.Prd.ResolutionY); dstFilename = dstPath + Guid.NewGuid() + ".ldf"; IRasterDataProvider prdWriter = drv.Create(dstFilename, dstSize.Width, dstSize.Height, fpm.BandNums.Length, fpm.Prd.DataType, "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + GetSpatialRefString(fpm.Prd), GetMapInfoString(dstEnvelope, dstSize.Width, dstSize.Height)) as IRasterDataProvider; switch (fpm.Prd.DataType) { case enumDataType.Byte: for (int i = 0; i < fpm.BandNums.Length; i++) { byte[] dataBlock = new byte[dstSize.Width * dstSize.Height]; fixed(byte *buffer = dataBlock) { IntPtr ptr = new IntPtr(buffer); ReadWriteCustomizingRegion(fpm, dstEnvelope, dstSize, prdWriter, offsetX, offsetY, dstFilename, bandNumTemp, drv, band, i, ptr); } } break; case enumDataType.Double: for (int i = 0; i < fpm.BandNums.Length; i++) { double[] dataBlock = new double[dstSize.Width * dstSize.Height]; fixed(double *buffer = dataBlock) { IntPtr ptr = new IntPtr(buffer); ReadWriteCustomizingRegion(fpm, dstEnvelope, dstSize, prdWriter, offsetX, offsetY, dstFilename, bandNumTemp, drv, band, i, ptr); } } break; case enumDataType.Float: for (int i = 0; i < fpm.BandNums.Length; i++) { float[] dataBlock = new float[dstSize.Width * dstSize.Height]; fixed(float *buffer = dataBlock) { IntPtr ptr = new IntPtr(buffer); ReadWriteCustomizingRegion(fpm, dstEnvelope, dstSize, prdWriter, offsetX, offsetY, dstFilename, bandNumTemp, drv, band, i, ptr); } } break; case enumDataType.Int16: for (int i = 0; i < fpm.BandNums.Length; i++) { Int16[] dataBlock = new Int16[dstSize.Width * dstSize.Height]; fixed(Int16 *buffer = dataBlock) { IntPtr ptr = new IntPtr(buffer); ReadWriteCustomizingRegion(fpm, dstEnvelope, dstSize, prdWriter, offsetX, offsetY, dstFilename, bandNumTemp, drv, band, i, ptr); } } break; case enumDataType.Int32: for (int i = 0; i < fpm.BandNums.Length; i++) { Int32[] dataBlock = new Int32[dstSize.Width * dstSize.Height]; fixed(Int32 *buffer = dataBlock) { IntPtr ptr = new IntPtr(buffer); ReadWriteCustomizingRegion(fpm, dstEnvelope, dstSize, prdWriter, offsetX, offsetY, dstFilename, bandNumTemp, drv, band, i, ptr); } } break; case enumDataType.Int64: for (int i = 0; i < fpm.BandNums.Length; i++) { Int64[] dataBlock = new Int64[dstSize.Width * dstSize.Height]; fixed(Int64 *buffer = dataBlock) { IntPtr ptr = new IntPtr(buffer); ReadWriteCustomizingRegion(fpm, dstEnvelope, dstSize, prdWriter, offsetX, offsetY, dstFilename, bandNumTemp, drv, band, i, ptr); } } break; case enumDataType.UInt16: for (int i = 0; i < fpm.BandNums.Length; i++) { UInt16[] dataBlock = new UInt16[dstSize.Width * dstSize.Height]; fixed(UInt16 *buffer = dataBlock) { IntPtr ptr = new IntPtr(buffer); ReadWriteCustomizingRegion(fpm, dstEnvelope, dstSize, prdWriter, offsetX, offsetY, dstFilename, bandNumTemp, drv, band, i, ptr); } } break; case enumDataType.UInt32: for (int i = 0; i < fpm.BandNums.Length; i++) { UInt32[] dataBlock = new UInt32[dstSize.Width * dstSize.Height]; fixed(UInt32 *buffer = dataBlock) { IntPtr ptr = new IntPtr(buffer); ReadWriteCustomizingRegion(fpm, dstEnvelope, dstSize, prdWriter, offsetX, offsetY, dstFilename, bandNumTemp, drv, band, i, ptr); } } break; case enumDataType.UInt64: for (int i = 0; i < fpm.BandNums.Length; i++) { UInt64[] dataBlock = new UInt64[dstSize.Width * dstSize.Height]; fixed(UInt64 *buffer = dataBlock) { IntPtr ptr = new IntPtr(buffer); ReadWriteCustomizingRegion(fpm, dstEnvelope, dstSize, prdWriter, offsetX, offsetY, dstFilename, bandNumTemp, drv, band, i, ptr); } } break; } fpm.StartBand = startBand; fpm.BandCount = fpm.BandNums.Length; fpm.BandNums = bandNumTemp.ToArray(); bandNumTemp.Clear(); fpm.Filename = dstFilename; fpm.SameRegion = true; fpm.Prd.Dispose(); prdWriter.Dispose(); fpm.Prd = GeoDataDriver.Open(dstFilename) as IRasterDataProvider; startBand += fpm.BandCount; //} //else // fpm.StartBand = startBand; } } } return(true); }
public IVirtualRasterDataProvider CreateVirtualRasterPRD(ref Dictionary <string, FilePrdMap> filePrdMap) { bool sucess = GetSameSizeFilePrdMap(ref filePrdMap, false); if (!sucess) { return(null); } IRasterDataProvider dstDataProvider = null; List <IRasterDataProvider> prdList = new List <IRasterDataProvider>(); IRasterDataProviderConverter converter = new RasterDataProviderConverter(); FilePrdMap fpm = null; string dstPath = GetTemplateFilePath(); string dstFilename; foreach (string key in filePrdMap.Keys) { fpm = filePrdMap[key]; dstFilename = dstPath + Guid.NewGuid() + ".ldf"; switch (fpm.Prd.DataType) { case enumDataType.Byte: dstDataProvider = converter.ConvertDataType <Byte, float>(fpm.Prd.fileName, enumDataType.Float, dstFilename, (v) => { return((float)(v / fpm.Zoom)); }); break; case enumDataType.Double: dstDataProvider = converter.ConvertDataType <Double, float>(fpm.Prd.fileName, enumDataType.Float, dstFilename, (v) => { return((float)(v / fpm.Zoom)); }); break; case enumDataType.Int16: dstDataProvider = converter.ConvertDataType <Int16, float>(fpm.Prd.fileName, enumDataType.Float, dstFilename, (v) => { return((float)(v / fpm.Zoom)); }); break; case enumDataType.Int32: dstDataProvider = converter.ConvertDataType <Int32, float>(fpm.Prd.fileName, enumDataType.Float, dstFilename, (v) => { return((float)(v / fpm.Zoom)); }); break; case enumDataType.Int64: dstDataProvider = converter.ConvertDataType <Int64, float>(fpm.Prd.fileName, enumDataType.Float, dstFilename, (v) => { return((float)(v / fpm.Zoom)); }); break; case enumDataType.UInt16: dstDataProvider = converter.ConvertDataType <UInt16, float>(fpm.Prd.fileName, enumDataType.Float, dstFilename, (v) => { return((float)(v / fpm.Zoom)); }); //dstDataProvider = converter.ConvertDataType<UInt16, UInt16>(fpm.Prd.fileName, enumDataType.Float, dstFilename, (v) => { return (UInt16)(v / fpm.Zoom); }); break; case enumDataType.UInt32: dstDataProvider = converter.ConvertDataType <UInt32, float>(fpm.Prd.fileName, enumDataType.Float, dstFilename, (v) => { return((float)(v / fpm.Zoom)); }); break; case enumDataType.UInt64: dstDataProvider = converter.ConvertDataType <UInt64, float>(fpm.Prd.fileName, enumDataType.Float, dstFilename, (v) => { return((float)(v / fpm.Zoom)); }); break; case enumDataType.Float: dstDataProvider = converter.ConvertDataType <float, float>(fpm.Prd.fileName, enumDataType.Float, dstFilename, (v) => { return((float)(v / fpm.Zoom)); }); break; } //dstDataProvider = CreatDstDataProvider(fpm, dstFilename); fpm.Prd.Dispose(); fpm.Prd = dstDataProvider; fpm.Filename = dstDataProvider.fileName; prdList.Add(dstDataProvider); } return(new VirtualRasterDataProvider(prdList.ToArray())); }