// Render part of a map to a bitmap. static BitmapSource RenderBitmap(Map map, int bmWidth, int bmHeight, RectangleF mapArea) { // Calculate the transform matrix. Point midpoint = new Point(bmWidth / 2.0F, bmHeight / 2.0F); double scaleFactor = bmWidth / mapArea.Width; PointF centerPoint = new PointF((mapArea.Left + mapArea.Right) / 2, (mapArea.Top + mapArea.Bottom) / 2); Matrix matrix = Matrix.Identity; matrix.TranslatePrepend(midpoint.X, midpoint.Y); matrix.ScalePrepend(scaleFactor, -scaleFactor); // y scale is negative to get to cartesian orientation. matrix.TranslatePrepend(-centerPoint.X, -centerPoint.Y); // Get the render options. RenderOptions renderOpts = new RenderOptions(); renderOpts.usePatternBitmaps = false; renderOpts.minResolution = (float) (1 / scaleFactor); // Create a drawing of the map. DrawingVisual visual = new DrawingVisual(); DrawingContext dc = visual.RenderOpen(); // Clear the bitmap dc.DrawRectangle(Brushes.White, null, new Rect(-1, -1, bmWidth + 2, bmHeight + 2)); // clear background. // Transform to map coords. dc.PushTransform(new MatrixTransform(matrix)); // Draw the map. using (map.Read()) map.Draw(dc, mapArea, renderOpts); dc.Close(); // Draw into a new bitmap. RenderTargetBitmap bitmapNew = new RenderTargetBitmap(bmWidth, bmHeight, 96.0, 96.0, PixelFormats.Pbgra32); bitmapNew.Render(visual); bitmapNew.Freeze(); return bitmapNew; }
// Fill in the bitmap member of a cached map area with a bitmap, created from the current map. void CreateBitmap(CachedMapArea mapArea) { // Determine the size of the bitmap we need. int height = (int) Math.Ceiling(mapArea.portion.Height / mapArea.pixelSize); int width = (int) Math.Ceiling(mapArea.portion.Width / mapArea.pixelSize); // Create transformation matrix from map coords to the bitmap coords Matrix matrix = Matrix.Identity; matrix.ScalePrepend(1 / mapArea.pixelSize, 1 / mapArea.pixelSize); matrix.TranslatePrepend(- mapArea.portion.X, - mapArea.portion.Y); // Get the render options. RenderOptions renderOpts = new RenderOptions(); renderOpts.usePatternBitmaps = false; renderOpts.minResolution = (float) mapArea.pixelSize; // Create a visual of the map, appropriately transformed DrawingVisual visual = new DrawingVisual(); DrawingContext dc = visual.RenderOpen(); dc.PushTransform(new MatrixTransform(matrix)); using (map.Read()) map.Draw(dc, mapArea.portion, renderOpts); dc.Close(); // Draw it into a new bitmap. if (mapArea.bitmap != null && mapArea.bitmap.PixelWidth >= width && mapArea.bitmap.PixelHeight >= height) mapArea.bitmap.Clear(); // reuse the old bitmap again by clearing it. else mapArea.bitmap = new RenderTargetBitmap(width, height, 96.0, 96.0, PixelFormats.Pbgra32); mapArea.bitmap.Render(visual); // Mark as up to date. mapArea.isUpToDate = true; }