wiki:PHPMapscriptPDF

Outputting maps to PDF

0. Background

While Mapserver can render to PDF directly, I found I got more aesthetic results by rendering to a PNG and inserting that into a PDF document. This is not the only way to create a PDF document, but it works for me. You will need to have support for PDFLib (http://www.pdflib.com) compiled into your PHP install.

This example shows the key parts of the process, you will need to furnish parts of the script yourself (depending on your app) and repeat the process for each map element you want to include.

1. How does it work?

In brief, we will pass parameters required to render a map to a PHP script that will:

  • create a PDF document
  • Render a PNG view at a suitably higher resolution
  • Insert the PNG
  • Buffer it and send it to the user

2. Create the PDF document

I used an example similar to the one given on the PHP website: http://www.php.net/manual/en/ref.pdf.php

    $my_pdf = pdf_new();
    ....

To create a new PDF document. Get this stage and step 5 working before you try inserting Mapserver elements.

3. Render PNG views at a suitable resolution

Work back from the assumption that you will need no more than 300 dpi on your page for your map to look presentable. For an A4 map, I am using 150 dpi for an 8' x 8' main map, which is 1200 x 1200 pixels.

    $map->set(width,1200);
    $map->set(height,1200);

Of course, our map will not be very useful unless it is zoomed in to the extent our user requested, and the layers they selected are switched on. Maintain arrays in your application that record:

  • The current extent (say $ext[])
  • Layer status (say $layer[])

Open your map file and pass these back through to set the map file into the state the user is expecting, something like:

    $map->setextent($ext[0], $ext[1], $ext[2], $ext[3]);

    while($layer[]) {
        $layer=$map->getLayer($n);
        if($layer[$n]==1) {
            $layer->set(status,1);
        } else {
            $layer->set(status,0);
        }
    }

Now you will need to save a rendered view to a PNG file.

    $img = $map->draw();
    $url = $img->saveWebImage(MS_PNG, 0, 0, 0);

Use the same method for all your map elements, such as drawReferenceMap?(), drawScaleBar?() and drawLegend().

4. Insert the PNG elements into your PDF document.

This is really easy, use the pdf_open_image_file() function to import the map elements into your PDF document:

    $element = pdf_open_image_file($my_pdf, "png", "$webroot/$url");
    pdf_place_image($my_pdf, $element, $xpos, $ypos);
    pdf_close_image($my_pdf, $element);

Repeated as needed for any map elements you created.

5. Buffer the PDF and send it to the user.

Assuming we have been creating the document $my_pdf, when we are done, we merely buffer it and send it to the user using echo():

    ....
    pdf_close($my_pdf);

    $data = pdf_get_buffer($my_pdf);

    header('Content-type: application/pdf');
    header('Content-disposition: inline; filename=my_pdf.pdf');
    header('Content-length: ' . strlen($data) );

    echo $data;

?>

Gotcha: remember that you cannot send headers if you have at any stage outputed text to the browser.

6. Additional stuff to try

Rendering everything as PNG can look ugly, so I step through the key and extract labels so I can render them using PDF's text functions.

This can be done for other map element, such as map titles, layer descriptions, or anything else that can be read from the map file.


back to PHPMapScript

Last modified 10 years ago Last modified on Jan 27, 2009 9:51:36 AM