Opened 11 years ago

Closed 4 years ago

#4176 closed defect (wontfix)

OSRExportToProj4() loses datum name, depends on capitalization?

Reported by: rbanfield Owned by: warmerdam
Priority: normal Milestone: closed_because_of_github_migration
Component: default Version: 1.8.1
Severity: normal Keywords:
Cc:

Description

Datums are dropping out of proj.4 strings from OSRExportToProj4(). Strangely, this behavior is inconsistent and depends upon the capitalization of the datum. I believe that if a datum is specified on input, it should also be exported as part of the proj4 string.

I have included a tiny program:

#include "ogr_spatialref.h"

int main(int argc, char** argv)
{
  char* exportProj4;
  char* outputWkt;

  OGRSpatialReference inputSRS;
  inputSRS.importFromProj4(argv[1]);
  inputSRS.exportToWkt(&outputWkt);

  OGRSpatialReferenceH outputSRS = OSRNewSpatialReference(outputWkt);
  OSRExportToProj4(outputSRS, &exportProj4);

  printf("Original proj4 = %s\n", argv[1]);
  printf("Exported proj4 = %s\n", exportProj4);
}

Here is some sample output from 2 runs of the program:

Original proj4 = +proj=utm +zone=17 +datum=nad27 +units=m +no_defs
Exported proj4 = +proj=utm +zone=17 +datum=NAD27 +units=m +no_defs 

Original proj4 = +proj=utm +zone=17 +datum=NAD27 +units=m +no_defs
Exported proj4 = +proj=utm +zone=17 +ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat +units=m +no_defs 

Change History (5)

comment:1 by Even Rouault, 11 years ago

Here's the result of my investigations.

importFromProj4() begins by calling OCTProj4Normalize() (line 375 of ogr_srs_proj4.cpp) which in turn builds a proj4 definition and serialize it again as a string. During this normalization step, proj4 will match the "NAD27" (uppercase) string (case sensitive match) and replace it by "+ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat" (this is done by pj_datums.c in proj4 sources). This will be then analyzed and conserved when building the WKT representation of the SRS object and als preserved later when converting back to proj4 string with exportToProj4().

In the "nad27" (lowercase) case, proj4 doesn't recognize the string and let is as such. But importFromProj4() has special processing for recognizing certain datum names (line 877) and putting the right value in the SRS object. The test here is case insensitive, so it will end up recognizing it as NAD27, hence the uppercase value will be properly put as uppercase by exportToProj4()

Now the question I'm wondering is : what is the consequence for you of "+datum=NAD27" being expanded as "+ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat". This should have no consequence of how proj4 will do its reprojection (I've verified it). What is your use case ? Do you rely on the structure of proj4 strings for some processing ? I can see that if you re-import "+proj=utm +zone=17 +ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat +units=m +no_defs", you will loose the information that it is equivalent to NAD27, but do you need this ?

comment:2 by rbanfield, 11 years ago

We support a subset of the datums in gdal (ones that we have completely verified work with our system), and we determine if a map is in that subset by looking at the value of OSRGetAttrValue() for "DATUM". We also show the datum to the user in the display. In the case where +datum=x has been replaced, OSRGetAttrValue returns "unknown" for the datum.

comment:3 by Even Rouault, 11 years ago

So if I've well understood your use case, you do the following operations :

  1) you have a SRS with "DATUM" = "North_American_Datum_1927"
  2) you export it a proj4 string
  3) you reimport this proj4 string
  4) you query OSRGetAttrValue() for "DATUM" and expect to find "North_American_Datum_1927", but here you find "unknown"

Question : why do you store a proj4 string and not the WKT ? I don't believe the proj4 string is claimed to be guaranteed to be perfectly round-trippable with the WKT representation of a SRS. The only 1-1 matching is between the WKT representation and the OSR model. But you have information loss when exporting to proj4 (citation strings, authority name and codes, etc...).

I'm not too sure how we could "fix" OSR for your use case. One possibility is to add new code after the OCTProj4Normalize() step, that would look for "+ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat" and remove it, or persumably some more general fix to undo the extension of +datum into +ellps +towgs84 or +ellps +nadgrids. The "+datum=" is preserved in this normalization step, so that would be OK. (which explains why when you query the DATUM just after the importFromProj4(), there's still NAD27 reported)

By the way, that might be a workaround to add in your code for now : look for "+ellps=clrk66 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat" and replace by "+datum=NAD27".

PS: If I remember well, you mentionned a change in behaviour between GDAL 1.8 and later and GDAL 1.7.x . I think this is due to fixes done for #3450 and #3737 . I've not tested, but it is likely that in 1.7.x, there is a non-desired +towgs84 in the proj4 string, so the new behaviour is generally more correct, even if it breaks your use case where you seem to expect round-trippability of proj4 strings.

comment:4 by Jukka Rahkonen, 8 years ago

What is your view about this ticket now three years later, rbanfield?

comment:5 by Even Rouault, 4 years ago

Milestone: closed_because_of_github_migration
Resolution: wontfix
Status: newclosed

This ticket has been automatically closed because Trac is no longer used for GDAL bug tracking, since the project has migrated to GitHub. If you believe this ticket is still valid, you may file it to https://github.com/OSGeo/gdal/issues if it is not already reported there.

Note: See TracTickets for help on using tickets.