예제 #1
0
        /// <summary>
        /// Render the full raster block by block, and then save the values to the pyramid raster.
        /// This will probably be nasty and time consuming, but what can you do.
        /// </summary>
        /// <param name="pyrFile">File name of the file the pyramid image should be saved to.</param>
        /// <param name="progressHandler">The progress handler.</param>
        /// <returns>The created pyramid image.</returns>
        public IImageData CreatePyramidImage(string pyrFile, IProgressHandler progressHandler)
        {
            PyramidImage py          = new PyramidImage(pyrFile, DataSet.Bounds);
            int          width       = DataSet.Bounds.NumColumns;
            int          blockHeight = 32000000 / width;

            if (blockHeight > DataSet.Bounds.NumRows)
            {
                blockHeight = DataSet.Bounds.NumRows;
            }
            int numBlocks = (int)Math.Ceiling(DataSet.Bounds.NumRows / (double)blockHeight);
            int count     = DataSet.NumRows;

            if (_symbolizer.ShadedRelief.IsUsed)
            {
                count = count * 2;
            }

            ProgressMeter      pm          = new ProgressMeter(progressHandler, "Creating Pyramids", count);
            PerformanceCounter pcRemaining = new PerformanceCounter("Memory", "Available Bytes");
            Process            proc        = Process.GetCurrentProcess();

            for (int j = 0; j < numBlocks; j++)
            {
                int h = blockHeight;
                if (j == numBlocks - 1)
                {
                    h = DataSet.Bounds.NumRows - (j * blockHeight);
                }
#if DEBUG
                var mem     = proc.PrivateMemorySize64 / 1000000;
                var freeRam = Convert.ToInt64(pcRemaining.NextValue()) / 1000000;
                Debug.WriteLine("Memory before: " + mem + ", " + freeRam + " remaining.");
#endif
                pm.BaseMessage = "Reading from Raster";
                pm.SendProgress();
                using (IRaster r = DataSet.ReadBlock(0, j * blockHeight, width, h))
                {
                    byte[] vals = new byte[h * 4 * width];
                    r.DrawToBitmap(Symbolizer, vals, width * 4, pm);
                    pm.BaseMessage = "Writing to Pyramids";
                    pm.SendProgress();
                    py.WriteWindow(vals, j * blockHeight, 0, h, width, 0);
                    Symbolizer.HillShade = null;
                }
#if DEBUG
                mem     = proc.PrivateMemorySize64 / 1000000;
                freeRam = Convert.ToInt64(pcRemaining.NextValue()) / 1000000;
                Debug.WriteLine("Memory after: " + mem + "Mb | " + freeRam + " remaining Mb.");
#endif
            }

            pm.Reset();
            py.ProgressHandler = ProgressHandler;
            py.CreatePyramids();
            py.WriteHeader(pyrFile);
            return(py);
        }
예제 #2
0
        /// <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;
        }
예제 #3
0
        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);
        }