private static object GetCellValue(int w, int h, int row, int col, MWImageData image, Color c, Hashtable colorTable, List<RcIndex> locations)
        {
            double dmin = double.MaxValue;
            object val = 0;
            bool empty = true;
            // Search 8 neighbor cells for likely blended neighbors
            // (otherwise distant shapes might match better incorrectly)
            for (int i = -1; i < 2; i++)
            {
                for (int j = -1; j < 2; j++)
                {
                    if (i == j && j == 0) continue;
                    if (row + i < 0 || row + i >= h) continue;
                    if (col + j < 0 || col + j >= w) continue;
                    Color nc = image.GetColor(row + i, col + j);
                    if (colorTable.ContainsKey(nc) == false) continue;
                    double d = (nc.R - c.R) * (nc.R - c.R) + (nc.G - c.G) * (nc.G - c.G) +
                               (nc.B - c.B) * (nc.B - c.B);
                    if (d >= dmin) continue;

                    val = colorTable[nc];
                    dmin = d;
                    empty = false;
                    image.SetColor(row, col, nc);
                }
            }
            if (empty)
            {
                locations.Add(new RcIndex(row, col));
            }
            return val;
        }
        /// <summary>
        /// Creates a new raster with the specified cell size.  If the cell size
        /// is zero, this will default to the shorter of the width or height
        /// divided by 256.  If the cell size produces a raster that is greater
        /// than 8,000 pixels in either dimension, it will be re-sized to
        /// create an 8,000 length or width raster.
        /// </summary>
        /// <param name="fs">The featureset to convert to a raster</param>
        /// <param name="cellSize">The double extent of the cell.</param>
        /// <param name="fieldName">The integer field index of the file.</param>
        /// <param name="destFilename">The filename of the raster to create</param>
        /// <param name="driverCode">The optional GDAL driver code to use if using GDAL 
        /// for a format that is not discernable from the file extension.  An empty string
        ///  is usually perfectly acceptable here.</param>
        /// <param name="options">For GDAL rasters, they can be created with optional parameters
        ///  passed in as a string array.  In most cases an empty string is perfectly acceptable.</param>
        /// <param name="progressHandler">An interface for handling the progress messages.</param>
        /// <returns>Generates a raster from the vectors.</returns>
        public static IRaster ToRaster(IFeatureSet fs, ref double cellSize, string fieldName, string destFilename, string driverCode, string[] options, IProgressHandler progressHandler)
        {
            IEnvelope env = fs.Envelope;
            if(cellSize == 0)
            {
                if(fs.Envelope.Width < fs.Envelope.Height)
                {
                    cellSize = env.Width/256;
                }
                else
                {
                    cellSize = env.Height/256;
                }
            }
            int w = (int)Math.Ceiling(env.Width/cellSize);
            if (w > 8000)
            {
                w = 8000;
                cellSize = env.Width/8000;
            }
            int h = (int) Math.Ceiling(env.Height/cellSize);
            if (h > 8000)
            {
                cellSize = env.Height/8000;
                h = 8000;
            }
            Bitmap bmp = new Bitmap(w, h);
            Graphics g = Graphics.FromImage(bmp);
            g.Clear(Color.Transparent);
            g.SmoothingMode = SmoothingMode.None;
            g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
            g.InterpolationMode = InterpolationMode.NearestNeighbor;
            Hashtable colorTable;
            MapArgs args = new MapArgs(new Rectangle(0, 0, w, h), env, g);

            switch (fs.FeatureType)
            {
                case FeatureTypes.Polygon:
                    {
                        MapPolygonLayer mpl = new MapPolygonLayer(fs);
                        PolygonScheme ps = new PolygonScheme();
                        colorTable = ps.GenerateUniqueColors(fs, fieldName);
                        mpl.Symbology = ps;
                        mpl.DrawRegions(args, new List<IEnvelope> {env});
                    }
                    break;
                case FeatureTypes.Line:
                    {
                        MapLineLayer mpl = new MapLineLayer(fs);
                        LineScheme ps = new LineScheme();
                        colorTable = ps.GenerateUniqueColors(fs, fieldName);
                        mpl.Symbology = ps;
                        mpl.DrawRegions(args, new List<IEnvelope> { env });
                    }
                    break;
                default:
                    {
                        MapPointLayer mpl = new MapPointLayer(fs);
                        PointScheme ps = new PointScheme();
                        colorTable = ps.GenerateUniqueColors(fs, fieldName);
                        mpl.Symbology = ps;
                        mpl.DrawRegions(args, new List<IEnvelope> { env });
                    }
                    break;
            }
            Type tp = fieldName == "FID" ? typeof(int) : fs.DataTable.Columns[fieldName].DataType;
           
            if (tp == typeof(string)) tp = typeof (double); // We will try to convert to double if it is a string
            Raster output = new Raster();
            MWImageData image = new MWImageData(bmp, env);
            ProgressMeter pm = new ProgressMeter(progressHandler, "Converting To Raster Cells", h);
            
            output.CreateNew(destFilename, driverCode, w, h, 1, tp, options);
            output.Bounds = new RasterBounds(h, w, env);
            List<RcIndex> locations = new List<RcIndex>();
            List<string> failureList = new List<string>();
            for (int row = 0; row < h; row++)
            {
                for (int col = 0; col < w; col++)
                {
                    Color c = image.GetColor(row, col);
                    if (c.A == 0)
                    {
                        output.Value[row, col] = output.NoDataValue;
                    }
                    else
                    {
                        if (colorTable.ContainsKey(c) == false)
                        {
                            if (c.A < 125)
                            {
                                output.Value[row, col] = output.NoDataValue;
                                continue;
                            }
                            // Use a color matching distance to pick the closest member
                            object val = GetCellValue(w, h, row, col, image, c, colorTable, locations);

                            output.Value[row, col] = GetDouble(val, failureList);
                        }
                        else
                        {
                            
                            output.Value[row, col] = GetDouble(colorTable[c], failureList);
                        }

                    }


                }
                pm.CurrentValue = row;
            }
            const int maxIterations = 5;
            int iteration = 0;
            while(locations.Count > 0)
            {
                List<RcIndex> newLocations = new List<RcIndex>();
                foreach (RcIndex location in locations)
                {
                    object val = GetCellValue(w, h, location.Row, location.Column, image, image.GetColor(location.Row, location.Column), colorTable, newLocations);
                    output.Value[location.Row, location.Column] = GetDouble(val, failureList);
                }
                locations = newLocations;
                iteration++;
                if(iteration > maxIterations) break;
            }

            pm.Reset();
            return output;
        }
 IDataSet IDataProvider.Open(string filename)
 {
     MWImageData img = new MWImageData();
     img.Open(filename);
     return img;
 }
 /// <summary>
 /// Opens a new Image with the specified filename
 /// </summary>
 /// <param name="filename">The string file to open</param>
 /// <returns>An IImageData object</returns>
 public IImageData Open(string filename)
 {
     MWImageData img = new MWImageData();
     img.Open(filename);
     return img;
 }
 /// <summary>
 /// Creates a new instance of an Image.
 /// </summary>
 /// <param name="filename">The string filename to use</param>
 /// <param name="width">The integer width in pixels</param>
 /// <param name="height">The integer height in pixels</param>
 /// <param name="inRam">Boolean, true if the entire contents should be stored in memory</param>
 /// <param name="progHandler">A Progress handler to use</param>
 /// <returns>A New IImageData object allowing access to the content of the image</returns>
 public IImageData Create(string filename, int width, int height, bool inRam, IProgressHandler progHandler)
 {
     MWImageData img = new MWImageData();
     img.CreateNew(filename, width, height);
     return img;
 }
        private void ReadARGB()
        {
            if (_dataset.RasterCount < 4)
            {
                throw new GdalException("ARGB Format was indicated but there are only " + _dataset.RasterCount + " bands!");
            }
            _alpha = _red;
            _red = _dataset.GetRasterBand(2);
            _green = _dataset.GetRasterBand(3);
            _blue = _dataset.GetRasterBand(4);

            int tw = TileCollection.TileWidth;
            int th = TileCollection.TileHeight;
            for (int row = 0; row < TileCollection.NumTilesTall(); row++)
            {
                for (int col = 0; col < TileCollection.NumTilesWide(); col++)
                {

                    int width = TileCollection.GetTileWidth(col);
                    int height = TileCollection.GetTileHeight(row);
                    MWImageData id = new MWImageData(width, height);


                    Bitmap image = new Bitmap(width, height, PixelFormat.Format32bppArgb);

                    byte[] red = new byte[width * height];
                    byte[] g = new byte[width * height];
                    byte[] b = new byte[width * height];
                    byte[] a = new byte[width * height];

                    _red.ReadRaster(col * tw, row * th, width, height, red, width, height, 0, 0);
                    _green.ReadRaster(col * tw, row * th, width, height, g, width, height, 0, 0);
                    _blue.ReadRaster(col * tw, row * th, width, height, b, width, height, 0, 0);
                    _alpha.ReadRaster(col * tw, row * th, width, height, a, width, height, 0, 0);

                    BitmapData bData = image.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite,
                                                       PixelFormat.Format32bppArgb);
                    Stride = bData.Stride;
                    image.UnlockBits(bData);
                    byte[] vals = new byte[Width * Height * 4];
                    int stride = Stride;
                    const int bpp = 4;
                    for (int r = 0; r < height; r++)
                    {
                        for (int c = 0; c < width; c++)
                        {
                            vals[r * stride + c * bpp] = b[r * width + c];
                            vals[r * stride + c * bpp + 1] = g[r * width + c];
                            vals[r * stride + c * bpp + 2] = red[r * width + c];
                            vals[r * stride + c * bpp + 3] = a[r * width + c];
                        }
                    }
                    id.Values = vals;
                    id.WriteBytes();
                    TileCollection.Tiles[row, col] = id;
                }
            }
            SetTileBounds(Bounds.AffineCoefficients);
        }
        private void ReadGrayIndex()
        {

            int tw = TileCollection.TileWidth;
            int th = TileCollection.TileHeight;
            for (int row = 0; row < TileCollection.NumTilesTall(); row++)
            {
                for (int col = 0; col < TileCollection.NumTilesWide(); col++)
                {

                    int width = TileCollection.GetTileWidth(col);
                    int height = TileCollection.GetTileHeight(row);
                    MWImageData id = new MWImageData(width, height);
                    byte[] red = new byte[width * height];
                    _red.ReadRaster(col * tw, row * th, width, height, red, width, height, 0, 0);
                    Bitmap image = new Bitmap(width, height);
                    BitmapData bData = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite,
                                                       PixelFormat.Format32bppArgb);
                    Stride = bData.Stride;
                    image.UnlockBits(bData);
                    byte[] vals = new byte[width*height*4];

                    int stride = Stride;
                    const int bpp = 4;

                    for (int r = 0; r < height; r++)
                    {
                        for (int c = 0; c < width; c++)
                        {
                            vals[r*stride + c*bpp] = red[r*width + c];
                            vals[r*stride + c*bpp + 1] = red[r*width + c];
                            vals[r*stride + c*bpp + 2] = red[r*width + c];
                            vals[r*stride + c*bpp + 3] = 255;
                        }
                    }
                    id.Values = vals;

                    id.WriteBytes();
                    TileCollection.Tiles[row, col] = id;
                }
            }
            SetTileBounds(Bounds.AffineCoefficients);
        }