ThinkGeo.com    |     Documentation    |     Premium Support

PrintPreviewSample

Hi all,


I'm playing around with PrintPreviewSample to print a map on paper.


I have changed the sample code to read a shape file which is at different projection (EPSG 31467).


MapUnit is Meter.


I get the program running, but the map doesn't show the shape layer.


What to do? How to zoom to a layer which is added to the mapPrinterLayer?


Here is my code:


private void AddMapLayer()

{

// Create the MapPrinterLayer and set the position

MapPrinterLayer mapPrinterLayer = new MapPrinterLayer();

mapPrinterLayer.MapUnit = GeographyUnit.Meter;

mapPrinterLayer.BackgroundMask = new AreaStyle(new GeoPen(GeoColor.StandardColors.Black, 1));

mapPrinterLayer.Open();



// Set the maps position slightly below the pages center and 8 inches wide and 7 inches tall

RectangleShape pageBoundingbox = GetPageBoundingBox(PrintingUnit.Meter);

mapPrinterLayer.SetPosition(8, 7, pageBoundingbox.GetCenterPoint().X, pageBoundingbox.GetCenterPoint().Y + 1, PrintingUnit.Meter);



// Setup the intial extent and ensure they snap to the default ZoomLevel

ZoomLevelSet zoomLevelSet = new ZoomLevelSet();

//mapPrinterLayer.MapExtent = ExtentHelper.ZoomToScale(zoomLevelSet.ZoomLevel03.Scale, new RectangleShape(-180, 90, 180, -90), mapPrinterLayer.MapUnit, (float)mapPrinterLayer.GetBoundingBox().Width, (float)mapPrinterLayer.GetBoundingBox().Height);



// Setup the Countries mapping layer                

ShapeFileFeatureLayer shapefileFeatureLayer = new ShapeFileFeatureLayer(@"\\192.168.178.31\hybrid\sulingen kirche\daten\referenzen\Vermessung\sulingen.shp", ShapeFileReadWriteMode.ReadOnly);

shapefileFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

shapefileFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;

shapefileFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.Highway1;

Proj4Projection BaseProjection = new Proj4Projection();

BaseProjection.ExternalProjectionParametersString = Proj4Projection.GetSphericalMercatorParametersString();

BaseProjection.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(31467);

BaseProjection.Open();

shapefileFeatureLayer.FeatureSource.Projection = BaseProjection;



// Add the new country layer to the MapPrinterLayer

mapPrinterLayer.Layers.Add(shapefileFeatureLayer);



// Add the MapPrinterLayer to the PrinterInteractiveOverlay

PrinterInteractiveOverLay printerInteractiveOverLay = (PrinterInteractiveOverLay)winformsMap1.InteractiveOverlays["PrintPreviewOverlay"];

printerInteractiveOverLay.PrinterLayers.Add("MapLayer", mapPrinterLayer);

                    }


What to do?


Regards


Hardy



Hi Hardy,



I reviewed your codes and I think the issue is caused as we didn’t give a correct extent for the MapExtent of MapPrinterLayer, where you commented out in your codes. Try to giving your shapelayer’s boundingbox for it should works. Some codes are like the below:



// Setup the intial extent and ensure they snap to the default ZoomLevel
            mapPrinterLayer.MapExtent = shapefileFeatureLayer.GetBoundingBox();



Hope it helps.

Thanks,

Troy

Hi Troy,


yes that works.


But some more questions:


How to set a correct scale to the PrinterLayer? I would like to have a map printed with a scale 1:500.


I think I have to catch the width of the Printing Layer in Paper Units? and calculate the width of the resulting Extent?


Am I right?


When clicking right mouse on PrinterLayer there is a Popup Menu with "remove" and "Property" ...how to handle these items?



Regards


Hardys



Me again,


I have integrated the snippet into my larger project. I can open a second window with a new map control, loading all layers from my main map.


Some problems with GeoImages have been fixed with DrawingMode property of printerlayer. Ok.


But if I open a PrintPreview and print the map to my device (OKI laser) the drawing is scaled incorrect.


I have to set the units to Centimeter (still Germany) so my page is pagePrinterLayer.CustomWidth = 21 / 2.54 * 100 '1/100 inch.


MapLayer is set to become width=18 cm and height=25 cm. Printed it will be width=17.3 cm and height=24.0 cm.


GeoImgaes also will be streched.


That's not looking great.


What to do to get correct scaled map?



Regards


Hardy




Hi Hartwig,


As your mentions,


1.I think it is right that setting the correct scale on printerlayer, but I have the other idea on it, we can invoke

ExtentHelper.ZoomToScale(targetScale, targetBoundingBox, mapPrinterLayer). Here is an article about how to calculate a scale as wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale  and I hope it helps. 

Besides, In our map system, the default ppi is 96. So, I get the actually scale with 1:500 is  1068670.9333. Following expression is the concrete parameters:

mapPrinterLayer.MapExtent = ExtentHelper.ZoomToScale(1068670.9333, new RectangleShape(-180, 90, 180, -90), mapPrinterLayer.MapUnit, (float)mapPrinterLayer.GetBoundingBox().Width, (float)mapPrinterLayer.GetBoundingBox().Height);


2.The context menu items are set in SetupContextMenu(), I think you can get them and make some changes.

3.About the printing deviation, I think it is caused by ppi, please try the 96 instead of 100.



Any questions, please feel free to let us know.

Thanks,

Troy