context: // ********************************************************************************************************
  // Product Name: DotSpatial.Symbology.dll
  // Description:  The core libraries for the DotSpatial project.
  //
  // ********************************************************************************************************
  // The contents of this file are subject to the MIT License (MIT)
  // you may not use this file except in compliance with the License. You may obtain a copy of the License at
  // http://dotspatial.codeplex.com/license
  //
  // Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
  // ANY KIND, either expressed or implied. See the License for the specific language governing rights and
  // limitations under the License.
  //
  // The Original Code is from MapWindow.dll version 6.0
  //
  // The Initial Developer of this Original Code is Ted Dunsford. Created 2/20/2008 3:42:21 PM
  //
  // Contributor(s): (Open source contributors should list themselves and their modifications here).
  //
  // ********************************************************************************************************
  
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Diagnostics;
  using System.Drawing;
  using System.Drawing.Drawing2D;
  using System.Drawing.Imaging;
  using System.IO;
  using System.Linq;
  using DotSpatial.Data;
  using DotSpatial.Projections;
  using DotSpatial.Serialization;
  
  namespace DotSpatial.Symbology
  {
      /// <summary>
      /// A raster layer describes using a single raster, and the primary application will be using this as a texture.
      /// </summary>
      public class RasterLayer : Layer, IRasterLayer
      {
          #region Private Variables
  
          [Serialize("Symbolizer", ConstructorArgumentIndex = 1)]
          private IRasterSymbolizer _symbolizer;
  
          #endregion
  
          #region Constructors
  
          /// <summary>
          /// Opens the specified fileName using the layer manager.
          /// </summary>
          /// <param name="fileName"></param>
          /// <param name="symbolizer"></param>
          public RasterLayer(string fileName, IRasterSymbolizer symbolizer)
          {
              IRaster r = DataManager.DefaultDataManager.OpenRaster(fileName);
              DataSet = r;
              _symbolizer = symbolizer;
              _symbolizer.ParentLayer = this;
              _symbolizer.Scheme.SetParentItem(this);
  
              symbolizer.ColorSchemeUpdated += _symbolizer_SymbologyUpdated;
          }
  
          /// <summary>
          /// Opens the specified fileName and automatically creates a raster that can be used by this raster layer.
          /// </summary>
          /// <param name="fileName">The string fileName to use in order to open the file</param>
          /// <param name="inProgressHandler">The progress handler to show progress messages</param>
          public RasterLayer(string fileName, IProgressHandler inProgressHandler)
          {
              base.ProgressHandler = inProgressHandler;
              IRaster r = DataManager.DefaultDataManager.OpenRaster(fileName, true, inProgressHandler);
              Configure(r);
          }
  
          /// <summary>
          /// Creates a new raster layer using the progress handler defined on the DefaultLayerManager
          /// </summary>
          /// <param name="raster">The raster to create this layer for</param>
          public RasterLayer(IRaster raster)
          {
              Configure(raster);
          }
  
          /// <summary>
          /// Creates a new instance of RasterLayer
          /// </summary>
          /// <param name="raster">The Raster</param>
          /// <param name="inProgressHandler">The Progress handler for any status updates</param>
          public RasterLayer(IRaster raster, IProgressHandler inProgressHandler)
          {
              base.ProgressHandler = inProgressHandler;
              Configure(raster);
          }
  
          private void Configure(IRaster raster)
          {
              DataSet = raster;
              _symbolizer = new RasterSymbolizer(this);
              _symbolizer.ColorSchemeUpdated += _symbolizer_SymbologyUpdated;
          }
  
          #endregion
  
          #region Methods
  
          /// <summary>
          /// This only updates the bitmap representation of the raster.  It does not write to a file unless
          /// the file is too large to fit in memory, in which case it will update the pyramid image.
          /// </summary>
          public void WriteBitmap()
          {
              WriteBitmap(ProgressHandler);
          }
  
          /// <summary>
          /// This only updates the bitmap representation of this raster.  This can be overridden, but currently
          /// uses the default implementation.
          /// </summary>
          /// <param name="progressHandler">An implementation of IProgressHandler to receive status messages</param>
          public virtual void WriteBitmap(IProgressHandler progressHandler)
          {
              DefaultWriteBitmap(progressHandler);
          }
  
          /// <summary>
          ///  Creates a bmp texture and saves it to the specified fileName.
          /// </summary>
          /// <param name="fileName">The string fileName to write to</param>
          /// <param name="bandType">The color band type.</param>
          public void ExportBitmap(string fileName, ImageBandType bandType)
          {
              ExportBitmap(fileName, DataSet.ProgressHandler, bandType);
          }
  
          /// <summary>
          /// Creates a new filename and saves the content from the current BitmapGetter to the
          /// file format.  This relies on the DataManager and will only be successful for
          /// formats supported by the write format possibility.  This will not update this raster
          /// </summary>
          /// <param name="fileName">The string fileName to write to</param>
          /// <param name="progressHandler">The progress handler for creating a new bitmap.</param>
          /// <param name="bandType">The band type ot use.</param>
          public void ExportBitmap(string fileName, IProgressHandler progressHandler, ImageBandType bandType)
          {
              int rows = DataSet.NumRowsInFile;
              int cols = DataSet.NumColumnsInFile;
  
              IImageData result = DataManager.DefaultDataManager.CreateImage(fileName, rows, cols, false, progressHandler, bandType);
              int numBlocks = 1;
              if (rows * cols > 8000 * 8000)
              {
                  numBlocks = Convert.ToInt32(Math.Ceiling(8000 * 8000 / (double)cols));
              }
              int blockRows = (8000 * 8000) / cols;
              ProjectionHelper ph = new ProjectionHelper(DataSet.Extent, new Rectangle(0, 0, cols, rows));
              for (int iblock = 0; iblock < numBlocks; iblock++)
              {
                  int rowCount = blockRows;
                  if (iblock == numBlocks - 1) rowCount = rows - blockRows * iblock;
                  Rectangle r = new Rectangle(0, iblock * blockRows, cols, rowCount);
                  Bitmap block = BitmapGetter.GetBitmap(ph.PixelToProj(r), r);
                  result.WriteBlock(block, 0, iblock * blockRows);
              }
          }
  
          /// <summary>
          /// Clean up any resources being used.
          /// </summary>
          /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
          protected override void Dispose(bool disposing)
          {
              // Grid is
  
              if (disposing)
              {
                  _symbolizer = null;
              }
          }
  
          /// <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"></param>
          /// <param name="progressHandler"></param>
          /// <returns></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();
              long mem;
              long freeRAM;
  
              for (int j = 0; j < numBlocks; j++)
              {
                  int h = blockHeight;
  
gt:                 if (j == numBlocks - 1)