Rendering to non-visible canvas in wpf

Jan 22, 2012 at 1:44 PM

Hi all,

I'm trying to capture an image of the map for use in a wpf application where I don't need the visual MapControl control. I intend the Mapsui rendering to be one layer in a composite image.

private readonly SharpMap.Map _sharpMap;
private View _view;
private TileLayer _layer;
private Canvas _tileCanvas = new Canvas();
private readonly MapRenderer _renderer;
private Image _renderedMapImage;

And in my rendering method:

_renderer.Render(_view, _sharpMap);
_tileCanvas = _renderer.Canvas;
_tileCanvas.InvalidateVisual();
_tileCanvas.InvalidateArrange();
 
// get size of control
var sizeOfView = new System.Windows.Size((int)_view.Width, (int)_view.Height);
// measure and arrange the control
_tileCanvas.Measure(sizeOfView);
// arrange the surface
_tileCanvas.Arrange(new Rect(sizeOfView));
 
var renderBitmap = new RenderTargetBitmap( (int)_view.Width, (int)_view.Height, 96d, 96d, PixelFormats.Pbgra32);
renderBitmap.Render(_tileCanvas);

var image = Image.FromStream(_renderer.ToBitmapStream((int)_view.Width, (int)_view.Height));
graphics.DrawImage(image, new Point(x, y));

I really don't know what I'm doing with the InvalidateVisual() and InvalidateArrange(), except many people online have found this helps when trying similar things.

Is there something I'm missing that the MapControl from MapSui does automatically because it's a visual control? I've tried copying a fair bit of functionality from the MapControl control, but when I try and draw to the graphics Graphic context, nothing shows. I have also tried saving the image to disk, and get a black image. An image loaded off disk renders correctly when put into the graphics.DrawImage() call, so it's defeinitely something in the canvas generating or conversion to a bitmap.

Any ideas? Thanks very much.

Coordinator
Jan 22, 2012 at 9:09 PM

First, Nice code styling! How did you do it?

Some ideas:

Is the data fetched at time of rendering. Not sure how your implementations works but in Mapsui itself the data is fetched async, which can be a disadvantage for, say, a wms server, or a case like yours

Is the canvas the proper size? This could depend on the Vertical and HorizontalAlignment. Perhaps start by drawing your own FrameworkElement directly on the canvas.

Is the View(Port) set correctly? On the full extend of what you want to draw.

Paul