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); }