Ticket #4216 (closed enhancement: fixed)

Opened 15 months ago

Last modified 15 months ago

[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

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

Change History

Changed 15 months ago by rouault

Demo map and data

Changed 15 months ago by rouault

Patch

Changed 15 months ago by tbonfort

  • 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.

Changed 15 months ago by rouault

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

Changed 15 months ago by tbonfort

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

Changed 15 months ago by tbonfort

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.

Changed 15 months ago by rouault

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

Changed 15 months ago by rouault

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.

Changed 15 months ago by tbonfort

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

Changed 15 months ago by rouault

  • keywords pdf added
  • status changed from new to closed
  • type changed from defect to enhancement
  • resolution set to fixed
  • milestone set to 6.2 release

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.

Changed 15 months ago by rouault

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.