/// <summary> /// /// </summary> /// <param name="fileName"></param> /// <returns></returns> private IImageData OpenFile(string fileName) { Dataset dataset; try { dataset = Gdal.Open(fileName, Access.GA_Update); } catch { try { dataset = Gdal.Open(fileName, Access.GA_ReadOnly); } catch (Exception ex) { throw new GdalException(ex.ToString()); } } Band red = dataset.GetRasterBand(1); ColorInterp bandType = red.GetRasterColorInterpretation(); if (bandType != ColorInterp.GCI_PaletteIndex && bandType != ColorInterp.GCI_GrayIndex && bandType != ColorInterp.GCI_RedBand && bandType != ColorInterp.GCI_AlphaBand) { // This is an image, not a raster, so return null. dataset.Dispose(); dataset = null; return null; } GdalImage result = new GdalImage(fileName); if (result.Width > 8000 || result.Height > 8000) { // Firstly, if there are pyramids inside of the GDAL file itself, we can just work with this directly, // without creating our own pyramid image. // For now, we can't get fast, low-res versions without some kind of pyramiding happening. // since that can take a while for huge images, I'd rather do this once, and create a kind of // standardized file-based pyramid system. Maybe in future pyramid tiffs could be used instead? string pyrFile = Path.ChangeExtension(fileName, ".mwi"); if (File.Exists(pyrFile)) { if (File.Exists(Path.ChangeExtension(pyrFile, ".mwh"))) { return new PyramidImage(fileName); } File.Delete(pyrFile); } GdalImageSource gs = new GdalImageSource(fileName); PyramidImage py = new PyramidImage(pyrFile, gs.Bounds); int width = gs.Bounds.NumColumns; int blockHeight = 64000000 / width; if (blockHeight > gs.Bounds.NumRows) blockHeight = gs.Bounds.NumRows; int numBlocks = (int)Math.Ceiling(gs.Bounds.NumRows / (double)blockHeight); ProgressMeter pm = new ProgressMeter(ProgressHandler, "Copying Data To Pyramids", numBlocks * 2); //ProgressHandler.Progress("pyramid", 0, "Copying Data To Pyramids: 0% Complete"); Application.DoEvents(); for (int j = 0; j < numBlocks; j++) { int h = blockHeight; if (j == numBlocks - 1) { h = gs.Bounds.NumRows - j * blockHeight; } Stopwatch sw = new Stopwatch(); sw.Start(); byte[] vals = gs.ReadWindow(j * blockHeight, 0, h, width, 0); Debug.WriteLine("Reading Value time: " + sw.ElapsedMilliseconds); pm.CurrentValue = j * 2 + 1; sw.Reset(); sw.Start(); py.WriteWindow(vals, j * blockHeight, 0, h, width, 0); sw.Stop(); Debug.WriteLine("Writing Pyramid time: " + sw.ElapsedMilliseconds); pm.CurrentValue = (j + 1) * 2; } gs.Dispose(); pm.Reset(); py.ProgressHandler = ProgressHandler; py.CreatePyramids(); py.WriteHeader(pyrFile); return py; } result.Open(); return result; }
private IImageData OpenFile(string fileName) { var dataset = Helpers.Open(fileName); bool hasOverviews; using (var red = dataset.GetRasterBand(1)) { ColorInterp bandType = red.GetRasterColorInterpretation(); if (bandType != ColorInterp.GCI_PaletteIndex && bandType != ColorInterp.GCI_GrayIndex && bandType != ColorInterp.GCI_RedBand && bandType != ColorInterp.GCI_AlphaBand) { // This is an image, not a raster, so return null. dataset.Dispose(); return(null); } hasOverviews = red.GetOverviewCount() > 0; } GdalImage result = new GdalImage(fileName); // Firstly, if there are pyramids inside of the GDAL file itself, we can just work with this directly, // without creating our own pyramid image. if ((result.Width > 8000 || result.Height > 8000) && !hasOverviews) { // For now, we can't get fast, low-res versions without some kind of pyramiding happening. // since that can take a while for huge images, I'd rather do this once, and create a kind of // standardized file-based pyramid system. Maybe in future pyramid tiffs could be used instead? string pyrFile = Path.ChangeExtension(fileName, ".mwi"); if (File.Exists(pyrFile)) { if (File.Exists(Path.ChangeExtension(pyrFile, ".mwh"))) { return(new PyramidImage(fileName)); } File.Delete(pyrFile); } GdalImageSource gs = new GdalImageSource(fileName); PyramidImage py = new PyramidImage(pyrFile, gs.Bounds); int width = gs.Bounds.NumColumns; int blockHeight = 64000000 / width; if (blockHeight > gs.Bounds.NumRows) { blockHeight = gs.Bounds.NumRows; } int numBlocks = (int)Math.Ceiling(gs.Bounds.NumRows / (double)blockHeight); ProgressMeter pm = new ProgressMeter(ProgressHandler, "Copying Data To Pyramids", numBlocks * 2); //ProgressHandler.Progress("pyramid", 0, "Copying Data To Pyramids: 0% Complete"); Application.DoEvents(); for (int j = 0; j < numBlocks; j++) { int h = blockHeight; if (j == numBlocks - 1) { h = gs.Bounds.NumRows - j * blockHeight; } byte[] vals = gs.ReadWindow(j * blockHeight, 0, h, width, 0); pm.CurrentValue = j * 2 + 1; py.WriteWindow(vals, j * blockHeight, 0, h, width, 0); pm.CurrentValue = (j + 1) * 2; } gs.Dispose(); pm.Reset(); py.ProgressHandler = ProgressHandler; py.CreatePyramids(); py.WriteHeader(pyrFile); result.Dispose(); return(py); } result.Open(); return(result); }