ThinkGeo.com    |     Documentation    |     Premium Support

How to print a WpfMap

Hello,


I just wanted to know how to print a WpfMap?


And wether there is an existing example project for printing a complete WpfMap?


thanks,


Alexander



Alexander,


Thanks for your interests in Map Suite component and welcome you to ThinkGeo Map Suite Desktop Discussion forum.
 
I made a simple sample for your to print map in Wpf Map control, get it in attachment. To run this application, you have to reference the DLLs(MapSuiteCore.dll and DesktopEdition.dll) and have to change the data path if needed.
 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale

2140-Post7598.zip (11.7 KB)

Hello Yale,




 


thanks for your reply, but which version of MapSuite do I need? Because I can't compile the project, by reason that a namespace (PrinterGeoCanvas) is missing.


 


Thanks, 


Alexander



Alexander, 
  
 The last public release 4.0.0.0 should have contained this class, while it is probably not available in 3.1.299. 
  
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale 


Hello Yale,


when using your sample, the PrintDialog doesn't show up. I think it's because you're using System.Windows.Forms.PrintDialog instead of System.Windows.Controls.PrintDialog. 


But the usage of the Controls.PrintDialog is a bit different, you only have to implement this lines.

 


if (dialog.ShowDialog() == true)
{
printerGeoCanvas.EndDrawing();
}
   


Another problem I encountered is, how do I manage to get the WpfMap as a Bitmap? The WinFormsMap got the Method DrawToBitMap(), why doesn't have the WpfMap such a Method?



Alexander,


Thanks for your sharing and questions.
 
Following code is the way to save the WPF map control map view into a bitmap as DrawToBitmap in Winforms version do.
 

 div>

if (wpfMap1.Overlays.Count > 0)
{
    SaveImageOfControl(wpfMap1, @"C:\temp\wpfControl.png");
}
 
private static PngBitmapEncoder getImageFromControl(Canvas controlToConvert)
{
     // save current canvas transform
     Transform transform = controlToConvert.LayoutTransform;
 
     // get size of control
     System.Windows.Size sizeOfControl = new System.Windows.Size(controlToConvert.ActualWidth, controlToConvert.ActualHeight);
     // measure and arrange the control
     controlToConvert.Measure(sizeOfControl);
     // arrange the surface
     controlToConvert.Arrange(new Rect(sizeOfControl));
 
     // craete and render surface and push bitmap to it
     RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)sizeOfControl.Width, (int)sizeOfControl.Height, 96d, 96d, PixelFormats.Pbgra32);
     // now render surface to bitmap
     renderBitmap.Render(controlToConvert);
 
     // encode png data
     PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
     // puch rendered bitmap into it
     pngEncoder.Frames.Add(BitmapFrame.Create(renderBitmap));
 
     // return encoder
     return pngEncoder;
}
 
 
public static ImageSource GetImageOfControl(Canvas controlToConvert)
{
     // return first frame of image 
     return getImageFromControl(controlToConvert).Frames[0];
}
 
 
public static bool SaveImageOfControl(Canvas controlToConvert, string fileName)
{
     try
     {
         // create a file stream for saving image
         using (System.IO.FileStream outStream = new System.IO.FileStream(fileName, System.IO.FileMode.Create))
         {
             // save encoded data to stream
             getImageFromControl(controlToConvert).Save(outStream);
         }
      }
      catch (Exception e)
      {
         // display for debugging
         Console.WriteLine("Exception caught saving stream: {0}", e.Message);
         // return fail
         return false;
      }
      // return that passed
      return true;
 }

 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale

What references are required for this to work?  I am not able to pass in the map as a Canvas control like you are above.  Is there a typecast or a child property I need to use for the canvas?


Another question of mine, is it possible to print an area larger than the display screen?  If I have a 1600x1200 monitor filled with the map at zoom level 19, can I print that area at zoom level 20?  So the print area would be 4x the screen size.  Basically can I print an area by sending a bounding box and a zoom level?  I would also want to be able to scale that image to fit on 1 piece of paper if the user wants it printed that way.





Jake, 
  
 Our WpfMap control is derived from Canvas, I think your probably use WinformaMap control so that you are not able to pass in it to the method made by Yale. The second one I think you only can do it for current display screen, if you want to print another zoomlevel, you can first draw that size map to a image and then print the image. 
  
 Please let me know if you have more questions. 
 James

Thanks James,  
  
     Not sure if I am not using an updated version, but the wpfmap element does not work as a canvas for me.  I updated the functions to use UIElement and everything works fine. 
  
     I don’t mind redrawing the image to print with, but what I need is to create an area larger than the current screen.  What I would like to do is when a user creates a bounding box around the area they want to print, to force a zoom to level 18, 19 or 20.  Then find the dimensions the map would need to be in order to fit that.  So if they select 40 square miles, is there a way I can find out how large the drawing area would need to be in order to fit that at a certain zoom level?

Jake, 
  
 I will try different machines with different OS to test if it works or not as a canvas. 
  
 Use layer to draw can render any size of image, and ExtentHelper contains many static method to convert coordinate, such as  GetWorldDistanceBetweenTwoScreenPoints, ToWorldCoordinate etc I think you can use them to calculate drawing area. 
  
 Thanks 
 James

Thanks, I am getting closer with those functions.  I can find the height and width I would need the control to be to display at my desired level and can set the map control height and width to those dimensions.  I do some checks to make sure it doesn’t hit a max screen size of roughly 4 times the standard window dimensions so we don’t get an out of memory error.  The numbers appear good in the debug window, but when I try to print all I get is a blank window.  I have no layers drawn, and no features displayed.  Do I have to do something to force the overlays to be drawn?  I do refresh my map after the extents change and the map height/width change. 
  
 If I find my issue I will let you know.

Jake,


I am glad that you are getting closer.


I just not sure what you mean for " I have no layers drawn, and no features displayed.", usually when extents changed or map size changed, the map control will automatically refresh by itself. If you can provide a sample, I think I will easily to reproduce your problem and give you some solutions to solve it.


Thanks


James