Register  |  Login
ThinkGeo - GPS Tracking and Mapping Solutions  |  Home  |  Cygnus Track  |   Code Community

Discussion Forums

The online community for users of Map Suite GIS components

RSS Feed Available AddThis - Bookmarking and Sharing Button Printer Friendly

PrevPrev NextNext

PDF Extension

Posted by ThinkGeo on 02-11-2009 12:24 AM

I wanted to get your feedback on a new PDF extension we are working on. The extension allows you to print your maps into a vector PDF. I think you will find the extension flexible and easy to use.

To implement this extension, we created a new class called PdfGeoCanvas that inherits from the abstract class GeoCanvas. We put the logic in there and because of that, we can easily draw all of our layers using this new GeoCanvas type. This is not just a cool extension for writing to PDFs, but also a fine example of how extensible the Map Suite 3.x framework is. We went from normally drawing on a bitmap in pixels to drawing to a vector PDF in points.

Downloads:

The zip file will eventually be included in the main release, but I wanted to get this into your hands as quickly as possible and get some feedback. In the zip file you will find the sample below, the source to the library we use to handle the PDF-specific stuff, and a DLL of the extension. I have also included a sample PDF as an attachment.

The sample application has two main parts. The first part is some very standard code to draw a few layers. The second part simply loops through these layers and draws them to the PDF. I think you will find it simple and easy to use.

Important:

When you load the sample application, you need to reference the MapSuiteCore.dll from any of the latest editions.

For the PDF to pop up you need to have a PDF reader associated with the .pdf extension. While the writing of the PDF has nothing to do with it, we just have some handy code in the sample that pops the PDF up when it's done drawing.

The code below is also in the zip file.

David


        // This method is really standard.  It is used to draw the image on the screen.  
        // The real magic is in the btnToPdf_Click event.
        private void Sample_Load(object sender, EventArgs e)
        {
            bitmap = new Bitmap(map.Width, map.Height);

            mapEngine = new MapEngine();
            mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-180.0, 83.0, 180.0, -90.0), map.Width, map.Height);

            mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);

            EcwRasterLayer worldImageLayer = new EcwRasterLayer(@"..\..\SampleData\World.ecw");

            ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@"..\..\SampleData\Countries02.shp");
            worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;
            worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.OutlinePen.LineJoin = DrawingLineJoin.Round;
            worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            ShapeFileFeatureLayer usStatesLayer = new ShapeFileFeatureLayer(@"..\..\SampleData\USStates.shp");
            usStatesLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.State2;        
            usStatesLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.OutlinePen.LineJoin = DrawingLineJoin.Round;
            usStatesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            ShapeFileFeatureLayer worldCapitalsLayer = new ShapeFileFeatureLayer(@"..\..\SampleData\WorldCapitals.shp");
            worldCapitalsLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.Capital3;          
            worldCapitalsLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            ShapeFileFeatureLayer worldCapitalsLabelsLayer = new ShapeFileFeatureLayer(@"..\..\SampleData\WorldCapitals.shp");
            worldCapitalsLabelsLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.Capital3("city_name");
            worldCapitalsLabelsLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.HaloPen = new GeoPen(GeoColor.StandardColors.White, 2);
            worldCapitalsLabelsLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.HaloPen.LineJoin = DrawingLineJoin.Round;
            worldCapitalsLabelsLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;


            mapEngine.StaticLayers.Add("WorldImageLayer", worldImageLayer);
            mapEngine.StaticLayers.Add("WorldLayer", worldLayer);
            mapEngine.StaticLayers.Add("USStatesLayer", usStatesLayer);
            mapEngine.StaticLayers.Add("WorldCapitals", worldCapitalsLayer);
            mapEngine.StaticLayers.Add("WorldCapitalsLabels", worldCapitalsLabelsLayer);

            DrawImage();
        }

        // Here we setup the PDF page and then create our PDFGeoCanvas.
        // We loop through all the layers to draw and then save & pop the 
        // PDF
        private void btnToPdf_Click(object sender, EventArgs e)
        {
            PdfDocument document = new PdfDocument();
            PdfPage page = document.AddPage();
            if (pageOrientationLandscape.Checked == true)
            {
                page.Orientation = PageOrientation.Landscape;
            }

            PdfGeoCanvas pdfGeoCanvas = new PdfGeoCanvas();            

            Collection<SimpleCandidate> labelsInLayers = new Collection<SimpleCandidate>();
            foreach (Layer layer in mapEngine.StaticLayers)
            {
                pdfGeoCanvas.BeginDrawing(page, ExtentHelper.GetDrawingExtent(mapEngine.CurrentExtent, (float)(page.Width.Point), (float)(page.Height.Point)),GeographyUnit.DecimalDegree);
                layer.Open();
                layer.Draw(pdfGeoCanvas, labelsInLayers);
                layer.Close();
                pdfGeoCanvas.EndDrawing();
            }
            
            string filename = "MapSuite PDF Map.pdf";
            document.Save(filename);
            Process.Start(filename);
        }

Downloads:



44 Comments

JeremyUser is Offline
02-12-2009 02:21 PM

I am trying to use the PDF extension example for the Map Suite 3.0 Web Edition using Custom Overlays instead of the Static Overlays you are using in the example.  I am running into trouble here because my Custom Overlays are all of different type, such as the YahooOverlay, InMemoryMarkerOverlay, and a LayerOverlay.  The main problem I'm having is how to draw the YahooOverlay, which doesn't have a layer.  Could you show an example of how this would be done.

Thanks,

Jeremy



BenUser is Offline
02-13-2009 02:27 AM
Avatar

Jeremy, 

PDFExtention prints layers on PDF at server side, so we can print raster data or feature data from all kinds of feature source. But however, we cannot draw the client part overlays to PDF using the PDFExtension, the reason is simple that we cannot get the images on server side. For example, for 3rd part overlays (GoogleOverlay,YahooOverlay,VirtualEarthOverlay,WmsOverlay), we get the images directly from their server and only render the images on client, our server has no idea about their images and sure it cannot draw it on another pdf; for MarkerOverlay, we have the data on server but we do not generate any pictures of it, so we cannot print it on pdf either.
 
Here are some alternate solutions (cannot solve your problem completely though) might be helpful for your case.
 
1, we have GoogleOverlay/WmsOverlay which get googleMap/WMS images to client side, also we have GoogleMapsLayer and WmsRasterLayer on server side which get images to Server. We didn’t use those quite often in Web Edition but now it might be the right case that you can print the GoogleMap/WMSMap to PDF with that. We don’t support YahooMap and VirtualEarth for now and we will add it in the future.
Here are the codes how to use it, and also I attached the result pdf.

   protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                Map1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.FromHtml("#B3C6D4"));
                Map1.CurrentExtent = new RectangleShape(-13939426.6371, 6701997.4056, -7812401.86, 2626987.386962);
                Map1.MapUnit = GeographyUnit.Meter;
                Map1.MapTools.MouseCoordinate.Enabled = true;
                GoogleMapsLayer googleLayer = new GoogleMapsLayer(ConfigurationManager.AppSettings["GoogleUri"]);
                googleLayer.MapType = GoogleMapsMapType.RoadMap;
                googleLayer.PictureFormat = GoogleMapsPictureFormat.Png32;
 
                Map1.StaticOverlay.Layers.Add(googleLayer);
            }
        }
        protected void btnToPdf_Click1(object sender, EventArgs e)
        {
            PdfDocument document = new PdfDocument();
            PdfPage page = document.AddPage();
            page.Orientation = PageOrientation.Landscape;
            PdfGeoCanvas pdfGeoCanvas = new PdfGeoCanvas();
 
            Collection<SimpleCandidate> labelsInLayers = new Collection<SimpleCandidate>();
            foreach (Layer layer in Map1.StaticOverlay.Layers)
            {
                pdfGeoCanvas.BeginDrawing(page, ExtentHelper.GetDrawingExtent(Map1.CurrentExtent, (float)(page.Width.Point), (float)(page.Height.Point)), Map1.MapUnit);
                layer.Open();
                layer.Draw(pdfGeoCanvas, labelsInLayers);
                layer.Close();
                pdfGeoCanvas.EndDrawing();
            }
            string filename = "c:\\MapSuite PDF Map.pdf";
            document.Save(filename);
            Process.Start(filename);
        }
2, you can also use the client side API “PrintMap()” to print it out, but we have some issues about it.
Here is a simple sample
 
And here are the issues we have about the client printing.(of course you know it J ),We are still doing some test about it.
 
Hope that helps, let me know if you have any issues.
 
Ben
AdrianUser is Offline
02-26-2009 02:44 PM
Hi,
I'm trying to use this in Web (map is in a control) instead of using a MapEngine. The problem I have is that I always get the full map at the original extent setup. That is because - for some reason - the map.CurrentExtent is not updated to the current viewport. Here's my code:


public void ToPdf(PdfPage page, Collection labelsInLayers)
{
PdfGeoCanvas pdfGeoCanvas = new PdfGeoCanvas();
// ThinkGeo.MapSuite.WebEdition.Map _map; // defined elsewhere

// this extent does not track the current viewport
RectangleShape extent = _map.CurrentExtent.CloneDeep() as RectangleShape;

Action PrintLayer = (layer) =>
{
pdfGeoCanvas.BeginDrawing(page, ExtentHelper.GetDrawingExtent(extent, (float)(page.Width.Point), (float)(page.Height.Point)), _map.MapUnit);
layer.Open();
layer.Draw(pdfGeoCanvas, labelsInLayers);
layer.Close();
//pdfGeoCanvas.DrawText()
pdfGeoCanvas.EndDrawing();
};


PrintLayer(_map.MapBackground);

foreach (Layer layer in _map.StaticOverlay.Layers)
PrintLayer(layer);
foreach (Layer layer in _map.DynamicOverlay.Layers)
PrintLayer(layer);
}



BenUser is Offline
02-27-2009 03:42 AM
Avatar

Adrian,

Here is a sample based on your code. You can get different printing result after changing the map’s CurrentExent, let me know if you have any issues.

Thanks,

Ben

AdrianUser is Offline
03-09-2009 03:40 PM
Maybe this is a dumb question, but how do I put your map into a certain rectangle in the page, and not the entire page? I'd like to figure out ho to do it, while maintaining the scaling advantages of pdf (not going through a bitmap image of some sort).

Thank you,
Adrian


BenUser is Offline
03-10-2009 01:26 AM
Avatar
Adrian,

Open the Default.aspx file and change Map's Height/Width from 100% to some concrete number like 400 and 400 (in pixels by default), you then will get what you want.

Thanks,

Ben


DavidUser is Offline
03-10-2009 08:06 AM
Avatar
Adrian,

Just to clarify this because I think Ben misunderstood you, you want to draw a map in a PDF but just not using the full page size? Do you want to be to draw on the PDF but in a limited region? Maybe I am missing this also.

David


AdrianUser is Offline
03-10-2009 10:18 AM
Yes, David. I have a web page displaying a map. And I'm happy about where it is displayed. Now I'm creating a pdf document with that map in it and I want to be able to say for example: put this map on the page at the following rectangle :[10,10,380,287] in pdf point units. The whole thing stems from the fact that putting a map on the whole page, upon printing some margins are clipped off. I would like to control the margins. Alas, using TrimMargins, or any of the boxes in pdfsharp either don't work, or are not intended for achieving this.


DavidUser is Offline
03-12-2009 08:02 AM
Avatar
Adrian,

Let me try and do this, I will let you know what I find.

David


DavidUser is Offline
03-16-2009 08:34 AM
Avatar
Adrian,

I got it working now. I added a DrawingArea rectangle that control where and how large of an area you want to draw. The code will automatically scale and clip everything. The PdfSharp library is a bit tough to figure out and they haven't implemented everything but does work well. Tomorrow I will try and compile and attach a new version for you here.

David


AdrianUser is Offline
03-16-2009 09:12 AM
Thanx David for running with this. I'm looking forward to the new apis.
Adrian


RyanUser is Offline
03-16-2009 06:02 PM
I'm trying to use the PdfGeoCanvas in the web version, only using custom overlays and layers. I have a problem that several of my layers override the DrawCore method, and within that I need to call canvas.ToGeoImage(bitmap), however when this method is called, the application crashes saying that the specified method is not supported. Any help would be appreciated.

Thanks,

Ryan


DavidUser is Offline
03-17-2009 12:20 AM
Avatar
Ryan,

That is why this is out in beta. :-) I will take a look at this and get back with you. I suspect it is just something we didn't get in for V1 but we should be able to get it to work. I will try this out and let you know.

David


RyanUser is Offline
03-17-2009 11:45 AM
Perfect... thank you very much for your help.

Ryan


AdrianUser is Offline
03-17-2009 12:03 PM
David, your message from March 15 12:03pm did not post here. I got an email with it, saying it would be in the topic here, but it isn't. Here is what it said:

Adrian,

I almost have this working. I am now able to specify the size at which to draw. For example I can say that I want to limit the drawing area to 400 points by 400 points. Next I will add some offset logic to place this little rectangle where I want it. I hope to have this done in the next day or two. I will keep you posted.

On note is that what I did was to add a DrawingArea property on the PdfGeoCanvas that accepts a RectangleShape that should be in points as to where on the page you want to draw. Does this sound good? I may also add an overload to the BeginDraw to allow you to pass it in here. I also made a change so that when you call the BeginDraw you do not have to use the ExtentHelper method call, we will do it internally. This change however required a change to the GeoCanvas which is in the Core namespace. This means that for now keep using the ExtentHelper but in the future, after we do the next official release of all of our products you will not need it. Having it there will not hurt you though.

David


RyanUser is Offline
03-17-2009 05:49 PM
Avatar
Thanks for adding this Adrian!


DavidUser is Offline
03-18-2009 10:19 AM
Avatar
Adrian,

I deleted that message myself. It seems I do not have have the power to remove it totally as the community forums seems to have self repairing properties. :-) It was removed it because it was not accurate. I was working on a solution and posted it as a stop gap. I then made a bit of a breakthrough but it was different from the original message so I tried to remove the first one. The good news is I am just about done with making the changes and I am able to draw in a chosen rectangle and able to clip it properly. The clipping was the big issue. I may be able to get a new DLL out tomorrow morning.

David


DavidUser is Offline
03-20-2009 06:45 AM
Avatar
Fellow coders,

We have updated the PDF Extension sample with the latest code. You can find it in the link of the original post at the top, scroll way up there. You will notice that now we have a DrawingArea property that is a Rectangle in screen points that you can use to position the map anywhere on the page and it also handles the clipping.

Side Note: When you make the call to the canvas you still have to use the ExtentHelper.GetDrawingExtent however pretty soon you will not need to do that. We made a change to the Map Suite Core but it hasn't been released yet.

Please let me know if this solves your issues.

David


AdrianUser is Offline
03-20-2009 10:51 AM
David, maybe I'm blind, but I can't seem to locate your _updated_ code. In the original post at the top the links point to the same old sample files. I've downloaded them again, unpacked and they are the old Feb 11 files, with no mention of the newly added DrawingArea property. I guess I'm somehow looking in the wrong place. Would you be more specific where the new files are?
Thanx,
Adrian


DavidUser is Offline
03-20-2009 12:08 PM
Avatar

Adrian,

  I asked someone else to update it, I guess something got crossed up.  I can only post 2 meg myself and the total package is larger.  I went ahead and stripped out the sample data out for now.  I will check what happened and have the full package updated but this might get you by for now.


David

AdrianUser is Offline
03-20-2009 01:59 PM
Thanx, David.
My stuff works now, just in the nick of time for the demo we have today. Couldn't have asked for better timing.

Comments:
the DrawingArea property deals with ints, whereas the rest of the units are in doubles. I would suggest you allow doubles. Or probably XUnit to have even more flexibility, but doubles (XUnit.Points) is just fine.

Thank you!


AdrianUser is Offline
03-20-2009 02:11 PM
Ok, now we're bombing. Could it be because of an InMemoryFeatureLayer added to DynamicOverlay?

The exception is:

System.NotSupportedException was unhandled by user code
Message="Specified method is not supported."
Source="PdfExtension"
StackTrace:
at ThinkGeo.MapSuite.Core.PdfGeoCanvas.xb8d9913b37331dbb(GeoBrush xd8f1949f8950238a, ScreenPointF[] xda99c77836daa640)
at ThinkGeo.MapSuite.Core.PdfGeoCanvas.xf97072fdfc090635(IEnumerable`1 x848e9a85f0afcfc0, GeoPen xd036c7519f764c77, GeoBrush x7a72ea3aa943057c, Single xf79f95b297b243b5, Single x77628737d203d4ed, PenBrushDrawingOrder xc4ddc942de3fbbcb)
at ThinkGeo.MapSuite.Core.PdfGeoCanvas.x1f0b4fcba039b0b8(Collection`1 xf6035ba09c7c2cc2)
at ThinkGeo.MapSuite.Core.PdfGeoCanvas.EndDrawingCore()
at ThinkGeo.MapSuite.Core.GeoCanvas.EndDrawing()
at eMap.Classes.PdfGenerator.<>c__DisplayClass5.b__0(Layer layer) in C:\Work\T5\T5.eMap\Trunk\eMap\Classes\PdfGenerator.cs:line 101
at eMap.Classes.PdfGenerator.PrintMap(Map mapCurrent, GridView gridCurrent, DataTable shadingTable) in C:\Work\T5\T5.eMap\Trunk\eMap\Classes\PdfGenerator.cs:line 110
at eMap.MainApp.PrintMap_Click(Object sender, ImageClickEventArgs e) in C:\Work\T5\T5.eMap\Trunk\eMap\MainApp.aspx.cs:line 343
at System.Web.UI.WebControls.ImageButton.OnClick(ImageClickEventArgs e)
at System.Web.UI.WebControls.ImageButton.RaisePostBackEvent(String eventArgument)
at System.Web.UI.WebControls.ImageButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
InnerException:

The layer we've added is as follows:

private void CreateSelectionLayer()
{
//special case! always add a layer to the DynamicOverlay to handle selections
//this layer needs to be on top (added last) so that the highlight will show
InMemoryFeatureLayer selectionsLayer = new InMemoryFeatureLayer();
selectionsLayer.Name = "SELECTION";
selectionsLayer.ZoomLevelSet.ZoomLevel05.DefaultAreaStyle = AreaStyles.CreateHatchStyle(GeoHatchStyle.DiagonalCross, GeoColor.StandardColors.Yellow, new GeoColor(128, GeoColor.SimpleColors.PaleYellow));
selectionsLayer.ZoomLevelSet.ZoomLevel05.DefaultPointStyle = PointStyles.CreateSimplePointStyle(PointSymbolType.Star2, GeoColor.SimpleColors.BrightOrange, GeoColor.SimpleColors.BrightBlue, 8.0F);
selectionsLayer.ZoomLevelSet.ZoomLevel05.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
_map.DynamicOverlay.Layers.Add(selectionsLayer.Name, selectionsLayer);
}



Cheers,


DavidUser is Offline
03-20-2009 09:10 PM
Avatar
Adrian,

I think it is the HatchStyle, we haven't implemented it yet. I can't remember if it was PdfSharp that didn't have it working yet or we had not finished it. I will check and let you know. In any event the error message should be more descriptive!

David


JeremyUser is Offline
05-18-2009 03:20 AM

I'm trying to use this extension to create print layouts (see attachment ). please note the attachment is a very rough idea of my layout for a landscape A4 print.

I'm trying to accomplish this layout by having two canvases pushed to the pdf file. the first and larger is an adornment layer that draws my borders, logos, legend and additional text. The second smaller canvase is my actual map being pushed. it is position "inside" my adornment layer on the pdf document.

The problem I'm having is the decalared sizes for the two canvases does not seem to correlate. for example when I started out, I wanted my adorment layer canvas just to draw a border box for the map canvas so I set the width and height of my adornment canvas to the same width and height of the map canvas (+2 on width and height).

However the resultant pdf ended up drawing my adornment canvas a lot smaller than my map canvas. The code below is my current code that draws to attached layout. please note the the height defference between the 2 canvases should be "20" as my bounding box margin is "10". however if you see my declaration of the canvas sizes below, you will see the actual height differences between the 2 canvases is "195"

 


    protected void cmdPrintToPDF_Click(object sender, ImageClickEventArgs e)
        {
            PdfDocument document = new PdfDocument();
            PdfPage page = document.AddPage();

            //----------------------------------------------------------//
            // PAGE LAYOUT                                              //
            //==========================================================//
            // Page Size                                                //
            //----------------------------------------------------------//
            
            page.Size = PdfSharp.PageSize.A4;

            //----------------------------------------------------------//
            //Set the Orientation. This must be after page size
            //------------------------------------------------------------

            if (rblPrintLayout.Items[0].Selected) //Protrait            
                page.Orientation = PdfSharp.PageOrientation.Portrait;
            else //Landscape
                page.Orientation = PdfSharp.PageOrientation.Landscape;

            //------------------------------------------------------------

            #region Draw Print Layout

            XUnit pX = page.Width;
            XUnit pY = page.Height; 

            PdfGeoCanvas pdfPrintLayoutCanvas = new PdfGeoCanvas();            

            //------------------//
            //A4 - Landscape    //
            //------------------//
            // x : 1120         //
            // y : 790          //
            //------------------//
            pdfPrintLayoutCanvas.DrawingArea = new System.Drawing.Rectangle(30, 30, 1040, 710);


            pdfPrintLayoutCanvas.DrawingQuality = DrawingQuality.HighSpeed;
            MyPrintAdornmentLayer myPrinterLayer = new MyPrintAdornmentLayer(pdfPrintLayoutCanvas.DrawingArea.Width, pdfPrintLayoutCanvas.DrawingArea.Height);
            pdfPrintLayoutCanvas.BeginDrawing(page, ExtentHelper.GetDrawingExtent(mapMain.CurrentExtent, pdfPrintLayoutCanvas.DrawingArea.Width, pdfPrintLayoutCanvas.DrawingArea.Height), mapMain.MapUnit);  //ExtentHelper.GetDrawingExtent(mapMain.CurrentExtent, pdfPrintLayoutCanvas.DrawingArea.Width, pdfPrintLayoutCanvas.DrawingArea.Height), mapMain.MapUnit); 
            myPrinterLayer.Open();
            myPrinterLayer.Draw(pdfPrintLayoutCanvas, new Collection<SimpleCandidate>());
            myPrinterLayer.Close();
            pdfPrintLayoutCanvas.EndDrawing(); 

            #endregion

            #region Draw From mapMain
            //Draw Layers from mapMain

            PdfGeoCanvas pdfGeoCanvas = new PdfGeoCanvas();
            pdfGeoCanvas.DrawingArea = new System.Drawing.Rectangle(39, 39, 650, 515); //This is optimized for A4 landscape
            pdfGeoCanvas.DrawingQuality = DrawingQuality.HighSpeed;
            pdfGeoCanvas.BeginDrawing(page, ExtentHelper.GetDrawingExtent(mapMain.CurrentExtent, pdfGeoCanvas.DrawingArea.Width, pdfGeoCanvas.DrawingArea.Height), mapMain.MapUnit); //GeographyUnit.DecimalDegree);

            foreach (Layer layer in mapMain.StaticOverlay.Layers)
            {
                layer.Open();
                layer.Draw(pdfGeoCanvas, new Collection<SimpleCandidate>());
                layer.Close();
            }

            foreach (Layer lDynamic in mapMain.DynamicOverlay.Layers)
            {
                lDynamic.Open();
                lDynamic.Draw(pdfGeoCanvas, new Collection<SimpleCandidate>());
                lDynamic.Close();
            }

            pdfGeoCanvas.EndDrawing();

            #endregion

            string fileName = "MyPDF.pdf";
            document.Save(Server.MapPath("~/Prints/" + fileName));
            Process.Start(Server.MapPath("~/Prints/" + fileName)); 
        }
LeeUser is Offline
05-21-2009 10:34 AM
Avatar
Jeremy,

Thanks for pointing this out. This is a bug and we have fixed it, you can get the fixed version from http://download.thinkgeo.com/blog/PdfExtensionSamples_Rev3.zip

Thanks,
ThinkGeo Support


LeeUser is Offline
05-21-2009 10:05 PM
Avatar

Jeremy,

I noticed there are some spike in your pdf,

actually there is a property geoPen.LineJoin can make it better look. You need to loop through the pen in your style and set it what you want.
 

Thanks,

ThinkGeo Support



JeremyUser is Offline
06-02-2009 08:40 AM
Thanks for the update guys. I'll have a look at it right away.


JeremyUser is Offline
06-02-2009 10:46 AM

does PdfExtensionSamples_Rev3.zip contain the fix? I've recompiled the PdfSharp.dll attached is as a reference and I'm still experiencing strange problems.

Firstly when I declare the DrawingArea of my two different PDFCanvases, my AdornmentLayer seems to require the rectangle to be in Pixels where as the PdfGeoCanvas layer seems to require the DrawingArea to be specified using Pts.

On top of which Im experiencing strange issues with he ExtentHelper. As is seem to render my original maps extent + more onto my canvas.
I've triple checked my code for using the helper, and its exactly the same as in your example code.

My code is identical to the code attached above except I now have a point/pixel converter to allocate my rectangle sizes. (as mentioned above my adornment layer I'm using the pages size in pixels, and my PDFCanvas layer I'm declaring it in Pts)

just a reminder, the adornment layer I'm talking about was derived from the PDFCanvas class.

Please seem my attached jpg of my layout for a better explanation.

AdrianUser is Offline
06-02-2009 11:01 AM
Jeremy, this may not be all that you want, but I was able to print the map and the nice border around it using the following code.

Somewhere in the class:
static string strFont = "Arial";
// setup a margin of .5 inches all around
static double dMargin = new XUnit(.5, XGraphicsUnit.Inch).Point;


The actual drawing code:
PdfDocument document = new PdfDocument();

// draw the map page
{
PdfPage page = document.AddPage();
page.Orientation = PageOrientation.Landscape;

{
PdfGeoCanvas pdfGeoCanvas = new PdfGeoCanvas();

pdfGeoCanvas.DrawingArea = new Rectangle((int)dMargin, (int)dMargin, (int)(page.Width - 2 * dMargin), (int)(page.Height - 2 * dMargin));
RectangleShape extent = ExtentHelper.GetDrawingExtent(mapCurrent.CurrentExtent, pdfGeoCanvas.DrawingArea.Width, pdfGeoCanvas.DrawingArea.Height);

Collection labelsInLayers = new Collection();
Action PrintLayer = delegate(Layer layer)
{
pdfGeoCanvas.BeginDrawing(page, extent, mapCurrent.MapUnit);
layer.Open();
layer.Draw(pdfGeoCanvas, labelsInLayers);
layer.Close();
pdfGeoCanvas.EndDrawing();
};


PrintLayer(mapCurrent.MapBackground);

foreach (Layer layer in mapCurrent.StaticOverlay.Layers)
PrintLayer(layer);
foreach (Layer layer in mapCurrent.DynamicOverlay.Layers)
PrintLayer(layer);
}

// draw a frame
{
using (XGraphics gfx = XGraphics.FromPdfPage(page))
{
gfx.DrawRectangle(XPens.Black, new XRect(new XPoint(dMargin, dMargin), new XPoint(page.Width.Point - dMargin, page.Height.Point - dMargin)));
gfx.DrawRectangle(XPens.Red, new XRect(new XPoint(dMargin + 1, dMargin + 1), new XPoint(page.Width.Point - dMargin - 1, page.Height.Point - dMargin - 1)));
}
}

{
string strCopyright = ConfigurationManager.AppSettings.Get("Copyright");
XFont font = new XFont(strFont, 8, XFontStyle.Regular);
using (XGraphics gfx = XGraphics.FromPdfPage(page))
{
gfx.DrawString(strCopyright, font, XBrushes.Gray, new XRect(dMargin, page.Height.Point - dMargin - 30, page.Width - 2 * dMargin, 30),
XStringFormats.Center);
}
}
}

Note the use of XGraphics gfx = XGraphics.FromPdfPage(page). This gives you a lot of flexibility to draw in PDF exactly where you want.

Hope it helps.
Chhers!


JeremyUser is Offline
06-02-2009 11:08 AM
Thanks Adrian. That makes a lot more sense than trying to use an adorment pdf canvas. I'll give it a go in the morning. however as stated above, there still seems to be some strange things happening the pdf class.


JeremyUser is Offline
06-03-2009 05:42 AM
Adrian. Thanks for the code. works really well for how I want to layout the print. However I'm still having a major issue with the map rendering to my pdf based on zoom levels. This is the problem i mentioned above. see my attached jpg above.

for some reason my extent doesn't render across properly (this is on rev3 of the pdf sharp library). This did work in rev2.


EdUser is Offline
06-03-2009 12:59 PM
In the 307 version, I am unable to get the lables to render to the pdf. Even using the HowDoI samples, I get the capitol points in the pdf but not the labels.


JeremyUser is Offline
06-04-2009 02:12 AM

Strange, my labels are coming out fine. I assume your labels are in your dynamic overlay.

   Collection<simplecandidate> labelsInLayers = new Collection<simplecandidate>(); 
 
            foreach (Layer layer in map.DynamicOverlay.Layers)
            {
                pdfGeoCanvas.BeginDrawing(page, extent, map.MapUnit);
                layer.Open();
                layer.Draw(pdfGeoCanvas, labelsInLayers);
                layer.Close();
                pdfGeoCanvas.EndDrawing();
            }


This works fine for me in all the versions that I have tried.

is it possible that your labels only appear at a certain scale and that when your map is rendered your extent on the pdf is just pushing out of that scale range?



JeremyUser is Offline
06-04-2009 02:36 AM
Is there any way to draw a string vertically using XGraphics? I went through the solution for PDFSharp and I see the enumerator XStringFormatFlags.DirectionVertical is disabled and commented marked "Not used in this implemtation." will we be seeing it in a future release? or is there another way to draw vertical text? (other than using an adornment layer)


EdUser is Offline
06-04-2009 11:40 AM

Jeremy,

In your code you are using DynamicOverlay which is depricated, the code below is what i am using so it should be drawing every overlay.  Also, when stepping thru the code, the labelsInLayers object is populated with the label I see on the map.

Collection<simplecandidate></simplecandidate> labelsInLayers = new Collection<simplecandidate></simplecandidate>();
<p>&nbsp;</p>
</p>
<p>for (int i = 0; i < winformsMap1.Overlays.Count; i++)
 {
 foreach (Layer layer in ((LayerOverlay) winformsMap1.Overlays<i>).Layers)
 {
 pdfGeoCanvas.BeginDrawing(page, winformsMap1.CurrentExtent, GeographyUnit.Meter); layer.Open(); 
layer.Draw(pdfGeoCanvas, labelsInLayers); 
layer.Close(); 
pdfGeoCanvas.EndDrawing(); 
}
 }
 



JeremyUser is Offline
06-05-2009 02:42 AM
Sorry I'm using the web edition. which doesn't seem to have any property to get a collection of the all the base overlay classes. it seems I have to call it via its overlay type name. i.e. Dynamic, Static etc. not that any of this matters.

I've tested everything I can think of that you are doing in your code that varies from mine, yet mine still renders the labels to the pdf. (for example statically setting the GeographyUnits, or not using the MapExtentHelper)

Sorry, I can be of more assistance. hopefully you will hear from the ThinkGeo guys soon. They are usually extremely helpful.




YaleUser is Offline
06-14-2009 11:49 PM
Avatar
Thanks for your reply, Jememy!

Ed, I am wondering if your problem is solved, if not, just created a new issue post in the corresponding forum, we will try our best to find out and solve the problem.

Thanks.

Yale


JeremyUser is Offline
06-15-2009 03:00 AM
Any solution in view of the scaling issues I'm having in the new PDFSharp library?


YaleUser is Offline
06-15-2009 10:36 PM
Avatar
Ed, we already notice the problem you mentioned about the labeling stuff disappearing in the latest version (3.0.307 RC) version. And we fixed this problem and it will be available in next version. And you can ask for our support (support@thinkgeo.com) for temporary version if you are interests.

Or if you want, you can create a new post in the Desktop Edition forum if you are using the Desktop control.

Any more questions just let me know.

Thanks.

Yale


YaleUser is Offline
06-15-2009 10:49 PM
Avatar

Jeremy,

This is long-history posts, it seems you have 3 problems.

One is for the vertical drawing string supported in PdfSharp? PdfSharp is an open-source project. I am not sure in which version it will be supported. We will try to see if we can provide some way to go around this problem.

The other is about the extent not matching problem, I guess it is probably because it always snapped to some ZoomLevel and this will somehow change the final view extent.

The last one about the drawing about the AdormentLayer, we create a demo without our very simple AdormentLayer, it seems works.

Finally I suggest you create a separate post and paste the code needed in WebEdtion forum for a very quick and detailed solution.

Sorry for the inconvenience now.

Thanks.

Yale
 



EdUser is Offline
06-23-2009 05:06 PM
Thank Yale. I am using the desktop edition and as long as it is fixed in the next release that is great.

THanks


YaleUser is Offline
06-23-2009 08:21 PM
Avatar
Ed, Sounds Good!

Thanks for your interests!

Yale


RyanUser is Offline
11-25-2009 03:03 PM
Hi,

I was wondering if there was any fix for the issue where you get a NotSupportedException when you call canvas.ToGeoImage( )?

Thanks,

Ryan


JamesUser is Offline
11-26-2009 01:38 AM
Avatar

 

Ryan,
 
Sorry for inconvenience, we still not implement ToGeoImageCore method.
 
Actually, you can extend PdfGeoCanvas and implement it by yourself.
 
I think your problem is that you don’t know how to convert pdf to bitmap, if you get the bitmap you can easy convert to GeoImage.
Here is some information which can help you:
 
PdfSharp sample: Export Images:
 
How can I create images from an existing PDF file?
 
You can create image by using Ghostscript, PdfSharp has an extension for it, but MapSuite didn’t supply it, you can download the source code of PdfSharp from http://www.pdfsharp.net/Downloads.ashx , after download the package and extract files, there is a project called PdfSharp.Ghostscript and you can find a class called GSwhich has many API can help.
 
Please let me know if you have questions
 
Thanks
James
 


You are not authorized to post a reply.
Active Forums 4.1