/// <summary> /// This does not have to be used to work, but provides a default implementation for writing bitmap, /// and will be used by the MapRasterLayer class during file creation. /// </summary> /// <param name="progressHandler"></param> protected void DefaultWriteBitmap(IProgressHandler progressHandler) { if (DataSet.NumRowsInFile * DataSet.NumColumnsInFile > 8000 * 8000) { // For huge images, assume that GDAL or something was needed anyway, // and we would rather avoid having to re-create the pyramids if there is any chance // that the old values will work ok. string pyrFile = Path.ChangeExtension(DataSet.Filename, ".mwi"); BitmapGetter = CreatePyramidImage(pyrFile, progressHandler); OnItemChanged(this); return; } Bitmap bmp = new Bitmap(DataSet.NumColumns, DataSet.NumRows, PixelFormat.Format32bppArgb); if (_symbolizer.DrapeVectorLayers == false) { // Generate the colorscheme, modified by hillshading if that hillshading is used all in one pass DataSet.DrawToBitmap(Symbolizer, bmp, progressHandler); } else { // work backwards. when we get to this layer do the colorscheme. // First, use this raster and its colorscheme to drop the background DataSet.PaintColorSchemeToBitmap(Symbolizer, bmp, progressHandler); // Set up a graphics object with a transformation pre-set so drawing a geographic coordinate // will draw to the correct location on the bitmap Graphics g = Graphics.FromImage(bmp); g.SmoothingMode = SmoothingMode.AntiAlias; Extent extents = DataSet.Extent; Rectangle target = new Rectangle(0, 0, bmp.Width, bmp.Height); ImageProjection ip = new ImageProjection(extents, target); // Cycle through each layer, and as long as it is not this layer, draw the bmp foreach (ILegendItem layer in GetParentItem().LegendItems) { // Temporarily I am only interested in doing this for vector datasets IFeatureLayer fl = layer as IFeatureLayer; if (fl == null) { continue; } fl.DrawSnapShot(g, ip); } if (Symbolizer.ShadedRelief.IsUsed) { // After we have drawn the underlying texture, apply a hillshade if it is requested Symbolizer.PaintShadingToBitmap(bmp, progressHandler); } } InRamImage image = new InRamImage(bmp); image.Bounds = DataSet.Bounds.Copy(); BitmapGetter = image; Symbolizer.Validate(); OnInvalidate(this, new EventArgs()); OnItemChanged(); }
/// <summary> /// Creates a bitmap of the requested size that covers the specified geographic extent using /// the current symbolizer for this layer. This does not have any drawing optimizations, /// or techniques to speed up performance and should only be used in special cases like /// draping of vector content onto a texture. It also doesn't worry about selections. /// </summary> /// <param name="geographicExtent"> /// The extent to use when computing the snapshot. /// </param> /// <param name="width"> /// The integer height of the bitmap. The height is calculated based on /// the aspect ratio of the specified geographic extent. /// </param> /// <returns> /// A Bitmap object /// </returns> public Bitmap SnapShot(Extent geographicExtent, int width) { int height = Convert.ToInt32((geographicExtent.Height / geographicExtent.Width) * width); Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(bmp); ImageProjection p = new ImageProjection(geographicExtent, new Rectangle(0, 0, width, height)); DrawSnapShot(g, p); g.Dispose(); OnSnapShotTaken(bmp); return bmp; }
/// <summary> /// This does not have to be used to work, but provides a default implementation for writing bitmap, /// and will be used by the MapRasterLayer class during file creation. /// </summary> /// <param name="progressHandler"></param> protected void DefaultWriteBitmap(IProgressHandler progressHandler) { if (DataSet.NumRowsInFile * DataSet.NumColumnsInFile > 8000 * 8000) { // For huge images, assume that GDAL or something was needed anyway, // and we would rather avoid having to re-create the pyramids if there is any chance // that the old values will work ok. string pyrFile = Path.ChangeExtension(DataSet.Filename, ".mwi"); BitmapGetter = CreatePyramidImage(pyrFile, progressHandler); OnItemChanged(this); return; } Bitmap bmp = new Bitmap(DataSet.NumColumns, DataSet.NumRows, PixelFormat.Format32bppArgb); if (_symbolizer.DrapeVectorLayers == false) { // Generate the colorscheme, modified by hillshading if that hillshading is used all in one pass DataSet.DrawToBitmap(Symbolizer, bmp, progressHandler); } else { // work backwards. when we get to this layer do the colorscheme. // First, use this raster and its colorscheme to drop the background DataSet.PaintColorSchemeToBitmap(Symbolizer, bmp, progressHandler); // Set up a graphics object with a transformation pre-set so drawing a geographic coordinate // will draw to the correct location on the bitmap Graphics g = Graphics.FromImage(bmp); g.SmoothingMode = SmoothingMode.AntiAlias; Extent extents = DataSet.Extent; Rectangle target = new Rectangle(0, 0, bmp.Width, bmp.Height); ImageProjection ip = new ImageProjection(extents, target); // Cycle through each layer, and as long as it is not this layer, draw the bmp foreach (ILegendItem layer in GetParentItem().LegendItems) { // Temporarily I am only interested in doing this for vector datasets IFeatureLayer fl = layer as IFeatureLayer; if (fl == null) continue; fl.DrawSnapShot(g, ip); } if (Symbolizer.ShadedRelief.IsUsed) { // After we have drawn the underlying texture, apply a hillshade if it is requested Symbolizer.PaintShadingToBitmap(bmp, progressHandler); } } InRamImage image = new InRamImage(bmp); image.Bounds = DataSet.Bounds.Copy(); BitmapGetter = image; Symbolizer.Validate(); OnInvalidate(this, new EventArgs()); OnItemChanged(); }