ThinkGeo.com    |     Documentation    |     Premium Support

Printing WorldMapKitLayer

I’m working on printing the map and I’m running into some issues. I’m currently working on a simple application to limit the factors involved. The code below brings up a print preview window, but after I close it and click on the map I get an unhandled exception: “Printer layer supports Feet or Meter only”. I have used similar code to this to do a print preview on the GoogleMapsLayer successfully. Some of this code is based on the LargeScaleMapPrinting example.

private void wpfMap1_Loaded(object sender, RoutedEventArgs e)
{
  wpfMap1.MapUnit = GeographyUnit.DecimalDegree;
  WorldMapKitLayer lTest = new WorldMapKitLayer(WorldMapKitLayerType.WorldMapKitLayer, <clientid>, <private key>);
  lTest.MapType = WorldMapKitMapType.AerialWithLabels;
  LayerOverlay overlayThinkGeo = new LayerOverlay();
  overlayThinkGeo.Name = "ThinkGeo";
  overlayThinkGeo.Layers.Add(lTest);
  wpfMap1.Overlays.Add(overlayThinkGeo);

  LayerOverlay overlayCache = new LayerOverlay();
  overlayCache.Name = "TileCache";
  overlayCache.TileType = TileType.MultipleTile;
  overlayCache.TileCache = new FileBitmapTileCache(<cache path>, <cache id>);
  wpfMap1.Overlays.Add(overlayCache);

  PrinterInteractiveOverlay printerInteractiveOverlay = new PrinterInteractiveOverlay();
  wpfMap1.InteractiveOverlays.Add("PrintPreviewOverlay", printerInteractiveOverlay);
  wpfMap1.InteractiveOverlays.MoveToBottom("PrintPreviewOverlay");
  PagePrinterLayer pagePrinterLayer = new PagePrinterLayer(PrinterPageSize.AnsiA, PrinterOrientation.Portrait);
  pagePrinterLayer.Open();
  printerInteractiveOverlay.PrinterLayers.Add("PageLayer", pagePrinterLayer);
}
private void button_Click(object sender, RoutedEventArgs e)
{
  RectangleShape rOrigExtent = wpfMap1.CurrentExtent;
  GeographyUnit eOrigUnit = wpfMap1.MapUnit;
  wpfMap1.MapUnit = GeographyUnit.Meter;
  PrinterInteractiveOverlay printerInteractiveOverlay = (PrinterInteractiveOverlay)wpfMap1.InteractiveOverlays["PrintPreviewOverlay"];
  PagePrinterLayer pagePrinterLayer = (PagePrinterLayer)printerInteractiveOverlay.PrinterLayers["PageLayer"];

  foreach (Overlay o in wpfMap1.Overlays)
  {
    MapPrinterLayer mapPrinterLayer = new MapPrinterLayer();
    mapPrinterLayer.MapUnit = eOrigUnit;
    mapPrinterLayer.MapExtent = rOrigExtent;
    mapPrinterLayer.BackgroundMask = new AreaStyle(new GeoPen(GeoColor.StandardColors.Black, 1));
    mapPrinterLayer.Open();
    RectangleShape pageBoundingbox = pagePrinterLayer.GetPosition(PrintingUnit.Inch);
    mapPrinterLayer.SetPosition(7, 10, pageBoundingbox.GetCenterPoint().X, pageBoundingbox.GetCenterPoint().Y, PrintingUnit.Inch);
    foreach (Layer l in ((LayerOverlay)o).Layers)
    {
      mapPrinterLayer.Layers.Add(l);
    }
    printerInteractiveOverlay.PrinterLayers.Add(mapPrinterLayer);
  }

  PrintDialog printDialog = new PrintDialog();
  PrintDocument printDocument = new PrintDocument();
  printDocument.DefaultPageSettings.Landscape = true;
  if (pagePrinterLayer.Orientation == PrinterOrientation.Portrait)
  {
    printDocument.DefaultPageSettings.Landscape = false;
  }

  PrinterGeoCanvas printerGeoCanvas = new PrinterGeoCanvas();
  printerGeoCanvas.DrawingArea = printDocument.DefaultPageSettings.Bounds;
  printerGeoCanvas.BeginDrawing(printDocument, pagePrinterLayer.GetBoundingBox(), wpfMap1.MapUnit);

  // Loop through all of the PrintingLayer in the PrinterInteractiveOverlay and print all of the
  // except for the PagePrinterLayer                
  Collection<SimpleCandidate> labelsInAllLayers = new Collection<SimpleCandidate>();
  foreach (PrinterLayer printerLayer in printerInteractiveOverlay.PrinterLayers)
  {
    printerLayer.IsDrawing = true;
    if (!(printerLayer is PagePrinterLayer))
    {
      printerLayer.Draw(printerGeoCanvas, labelsInAllLayers);
    }
    printerLayer.IsDrawing = false;
  }
  printerGeoCanvas.Flush();

  wpfMap1.MapUnit = eOrigUnit;

  System.Windows.Forms.PrintPreviewDialog printPreviewDialog = new System.Windows.Forms.PrintPreviewDialog();
  printPreviewDialog.Document = printDocument;
  System.Windows.Forms.DialogResult dialogResult = printPreviewDialog.ShowDialog();
}

Hi Neil,

I tested your code but it looks works well.

Please try my attached code and test it with our latest dlls.

DisplayASimpleMap.zip (2.0 KB)

Regards,

Don

Thanks for the quick response. I downloaded the most recent production build from 6/13/2016 and copied the code you sent into the WpfDesktopEdition_HowDoI_CS project. When I hit the button the print preview comes up but the image shows the map broken up (for example, there will be four squares that show the map but they will be separated by white space). After I close the print preview window, I can pan or zoom with different results. Panning causes the map to break into separate blocks just like the print preview. Zooming causes the unhandled exception from my first post. Are you able to use the map (panning and zooming) after doing a print preview?

Hi Neil,

I tested both 9.0.0.356 and 9.0.356.0 today, they work well just like the screen shot.

About the exception after you close the preview, you should make sure the mapUnit is meter if your printerInteractiveOverlay is active in your map, or you can just keep it as a standalone overlay but not need add it to map.

So disable this overlay in map can solve the exception.

printerInteractiveOverlay.IsVisible = false;

I think if you are using some basic layer like WorldMapKitLayer please don’t add printerlayer in same map.

Regards,

Don

Disabling the overlay did clear up the exception, However, I’m still left with this when I zoom in after a print preview:

You mentioned the possibility of keeping the printerInteractiveOverlay as a standalone overlay and not adding it to the map. How would that be done? I’m guessing that would clear up the odd display issues I’m seeing after the print preview.

Hi Neil,

Do you have some other code hadn’t been included in the DisplayASimpleMap code?

I still cannot reproduce it like your screen shot.

In fact I am not sure why you need to add printerInteractiveOverlay into map, do you want to make the map looks like a print preview? If you just want to show map please render them by some other layer like ShapeFileFeatureLayer or BingmapsOverlay etc.

So I think you don’t need add it to map, just keep it as a global object for printing is OK.

Regards,

Don

It sounds like the global printing object is the way to go. I was adding to the map since that seemed to be the way to do it, but I’m not sure how to do this without adding it to the map. Is there sample code that shows how to print without adding the print overlay to the map? I think that will do exactly what we need.

Hi Neil,

Sorry we don’t have a global object sample, why I suggest you use that because I found you use this layer only for print in the popup window, and you don’t need use it print on the main map.

You can find a sample Print Preview in this page http://wiki.thinkgeo.com/wiki/map_suite_wpf_desktop_edition_all_samples, which shows how to build a print preview on main map, which is not the same like your requirement, but I think some code in it should be helpful.

Regards,

Don