[gdal-dev] Re: GeoPDF - incorrect neatline values computed for OGC PDF

Even Rouault even.rouault at mines-paris.org
Sun Nov 28 09:38:35 EST 2010


Robert,

I'm not sure to understand what you think is wrong. On the link you've 
provided, I've compared the neatline coordinates reported by the GDAL PDF 
driver and the ones reported by the TerraGo toolbar. They match with a quite 
good precision. So you have to be more specific of what you think is wrong 
(what are the bad figures ? what are the expected figures).

As far as explaining how the code works, well, this is always a bit difficult 
and especially since the line number you mention don't match with my version, 
as driver has changed a bit since you've checked it in.

Basically, the GDAL geotransform is derived from the CTM object with a 
rescaling of the scaling terms of the geotransform according to the specified 
DPI. The corner coordinates reported by GDAL are the corners of the whole 
rasterized image (including the white area) and are not at all computed from 
the neatline definition (which in this example is the black rectangle).

The neatline is computed by transforming from PDF point coordinates to 
projected coordinates by using the computed geotransform and the DPI. The 
poDS->nRasterYSize - poRing->getY(i) * dfPixelPerPt trick is due to a 
difference of Y origin between GDAL and PDF conventions (or even within PDF, as 
they are multiple coordinate referentials). I don't recall the details but it 
was necessary and I was satisfied with the result after a few cycles of write-
code-and-test-it :-)

Le mercredi 17 novembre 2010 03:25:48, Robert Zermeno a écrit :
> Even and GDAL community,
>  
> I hope you can enlighten me on the issue of computing neatline values.  The
> solution presented in GDAL to compute the neatline values is not fully
> correct (file: pdfdataset.cpp lines 743-749) 
> specifically:
>                 double X = poDS->adfGeoTransform[0] + x *
> poDS->adfGeoTransform[1] + y * poDS->adfGeoTransform[2]; double Y =
> poDS->adfGeoTransform[3] + x * poDS->adfGeoTransform[4] + y *
> poDS->adfGeoTransform[5]; 
> but to understand the two lines of code above, you need to understand what
> was done before. 
> The case where it is correct is when:
>  
> 1.  - PDF is  OGC Standard
>      - Neatline values are the corner points of the image.
>  
> The case when GDAL does not compute correct Neatline values is when:
>  
> 2. -PDF is OGC Standard
>     - Neatline values are not the corner points of the image.
>  
> Let me elaborate on the case when it does not compute neatline values
> correctly.  An example file is taken from:
> http://giigt.tec.army.mil/GeoPDFgallery/AU_NZ_Re-seller/Env_Sample_geo.pdf
> 
> here is GDAL's output:
> NOTE: I have modified GDAL code to make default DPI to be 110.
>      
> C:\apps>gdalinfo.exe c:\Env_Sample_geo.pdf
> PDF: OGC Encoding Best Practice style detected
> PDF: LGIDict Version : 2.1
> PDF: This is a the largest neatline for now
> PDF: CTM[0] = 1.4111110661
> PDF: CTM[1] = 0
> PDF: CTM[2] = 0
> PDF: CTM[3] = 1.4111110661
> PDF: CTM[4] = 725048.2016161948
> PDF: CTM[5] = 7671532.018003316
> PDF: Datum = HEN
> PDF: Projection.ProjectionType = TC
> GDAL: GDALOpen(c:\Env_Sample_geo.pdf, this=026BE308) succeeds as PDF.
> Driver: PDF/Geospatial PDF
> GDAL: GDALDefaultOverviews::OverviewScan()
> Files: c:\Env_Sample_geo.pdf
> Size is 1285, 909
> Coordinate System is:
> PROJCS["UTM Zone 55, Southern Hemisphere",
>     GEOGCS["unknown",
>         DATUM["unknown",
>             SPHEROID["International 1924",6378388,297],
>             TOWGS84[-333,-222,114,0,0,0,0]],
>         PRIMEM["Greenwich",0],
>         UNIT["degree",0.0174532925199433]],
>     PROJECTION["Transverse_Mercator"],
>     PARAMETER["latitude_of_origin",0],
>     PARAMETER["central_meridian",147],
>     PARAMETER["scale_factor",0.9996],
>     PARAMETER["false_easting",500000],
>     PARAMETER["false_northing",10000000],
>     UNIT["Meter",1]]
> Origin = (725048.201616194800000,7672372.337465400800000)
> Pixel Size = (0.923636334174545,-0.923636334174545)
> GeoTransform =
>  725048.20161619480,  0.92363633417454549,  0.00000000000000000
>  7672372.3374654008,  -0.0000000000000000, -0.92363633417454549
> Metadata:
>   NEATLINE=POLYGON ((725124.91858881968
> 7671671.0094531905,725124.91858881968 76
> 72311.3218032392,726165.27821117197 7672311.3218032392,726165.27821117197
> 767167 1.0094531905,725124.91858881968 7671671.0094531905))
> OGRCT: Source: +proj=utm +zone=55 +south +ellps=intl
> +towgs84=-333,-222,114,0,0, 0,0 +units=m +no_defs
> OGRCT: Target: +proj=longlat +ellps=intl +towgs84=-333,-222,114,0,0,0,0
> +no_defs Corner Coordinates:
> Upper Left  (  725048.202, 7672372.337) (149d 9'55.60"E, 21d 2' 7.62"S)
> Lower Left  (  725048.202, 7671532.752) (149d 9'55.99"E, 21d 2'34.91"S)
> Upper Right (  726235.074, 7672372.337) (149d10'36.69"E, 21d 2' 7.10"S)
> Lower Right (  726235.074, 7671532.752) (149d10'37.09"E, 21d 2'34.39"S)
> Center      (  725641.638, 7671952.545) (149d10'16.34"E, 21d 2'21.00"S)
> Band 1 Block=1285x1 Type=Byte, ColorInterp=Red
> Band 2 Block=1285x1 Type=Byte, ColorInterp=Green
> Band 3 Block=1285x1 Type=Byte, ColorInterp=Blue
> GDAL: GDALClose(c:\Env_Sample_geo.pdf, this=026BE308)
> GDAL: GDALDeregister_GTiff() called.
>  
> The Corner points reported should be accurate.  I have an unclassified file
> which the neatline is the height and width of the image, so the corner
> points are the neatlines.  In that case, all points are correct.
> The issues is when you have a defined neatline within the PDF that is
> smaller than the image we are looking at (i.e. Neatline != MediaBox)
> FOr this file, the top-left corner of the neatline is very accurate, but
> the top-right, bottom-right are way off.
> 
> Can you describe to me how you computed the Neatline values (X,Y).  I
> understand that the CTM is the PDF page coordinate space transformation to
> projected coordinate system (This file is UTM (Northing/Easting). Then you
> will use that information to compute the Transformation matrix of
> projection coordinates onto the image space.
> 
> Once you have found the GeoTransform you use that information with the
> NeatLine values registered in the PDF to translate the PDF page coordinate
> to projected coordinates (this case, Northing/Easting).
> 
> The problem I found, is the neatline values are all not accurate.  The
> values presented do not provided an acceptable bounding region that
> defines the coordinate space.
> Can you please provide input to help me figure out why this is not working
> accurately?  Specifically, it would be nice if you can explain how, and
> why, you obtained the computations of the GeoTransform (Look at file
> pdfdataset.cpp lines 682-689) and Neatline values (Look at file
> pdfdataset.cpp lines 712-718)
> 
> It would be nice if you can take the time to help me resolve this.
> 
> Summary:
> 1.  From above, please explain your logic to compute the neatline,
> geotransform 2. when computing:
>     double y = poDS->nRasterYSize - poRing->getY(i) * dfPixelPerPt;  
>     Line 713 in pdfdataset.cpp  why are you doing that?
> 
> I have tried to explain in a simple manner.  However, I know I did not do
> the best job because I am still trying to wrap my brain around how
> transforming from PDF page --> projected coords (UTM) by using the CTM to
> create the GeoTransform (projected Coords affine transformation) and then
> use it to compute the proper UTM coordinate for a given neatline point
> provided in the PDF. 
> Robert


More information about the gdal-dev mailing list