3

I'd like to convert a normal PDF to a geospatial PDF.

To do this I'd like to use another PDF as a template which already has all the correct SRS, bounds etc.

To start I exported a PDF from ArcMAP with the geospatial info etc. I can see this info using

gdalsrsinfo geopdf.pdf

which yields

PROJ.4 : +proj=lcc +lat_0=44.25 +lon_0=-109.5 +lat_1=45 +lat_2=49 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m +no_defs

OGC WKT2:2018 :
PROJCRS["NAD83(2011) / Montana",
    BASEGEOGCRS["NAD83(2011)",
        DATUM["NAD83 (National Spatial Reference System 2011)",
            ELLIPSOID["GRS 1980",6378137,298.257222101,
                LENGTHUNIT["metre",1]],
            ID["EPSG",1116]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["Degree",0.0174532925199433]]],
    CONVERSION["unnamed",
        METHOD["Lambert Conic Conformal (2SP)",
            ID["EPSG",9802]],
        PARAMETER["Latitude of false origin",44.25,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8821]],
        PARAMETER["Longitude of false origin",-109.5,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8822]],
        PARAMETER["Latitude of 1st standard parallel",45,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8823]],
        PARAMETER["Latitude of 2nd standard parallel",49,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8824]],
        PARAMETER["Easting at false origin",600000,
            LENGTHUNIT["metre",1],
            ID["EPSG",8826]],
        PARAMETER["Northing at false origin",0,
            LENGTHUNIT["metre",1],
            ID["EPSG",8827]]],
    CS[Cartesian,2],
        AXIS["(E)",east,
            ORDER[1],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]],
        AXIS["(N)",north,
            ORDER[2],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]]]

Also, gdalinfo geopdf.pdf yields below

Driver: PDF/Geospatial PDF
Files: geopdf.pdf
Size is 3600, 3600
Coordinate System is:
PROJCRS["NAD83(2011) / Montana",
    BASEGEOGCRS["NAD83(2011)",
        DATUM["NAD83 (National Spatial Reference System 2011)",
            ELLIPSOID["GRS 1980",6378137,298.257222101,
                LENGTHUNIT["metre",1]],
            ID["EPSG",1116]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["Degree",0.0174532925199433]]],
    CONVERSION["unnamed",
        METHOD["Lambert Conic Conformal (2SP)",
            ID["EPSG",9802]],
        PARAMETER["Latitude of false origin",44.25,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8821]],
        PARAMETER["Longitude of false origin",-109.5,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8822]],
        PARAMETER["Latitude of 1st standard parallel",45,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8823]],
        PARAMETER["Latitude of 2nd standard parallel",49,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8824]],
        PARAMETER["Easting at false origin",600000,
            LENGTHUNIT["metre",1],
            ID["EPSG",8826]],
        PARAMETER["Northing at false origin",0,
            LENGTHUNIT["metre",1],
            ID["EPSG",8827]]],
    CS[Cartesian,2],
        AXIS["(E)",east,
            ORDER[1],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]],
        AXIS["(N)",north,
            ORDER[2],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]]]
Data axis to CRS axis mapping: 1,2
GeoTransform =
  525499.2672571723, 1.636947702676121, -3.762484079644317e-05
  190791.6800958478, 6.53913709043272e-05, -1.637145919360133
Metadata:
  CREATION_DATE=D:20240429142416Z
  CREATOR=Esri ArcMap 10.8.0.12790
  NEATLINE=POLYGON ((525526.372661148 184925.412013116,525526.590629083 190757.591162772,531351.253783962 190757.791660127,531351.203683426 184925.676879678,525526.372661148 184925.412013116))
Corner Coordinates:
Upper Left  (  525499.267,  190791.680) (110d27'41.61"W, 45d57'45.73"N)
Lower Left  (  525499.132,  184897.955) (110d27'38.26"W, 45d54'34.78"N)
Upper Right (  531392.279,  190791.916) (110d23' 7.82"W, 45d57'47.99"N)
Lower Right (  531392.144,  184898.190) (110d23' 4.73"W, 45d54'37.03"N)
Center      (  528445.705,  187844.935) (110d25'23.10"W, 45d56'11.41"N)
Band 1 Block=3600x1 Type=Byte, ColorInterp=Red
Band 2 Block=3600x1 Type=Byte, ColorInterp=Green
Band 3 Block=3600x1 Type=Byte, ColorInterp=Blue

I have another PDF I've been working on in Illustrator.. It has the exact same extent, srs etc as the template PDF I created. I tried exporting the template SRS info as a WKT and then using that in a gdal_translate call like below

gdalsrsinfo -o wkt geopdf.pdf > target.wkt
gdal_translate -a_srs target.wkt pdfToConvert.pdf newConvertedPdf.pdf
gdalinfo newConvertedPdf.pdf

This command runs fine but the newConvertedPdf does not have any of the projection information

gdalinfo newConvertedPdf.pdf

Yields

Driver: PDF/Geospatial PDF
Files: newConvertedPdf.pdf
Size is 3600, 3600
Metadata:
  CREATION_DATE=D:20240429142336-06'00'
  CREATOR=Adobe Illustrator 26.0 (Windows)
  DPI=72
  PRODUCER=Adobe PDF library 16.03
  TITLE=newConvertedPdf
Corner Coordinates:
Upper Left  (    0.0,    0.0)
Lower Left  (    0.0, 3600.0)
Upper Right ( 3600.0,    0.0)
Lower Right ( 3600.0, 3600.0)
Center      ( 1800.0, 1800.0)
Band 1 Block=3600x1 Type=Byte, ColorInterp=Red
Band 2 Block=3600x1 Type=Byte, ColorInterp=Green
Band 3 Block=3600x1 Type=Byte, ColorInterp=Blue

Any other suggested workflows for converting a PDF to geospatial PDF using GDAL ?

5
  • The gdal_translate docs specify a ".prj" file for the -a_srs argument, try renaming your target.wkt to target.prj. You also need to grab the extent coordinates from geopdf.pdf and pass in the -a_ullr argument.
    – user2856
    Commented Apr 29 at 22:31
  • Projection is only one half of georeferencing. Add also the neatline or ground control points of the template image from gdalinfo. Does the other PDF cover exactly the same area than the template?
    – user30184
    Commented Apr 30 at 6:10
  • @user30184 - yes, the other PDF is an exact match
    – jotamon
    Commented Apr 30 at 14:40
  • Where is the information about the source file gdalinfo geopdf.pdf?
    – user30184
    Commented Apr 30 at 20:32
  • @user30184 - just updated with the gdalinfo for geopdf
    – jotamon
    Commented May 1 at 19:37

1 Answer 1

1

I used this PDF file for testing https://github.com/OSGeo/gdal/blob/master/autotest/gdrivers/data/pdf/adobe_style_geospatial.pdf

I made a copy of that file (crs_test_2.pdf) and removed the coordinate system and georeferencing with two gdal_edit commands

gdal_edit -unsetgt crs_test_2.pdf 
gdal_edit -a_srs "" crs_test_2.pdf 

Finding the right syntax required some experimenting. Gdal_edit is obviously not well tested with PDF, but anyway, the result was a clean PDF.

I saved the CRS into a file with your command

gdalsrsinfo -o wkt adobe_style_geospatial.pdf > target.wkt

I also took the upper-left - lower-right coordinates from the original PDF.

Both the coordinate system and ullr coordinates must be assigned to the clean PDF with the same gdal_translate command.

gdal_translate -a_srs target.wkt -a_ullr 333274.617 4940391.759 387274.780 4870443.319 crs_test_2.pdf crs_test_3.pdf

This way the crs_test_3.pdf has the same coordinate system and the corner coordinates than the original PDF. However, the original PDF had a neatline that covered a smaller area within the PDF file. That cannot be preserved by using gdal_translate.

Original:

  NEATLINE=POLYGON ((338304.150126182 4896673.63942063,338304.17729383 4933414.79937582,382774.271384475 4933414.54626366,382774.767330032 4896674.27358034,338304.150126182 4896673.63942063))

Created with gdal_translate:

  NEATLINE=POLYGON ((333274.617000003 4940391.759,333274.617000001 4870443.319,387274.779999999 4870443.319,387274.780000002 4940391.759,333274.617000003 4940391.759))

It is possible to copy the neatline by using Python. An example can be found from the GDAL autotests https://github.com/OSGeo/gdal/blob/master/autotest/gdrivers/pdf.py#L1196

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.