Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#4216 closed enhancement (fixed)

[PATCH] Add support for writing geospatial PDF

Reported by: rouault Owned by: tbonfort
Priority: normal Milestone: 6.2 release
Component: Output-PDF Version: unspecified
Severity: normal Keywords: pdf
Cc:

Description

The attached patch relies on the very latest version of the PDF driver from GDAL trunk to add geospatial information to the PDF file produced by the Cairo/PDF mapserver backend.

In order to be triggered, one has to add a FORMATOPTION "GEO_ENCODING=ISO32000" into the OUTPUTFORMAT definition of the CAIRO/PDF driver. Additional options can also be added in order to set Info keywords. For example :

    OUTPUTFORMAT
        NAME pdf
        DRIVER "CAIRO/PDF"
        MIMETYPE "application/x-pdf"
        IMAGEMODE RGB
        EXTENSION "pdf"
        FORMATOPTION "GEO_ENCODING=ISO32000"
        FORMATOPTION "METADATA_ITEM:CREATOR=MapServer, with GDAL trunk"
        FORMATOPTION "METADATA_ITEM:PRODUCER=MapServer, with GDAL trunk"
    END

Attached a mapfile and an associate shapefile that demonstrate the patch.

The following work :

shp2img -m demo_geospatial_pdf.map -o out.pdf -s 1024 1024 -i "application/x-pdf"

and

QUERY_STRING="map=demo_geospatial_pdf.map&SERVICE=WMS&request=GetMap&version=1.1.1&layers=demo_geospatial_pdf&styles=&srs=EPSG:4326&transparent=FALSE&format=application/x-pdf&width=1024&height=1024&bbox=2,48,3,49" REQUEST_METHOD=GET ./mapserv > out.pdf

Attachments (3)

demo_geospatial_pdf.zip (2.9 KB ) - added by rouault 12 years ago.
Demo map and data
maputil_geospatial_pdf_ticket_4216.patch (4.9 KB ) - added by rouault 12 years ago.
Patch
ticket4216.patch (8.7 KB ) - added by rouault 12 years ago.
Revised version of the patch that only significantly touches mapcairo.c

Download all attachments as: .zip

Change History (11)

by rouault, 12 years ago

Attachment: demo_geospatial_pdf.zip added

Demo map and data

by rouault, 12 years ago

Patch

comment:1 by tbonfort, 12 years ago

Owner: changed from assefa to tbonfort

Even,

I believe the functionality you added to maputil.c would be more suited to go in mapcairo.c, in saveImageCairo(). I'm not particularly keen in complicating the save functions in maputil.c, and furthermore, in mapcairo.c, you have access to the raw pdf bytes without having to save to an intermediate file on disk, if you are able to load that directly in gdal.

comment:2 by rouault, 12 years ago

Thomas,

I indeed wanted at first to add the functionnality into saveImageCairo(), but as I'm not familiar with the code, I somehow thought this wasn't possible. But actually while looking at it again, it might be possible. I'll try to see if I can come with a patch to change it.

If the GDAL PDF driver is compiled against libpoppler (which supports GDAL VirtualIO), I can create a /vsimem virtual file from the r->outputStream buffer, that can later be opened by the GDAL PDF driver and to be updated with the geo stuff.

If the GDAL PDF driver is compiled against libpodofo (which does *not* support GDAL VirtualIO), then I'll need a "real" temporary file. In my current patch, I use the following call "real_filename = msTmpFile(map, map->mappath, NULL, "pdf");" which needs a map object, but this is not passed to saveImageCairo(). Any idea how to build a temporary filename from saveImageCairo() ?

Thanks

comment:3 by tbonfort, 12 years ago

You can call msTmpPath with a NULL mapObj and mappath, in which case it will use the system specific temp path instead of the mapObj provided one. This seems like a good enough solution to me, it is used elsewhere to.

-- thomas

comment:4 by tbonfort, 12 years ago

Actually you'll need the mapObj itself to get the georeferencing information. I have nothing against modifying the saveImage() renderer vtable signature to take a mapObj*, as long as the implementations cleanly support a NULL value for it.

by rouault, 12 years ago

Attachment: ticket4216.patch added

Revised version of the patch that only significantly touches mapcairo.c

comment:5 by rouault, 12 years ago

Attached a revised version of the patch that implements the above discussion : code essentially contained in mapcairo.c, and signature of the saveImage() callback changed to accept an additional mapObj *map argument.

comment:6 by tbonfort, 12 years ago

I won't speak about the actual gdal/geopdf part of the code as you're the expert there. As far as the integration with mapserver goes, I'm fine with it you can go ahead and commit.

cheers, thomas

comment:7 by rouault, 12 years ago

Keywords: pdf added
Milestone: 6.2 release
Resolution: fixed
Status: newclosed
Type: defectenhancement

r13186 /trunk/mapserver/ (9 files): PDF backend: add support for generating geospatial PDF, when GDAL 2.0 with PDF driver is used, and the GEO_ENCODING FORMATOPTION (set to ISO32000 or OGC_BP) is added to the OUTPUTFORMAT definition. (#4216)

I've also created a documentation ticket about the new feature (#4218), so closing that ticket.

comment:8 by rouault, 12 years ago

r13191 /trunk/mapserver/mapscript/ (python/pyextend.i swiginc/image.i): Fix mapscript compilation error due to r13186 (#4216)

Note: due to my total unfamilarity with mapscript, I didn't see an easy way to fetch the map object, so I passed a NULL pointer, which should be fine for all existing use cases (but prevent enabling geospatial PDF output from it)

Note: See TracTickets for help on using tickets.