private void EnableBasemapLayer(ServiceProvider serviceProvider) { if (_baseLayer == null) { // Need to first initialize and add the basemap layer synchronously (it will fail if done in another thread). var tempImageData = new InRamImageData(Resources.nodata, new Extent(1, 1, 2, 2)); _baseLayer = new WebMapImageLayer() { LegendText = Resources.Legend_Title, Projection = App.Map.Projection }; _baseLayer.WebMapName = serviceProvider.Name; if (serviceProvider is WmtsServiceProvider wmtsServiceProvider) { _baseLayer.WebMapUrl = wmtsServiceProvider.CapabilitiesUrl; } _baseLayer.RemoveItem += BaseMapLayerRemoveItem; App.Map.Layers.Insert(0, _baseLayer); } else { if (_baseLayer.WebMapName != serviceProvider.Name) { _baseLayer.WebMapName = serviceProvider.Name; } } }
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); InRamImageData id = new InRamImageData(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.CopyValuesToBitmap(); TileCollection.Tiles[row, col] = id; } } SetTileBounds(Bounds.AffineCoefficients); }
/// <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> /// <param name="band">.Net type ignores this for now.</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, ImageBandType band) { InRamImageData img = new InRamImageData(); img.Create(fileName, width, height, band); return(img); }
private void ReadRgb() { if (_dataset.RasterCount < 3) { throw new GdalException("RGB Format was indicated but there are only " + _dataset.RasterCount + " bands!"); } _green = _dataset.GetRasterBand(2); _blue = _dataset.GetRasterBand(3); int tw = TileCollection.TileWidth; int th = TileCollection.TileHeight; int ntt = TileCollection.NumTilesTall(); int ntw = TileCollection.NumTilesWide(); ProgressMeter pm = new ProgressMeter(ProgressHandler, "Reading Tiles ", ntt * ntw); for (int row = 0; row < ntt; row++) { for (int col = 0; col < ntw; col++) { int width = TileCollection.GetTileWidth(col); int height = TileCollection.GetTileHeight(row); InRamImageData id = new InRamImageData(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]; _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); 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] = 255; } } id.Values = vals; id.CopyValuesToBitmap(); TileCollection.Tiles[row, col] = id; pm.CurrentValue = row * ntw + col; } } pm.Reset(); SetTileBounds(Bounds.AffineCoefficients); }
/// <summary> /// Main method of this plugin: gets the tiles from the TileManager, stitches them together, and adds the layer to the map. /// </summary> private void UpdateStichedBasemap() { var map = App.Map as Map; if (map != null) { var rectangle = map.Bounds; var webMercExtent = map.ViewExtents; //Clip the reported Web Merc Envelope to be within possible Web Merc extents // This fixes an issue with Reproject returning bad results for very large (impossible) web merc extents reported from the Map var webMercTopLeftX = TileCalculator.Clip(webMercExtent.MinX, TileCalculator.MinWebMercX, TileCalculator.MaxWebMercX); var webMercTopLeftY = TileCalculator.Clip(webMercExtent.MaxY, TileCalculator.MinWebMercY, TileCalculator.MaxWebMercY); var webMercBtmRightX = TileCalculator.Clip(webMercExtent.MaxX, TileCalculator.MinWebMercX, TileCalculator.MaxWebMercX); var webMercBtmRightY = TileCalculator.Clip(webMercExtent.MinY, TileCalculator.MinWebMercY, TileCalculator.MaxWebMercY); //Get the web mercator vertices of the current map view var mapVertices = new[] { webMercTopLeftX, webMercTopLeftY, webMercBtmRightX, webMercBtmRightY }; double[] z = { 0, 0 }; //Reproject from web mercator to WGS1984 geographic Reproject.ReprojectPoints(mapVertices, z, WebMercProj, Wgs84Proj, 0, mapVertices.Length / 2); var geogEnv = new Envelope(mapVertices[0], mapVertices[2], mapVertices[1], mapVertices[3]); //Grab the tiles var tiles = _tileManager.GetTiles(geogEnv, rectangle); //Stitch them into a single image var stitchedBasemap = TileCalculator.StitchTiles(tiles); _basemapImage = stitchedBasemap; stitchedBasemap = GetTransparentBasemapImage(stitchedBasemap, _opacity); var tileImage = new InRamImageData(stitchedBasemap); //Tiles will have often slightly different bounds from what we are displaying on screen // so we need to get the top left and bottom right tiles' bounds to get the proper extent // of the tiled image var topLeftTile = tiles[0, 0]; var bottomRightTile = tiles[tiles.GetLength(0) - 1, tiles.GetLength(1) - 1]; var tileVertices = new[] { topLeftTile.Envelope.TopLeft().X, topLeftTile.Envelope.TopLeft().Y, bottomRightTile.Envelope.BottomRight().X, bottomRightTile.Envelope.BottomRight().Y }; //Reproject from WGS1984 geographic coordinates to web mercator so we can show on the map Reproject.ReprojectPoints(tileVertices, z, Wgs84Proj, WebMercProj, 0, tileVertices.Length / 2); tileImage.Bounds = new RasterBounds(stitchedBasemap.Height, stitchedBasemap.Width, new Extent(tileVertices[0], tileVertices[3], tileVertices[2], tileVertices[1])); _baseMapLayer.Image = tileImage; } }
public void InRamImageDataCtorLoadsImageWithColor() { var imagePath = Common.AbsolutePath(Path.Combine(@"Data\Grids", "Hintergrundkarte.tif")); using var inram = new InRamImageData(imagePath); using var bitmap = inram.GetBitmap(); Assert.AreEqual(Color.FromArgb(255, 125, 105, 72), bitmap.GetPixel(300, 300)); // if the image was not drawn correctly GetPixel returns the ARGB values for white }
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); InRamImageData id = new InRamImageData(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.CopyValuesToBitmap(); TileCollection.Tiles[row, col] = id; } } SetTileBounds(Bounds.AffineCoefficients); }
private void EnableBasemapLayer() { if (_baseMapLayer == null) { // Need to first initialize and add the basemap layer synchronously (it will fail if done in another thread). // First create a temporary imageData with an Envelope (otherwise adding to the map will fail) var tempImageData = new InRamImageData(Resources.nodata, new Extent(1, 1, 2, 2)); _baseMapLayer = new MapImageLayer(tempImageData) { Projection = App.Map.Projection, LegendText = Resources.Legend_Title }; _baseMapLayer.RemoveItem += BaseMapLayerRemoveItem; AddBasemapLayerToMap(); } App.Map.MapFrame.ViewExtentsChanged -= MapFrameExtentsChanged; App.Map.MapFrame.ViewExtentsChanged += MapFrameExtentsChanged; }
/// <summary> /// Main method of this plugin: gets the tiles from the TileManager, stitches them together, and adds the layer to the map. /// </summary> /// <param name="e">The event args.</param> private void UpdateStichedBasemap(DoWorkEventArgs e) { var map = App.Map as Map; if (map == null) { return; } var bwProgress = (Func <int, bool>)(p => { _bw.ReportProgress(p); if (_bw.CancellationPending) { e.Cancel = true; return(false); } return(true); }); var rectangle = map.Bounds; var webMercExtent = map.ViewExtents.Clone() as Extent; if (webMercExtent == null) { return; } // If ExtendBuffer, correct the displayed extent if (map.ExtendBuffer) { webMercExtent.ExpandBy(-webMercExtent.Width / _extendBufferCoeff, -webMercExtent.Height / _extendBufferCoeff); } // Clip the reported Web Merc Envelope to be within possible Web Merc extents // This fixes an issue with Reproject returning bad results for very large (impossible) web merc extents reported from the Map var webMercTopLeftX = TileCalculator.Clip(webMercExtent.MinX, TileCalculator.MinWebMercX, TileCalculator.MaxWebMercX); var webMercTopLeftY = TileCalculator.Clip(webMercExtent.MaxY, TileCalculator.MinWebMercY, TileCalculator.MaxWebMercY); var webMercBtmRightX = TileCalculator.Clip(webMercExtent.MaxX, TileCalculator.MinWebMercX, TileCalculator.MaxWebMercX); var webMercBtmRightY = TileCalculator.Clip(webMercExtent.MinY, TileCalculator.MinWebMercY, TileCalculator.MaxWebMercY); if (!bwProgress(25)) { return; } // Get the web mercator vertices of the current map view var mapVertices = new[] { webMercTopLeftX, webMercTopLeftY, webMercBtmRightX, webMercBtmRightY }; double[] z = { 0, 0 }; // Reproject from web mercator to WGS1984 geographic Reproject.ReprojectPoints(mapVertices, z, _webMercProj, _wgs84Proj, 0, mapVertices.Length / 2); var geogEnv = new Envelope(mapVertices[0], mapVertices[2], mapVertices[1], mapVertices[3]); if (!bwProgress(40)) { return; } // Grab the tiles var tiles = _tileManager.GetTiles(geogEnv, rectangle, _bw); if (!bwProgress(50)) { return; } // Stitch them into a single image var stitchedBasemap = TileCalculator.StitchTiles(tiles.Bitmaps, _opacity); var tileImage = new InRamImageData(stitchedBasemap) { Projection = _baseMapLayer.Projection }; // report progress and check for cancel if (!bwProgress(70)) { return; } // Tiles will have often slightly different bounds from what we are displaying on screen // so we need to get the top left and bottom right tiles' bounds to get the proper extent // of the tiled image var tileVertices = new[] { tiles.TopLeftTile.MinX, tiles.TopLeftTile.MaxY, tiles.BottomRightTile.MaxX, tiles.BottomRightTile.MinY }; // Reproject from WGS1984 geographic coordinates to web mercator so we can show on the map Reproject.ReprojectPoints(tileVertices, z, _wgs84Proj, _webMercProj, 0, tileVertices.Length / 2); tileImage.Bounds = new RasterBounds(stitchedBasemap.Height, stitchedBasemap.Width, new Extent(tileVertices[0], tileVertices[3], tileVertices[2], tileVertices[1])); // report progress and check for cancel if (!bwProgress(90)) { return; } _baseMapLayer.Image = tileImage; // report progress and check for cancel bwProgress(99); }
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); InRamImageData id = new InRamImageData(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.CopyValuesToBitmap(); TileCollection.Tiles[row, col] = id; } } SetTileBounds(Bounds.AffineCoefficients); }
/// <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) { InRamImageData data = new InRamImageData(fileName); return(data); }
/// <summary> /// Opens a new Image with the specified fileName. /// </summary> /// <param name="fileName">The string file to open.</param> /// <returns>An IDataSet object.</returns> IDataSet IDataProvider.Open(string fileName) { InRamImageData data = new InRamImageData(fileName); return(data); }
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); InRamImageData id = new InRamImageData(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.CopyValuesToBitmap(); TileCollection.Tiles[row, col] = id; } } SetTileBounds(Bounds.AffineCoefficients); }
/// <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="extent">Force the raster to this specified extent.</param> /// <param name="cellSize">The double extent of the cell.</param> /// <param name="fieldName">The integer field index of the file.</param> /// <param name="outputFileName">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, Extent extent, double cellSize, string fieldName, string outputFileName, string driverCode, string[] options, IProgressHandler progressHandler) { Extent env = extent; if (cellSize == 0) { if (env.Width < env.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) { 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 FeatureType.Polygon: { MapPolygonLayer mpl = new MapPolygonLayer(fs); PolygonScheme ps = new PolygonScheme(); colorTable = ps.GenerateUniqueColors(fs, fieldName); mpl.Symbology = ps; mpl.DrawRegions(args, new List <Extent> { env }); } break; case FeatureType.Line: { MapLineLayer mpl = new MapLineLayer(fs); LineScheme ps = new LineScheme(); colorTable = ps.GenerateUniqueColors(fs, fieldName); mpl.Symbology = ps; mpl.DrawRegions(args, new List <Extent> { 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 <Extent> { env }); } break; } Type tp = fieldName == "FID" ? typeof(int) : fs.DataTable.Columns[fieldName].DataType; // We will try to convert to double if it is a string if (tp == typeof(string)) { tp = typeof(double); } InRamImageData image = new InRamImageData(bmp, env); ProgressMeter pm = new ProgressMeter(progressHandler, "Converting To Raster Cells", h); IRaster output; output = Raster.Create(outputFileName, driverCode, w, h, 1, tp, options); output.Bounds = new RasterBounds(h, w, env); double noDataValue = output.NoDataValue; if (fieldName != "FID") { // We can't use this method to calculate Max on a non-existent FID field. double dtMax = Convert.ToDouble(fs.DataTable.Compute("Max(" + fieldName + ")", "")); double dtMin = Convert.ToDouble(fs.DataTable.Compute("Min(" + fieldName + ")", "")); if (dtMin <= noDataValue && dtMax >= noDataValue) { if (dtMax != GetFieldValue(tp, "MaxValue")) { output.NoDataValue = noDataValue; } else if (dtMin != GetFieldValue(tp, "MinValue")) { output.NoDataValue = noDataValue; } } } 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) { InRamImageData data = new InRamImageData(fileName); return data; }
/// <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) { InRamImageData data = new InRamImageData(fileName); return data; }
/// <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> /// <param name="band">.Net type ignores this for now.</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, ImageBandType band) { InRamImageData img = new InRamImageData(); img.Create(fileName, width, height, band); return img; }