LCOV - code coverage report
Current view: top level - frmts/gxf - gxf_proj4.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 259 0.0 %
Date: 2025-01-18 12:42:00 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GXF Reader
       4             :  * Purpose:  Handle GXF to PROJ.4 projection transformation.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1998, Global Geomatics
       9             :  * Copyright (c) 1998, Frank Warmerdam
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "gxfopen.h"
      15             : 
      16             : #define SAFE_strcat(x, y)                                                      \
      17             :     snprintf(x + strlen(x), sizeof(x) - strlen(x), "%s", y)
      18             : 
      19             : /************************************************************************/
      20             : /*                     GXFGetMapProjectionAsPROJ4()                     */
      21             : /************************************************************************/
      22             : 
      23             : /**
      24             :  * Return the GXF Projection in PROJ.4 format.
      25             :  *
      26             :  * The returned string becomes owned by the caller, and should be freed
      27             :  * with CPLFree() or VSIFree().  The return value will be "unknown" if
      28             :  * no projection information is passed.
      29             :  *
      30             :  * The mapping of GXF projections to PROJ.4 format is not complete.  Please
      31             :  * see the gxf_proj4.c code to better understand limitations of this
      32             :  * translation.  In particular, PROJ.4 knows little about datums.
      33             :  *
      34             :  * For example, the following GXF definitions:
      35             :  * <pre>
      36             :  * #UNIT_LENGTH
      37             :  * m,1
      38             :  * #MAP_PROJECTION
      39             :  * "NAD83 / UTM zone 19N"
      40             :  * "GRS 1980",6378137,0.081819191,0
      41             :  * "Transverse Mercator",0,-69,0.9996,500000,0
      42             :  * </pre>
      43             :  *
      44             :  * Would translate to:
      45             :  * <pre>
      46             :  * +proj=tmerc +lat_0=0 +lon_0=-69 +k=0.9996 +x_0=500000 +y_0=0 +ellps=GRS80
      47             :  * </pre>
      48             :  *
      49             :  * @param hGXF handle to GXF file, as returned by GXFOpen().
      50             :  *
      51             :  * @return string containing PROJ.4 projection.
      52             :  */
      53             : 
      54           0 : char *GXFGetMapProjectionAsPROJ4(GXFHandle hGXF)
      55             : 
      56             : {
      57           0 :     GXFInfo_t *psGXF = hGXF;
      58           0 :     char **papszMethods = NULL;
      59           0 :     char szPROJ4[512] = {0};
      60             : 
      61             :     /* -------------------------------------------------------------------- */
      62             :     /*      If there was nothing in the file return "unknown".              */
      63             :     /* -------------------------------------------------------------------- */
      64           0 :     if (CSLCount(psGXF->papszMapProjection) < 2)
      65           0 :         return (CPLStrdup("unknown"));
      66             : 
      67             :     /* -------------------------------------------------------------------- */
      68             :     /*      Parse the third line, looking for known projection methods.     */
      69             :     /* -------------------------------------------------------------------- */
      70           0 :     if (psGXF->papszMapProjection[2] != NULL)
      71             :     {
      72           0 :         if (strlen(psGXF->papszMapProjection[2]) > 80)
      73           0 :             return (CPLStrdup(""));
      74           0 :         papszMethods = CSLTokenizeStringComplex(psGXF->papszMapProjection[2],
      75             :                                                 ",", TRUE, TRUE);
      76             :     }
      77             : 
      78           0 :     if (papszMethods == NULL || papszMethods[0] == NULL ||
      79           0 :         EQUAL(papszMethods[0], "Geographic"))
      80             :     {
      81           0 :         SAFE_strcat(szPROJ4, "+proj=longlat");
      82             :     }
      83             : 
      84             : #ifdef notdef
      85             :     else if (EQUAL(papszMethods[0], "Lambert Conic Conformal (1SP)") &&
      86             :              CSLCount(papszMethods) > 5)
      87             :     {
      88             :         /* notdef: It isn't clear that this 1SP + scale method is even
      89             :            supported by PROJ.4
      90             :            Later note: It is not. */
      91             : 
      92             :         SAFE_strcat(szPROJ4, "+proj=lcc");
      93             : 
      94             :         SAFE_strcat(szPROJ4, " +lat_0=");
      95             :         SAFE_strcat(szPROJ4, papszMethods[1]);
      96             : 
      97             :         SAFE_strcat(szPROJ4, " +lon_0=");
      98             :         SAFE_strcat(szPROJ4, papszMethods[2]);
      99             : 
     100             :         SAFE_strcat(szPROJ4, " +k=");
     101             :         SAFE_strcat(szPROJ4, papszMethods[3]);
     102             : 
     103             :         SAFE_strcat(szPROJ4, " +x_0=");
     104             :         SAFE_strcat(szPROJ4, papszMethods[4]);
     105             : 
     106             :         SAFE_strcat(szPROJ4, " +y_0=");
     107             :         SAFE_strcat(szPROJ4, papszMethods[5]);
     108             :     }
     109             : #endif
     110           0 :     else if (EQUAL(papszMethods[0], "Lambert Conic Conformal (2SP)") ||
     111           0 :              EQUAL(papszMethods[0], "Lambert Conformal (2SP Belgium)"))
     112             :     {
     113             :         /* notdef: Note we are apparently losing whatever makes the
     114             :            Belgium variant different than normal LCC, but hopefully
     115             :            they are close! */
     116             : 
     117           0 :         SAFE_strcat(szPROJ4, "+proj=lcc");
     118             : 
     119           0 :         if (CSLCount(papszMethods) > 1)
     120             :         {
     121           0 :             SAFE_strcat(szPROJ4, " +lat_1=");
     122           0 :             SAFE_strcat(szPROJ4, papszMethods[1]);
     123             :         }
     124             : 
     125           0 :         if (CSLCount(papszMethods) > 2)
     126             :         {
     127           0 :             SAFE_strcat(szPROJ4, " +lat_2=");
     128           0 :             SAFE_strcat(szPROJ4, papszMethods[2]);
     129             :         }
     130             : 
     131           0 :         if (CSLCount(papszMethods) > 3)
     132             :         {
     133           0 :             SAFE_strcat(szPROJ4, " +lat_0=");
     134           0 :             SAFE_strcat(szPROJ4, papszMethods[3]);
     135             :         }
     136             : 
     137           0 :         if (CSLCount(papszMethods) > 4)
     138             :         {
     139           0 :             SAFE_strcat(szPROJ4, " +lon_0=");
     140           0 :             SAFE_strcat(szPROJ4, papszMethods[4]);
     141             :         }
     142             : 
     143           0 :         if (CSLCount(papszMethods) > 5)
     144             :         {
     145           0 :             SAFE_strcat(szPROJ4, " +x_0=");
     146           0 :             SAFE_strcat(szPROJ4, papszMethods[5]);
     147             :         }
     148             : 
     149           0 :         if (CSLCount(papszMethods) > 6)
     150             :         {
     151           0 :             SAFE_strcat(szPROJ4, " +y_0=");
     152           0 :             SAFE_strcat(szPROJ4, papszMethods[6]);
     153             :         }
     154             :     }
     155             : 
     156           0 :     else if (EQUAL(papszMethods[0], "Mercator (1SP)") &&
     157           0 :              CSLCount(papszMethods) > 5)
     158             :     {
     159             :         /* notdef: it isn't clear that +proj=merc support a scale of other
     160             :            than 1.0 in PROJ.4 */
     161             : 
     162           0 :         SAFE_strcat(szPROJ4, "+proj=merc");
     163             : 
     164           0 :         SAFE_strcat(szPROJ4, " +lat_ts=");
     165           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     166             : 
     167           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     168           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     169             : 
     170           0 :         SAFE_strcat(szPROJ4, " +k=");
     171           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     172             : 
     173           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     174           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     175             : 
     176           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     177           0 :         SAFE_strcat(szPROJ4, papszMethods[5]);
     178             :     }
     179             : 
     180           0 :     else if (EQUAL(papszMethods[0], "Mercator (2SP)") &&
     181           0 :              CSLCount(papszMethods) > 4)
     182             :     {
     183             :         /* notdef: it isn't clear that +proj=merc support a scale of other
     184             :            than 1.0 in PROJ.4 */
     185             : 
     186           0 :         SAFE_strcat(szPROJ4, "+proj=merc");
     187             : 
     188           0 :         SAFE_strcat(szPROJ4, " +lat_ts=");
     189           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     190             : 
     191           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     192           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     193             : 
     194           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     195           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     196             : 
     197           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     198           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     199             :     }
     200             : 
     201           0 :     else if (EQUAL(papszMethods[0], "Hotine Oblique Mercator") &&
     202           0 :              CSLCount(papszMethods) > 7)
     203             :     {
     204             :         /* Note that only the second means of specifying omerc is supported
     205             :            by this code in GXF. */
     206           0 :         SAFE_strcat(szPROJ4, "+proj=omerc");
     207             : 
     208           0 :         SAFE_strcat(szPROJ4, " +lat_0=");
     209           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     210             : 
     211           0 :         SAFE_strcat(szPROJ4, " +lonc=");
     212           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     213             : 
     214           0 :         SAFE_strcat(szPROJ4, " +alpha=");
     215           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     216             : 
     217           0 :         if (CPLAtof(papszMethods[4]) < 0.00001)
     218             :         {
     219           0 :             SAFE_strcat(szPROJ4, " +not_rot");
     220             :         }
     221             :         else
     222             :         {
     223             : #ifdef notdef
     224             :             if (CPLAtof(papszMethods[4]) + CPLAtof(papszMethods[3]) < 0.00001)
     225             :                 /* ok */;
     226             :             else
     227             :                 /* notdef: no way to specify arbitrary angles! */;
     228             : #endif
     229             :         }
     230             : 
     231           0 :         SAFE_strcat(szPROJ4, " +k=");
     232           0 :         SAFE_strcat(szPROJ4, papszMethods[5]);
     233             : 
     234           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     235           0 :         SAFE_strcat(szPROJ4, papszMethods[6]);
     236             : 
     237           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     238           0 :         SAFE_strcat(szPROJ4, papszMethods[7]);
     239             :     }
     240             : 
     241           0 :     else if (EQUAL(papszMethods[0], "Laborde Oblique Mercator") &&
     242           0 :              CSLCount(papszMethods) > 6)
     243             :     {
     244           0 :         SAFE_strcat(szPROJ4, "+proj=labrd");
     245             : 
     246           0 :         SAFE_strcat(szPROJ4, " +lat_0=");
     247           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     248             : 
     249           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     250           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     251             : 
     252           0 :         SAFE_strcat(szPROJ4, " +azi=");
     253           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     254             : 
     255           0 :         SAFE_strcat(szPROJ4, " +k=");
     256           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     257             : 
     258           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     259           0 :         SAFE_strcat(szPROJ4, papszMethods[5]);
     260             : 
     261           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     262           0 :         SAFE_strcat(szPROJ4, papszMethods[6]);
     263             :     }
     264             : 
     265           0 :     else if (EQUAL(papszMethods[0], "New Zealand Map Grid") &&
     266           0 :              CSLCount(papszMethods) > 4)
     267             :     {
     268           0 :         SAFE_strcat(szPROJ4, "+proj=nzmg");
     269             : 
     270           0 :         SAFE_strcat(szPROJ4, " +lat_0=");
     271           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     272             : 
     273           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     274           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     275             : 
     276           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     277           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     278             : 
     279           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     280           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     281             :     }
     282             : 
     283           0 :     else if (EQUAL(papszMethods[0], "New Zealand Map Grid") &&
     284           0 :              CSLCount(papszMethods) > 4)
     285             :     {
     286           0 :         SAFE_strcat(szPROJ4, "+proj=nzmg");
     287             : 
     288           0 :         SAFE_strcat(szPROJ4, " +lat_0=");
     289           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     290             : 
     291           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     292           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     293             : 
     294           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     295           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     296             : 
     297           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     298           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     299             :     }
     300             : 
     301           0 :     else if (EQUAL(papszMethods[0], "Oblique Stereographic") &&
     302           0 :              CSLCount(papszMethods) > 5)
     303             :     {
     304             :         /* there is an option to produce +lat_ts, which we ignore */
     305             : 
     306           0 :         SAFE_strcat(szPROJ4, "+proj=stere");
     307             : 
     308           0 :         SAFE_strcat(szPROJ4, " +lat_0=45");
     309             : 
     310           0 :         SAFE_strcat(szPROJ4, " +lat_ts=");
     311           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     312             : 
     313           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     314           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     315             : 
     316           0 :         SAFE_strcat(szPROJ4, " +k=");
     317           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     318             : 
     319           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     320           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     321             : 
     322           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     323           0 :         SAFE_strcat(szPROJ4, papszMethods[5]);
     324             :     }
     325             : 
     326           0 :     else if (EQUAL(papszMethods[0], "Polar Stereographic") &&
     327           0 :              CSLCount(papszMethods) > 5)
     328             :     {
     329             :         /* there is an option to produce +lat_ts, which we ignore */
     330             : 
     331           0 :         SAFE_strcat(szPROJ4, "+proj=stere");
     332             : 
     333           0 :         SAFE_strcat(szPROJ4, " +lat_0=90");
     334             : 
     335           0 :         SAFE_strcat(szPROJ4, " +lat_ts=");
     336           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     337             : 
     338           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     339           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     340             : 
     341           0 :         SAFE_strcat(szPROJ4, " +k=");
     342           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     343             : 
     344           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     345           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     346             : 
     347           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     348           0 :         SAFE_strcat(szPROJ4, papszMethods[5]);
     349             :     }
     350             : 
     351           0 :     else if (EQUAL(papszMethods[0], "Swiss Oblique Cylindrical") &&
     352           0 :              CSLCount(papszMethods) > 4)
     353             :     {
     354             :         /* notdef: geotiff's geo_ctrans.inc says this is the same as
     355             :            ObliqueMercator_Rosenmund, which GG's geotiff support just
     356             :            maps directly to +proj=omerc, though I find that questionable. */
     357             : 
     358           0 :         SAFE_strcat(szPROJ4, "+proj=omerc");
     359             : 
     360           0 :         SAFE_strcat(szPROJ4, " +lat_0=");
     361           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     362             : 
     363           0 :         SAFE_strcat(szPROJ4, " +lonc=");
     364           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     365             : 
     366           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     367           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     368             : 
     369           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     370           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     371             :     }
     372             : 
     373           0 :     else if (EQUAL(papszMethods[0], "Transverse Mercator") &&
     374           0 :              CSLCount(papszMethods) > 5)
     375             :     {
     376             :         /* notdef: geotiff's geo_ctrans.inc says this is the same as
     377             :            ObliqueMercator_Rosenmund, which GG's geotiff support just
     378             :            maps directly to +proj=omerc, though I find that questionable. */
     379             : 
     380           0 :         SAFE_strcat(szPROJ4, "+proj=tmerc");
     381             : 
     382           0 :         SAFE_strcat(szPROJ4, " +lat_0=");
     383           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     384             : 
     385           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     386           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     387             : 
     388           0 :         SAFE_strcat(szPROJ4, " +k=");
     389           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     390             : 
     391           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     392           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     393             : 
     394           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     395           0 :         SAFE_strcat(szPROJ4, papszMethods[5]);
     396             :     }
     397             : 
     398           0 :     else if (EQUAL(papszMethods[0], "Transverse Mercator (South Oriented)") &&
     399           0 :              CSLCount(papszMethods) > 5)
     400             :     {
     401             :         /* notdef: I don't know how south oriented is different from
     402             :            normal, and I don't find any mention of it in Geotiff;s geo_ctrans.
     403             :            Translating as tmerc, but that is presumably wrong. */
     404             : 
     405           0 :         SAFE_strcat(szPROJ4, "+proj=tmerc");
     406             : 
     407           0 :         SAFE_strcat(szPROJ4, " +lat_0=");
     408           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     409             : 
     410           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     411           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     412             : 
     413           0 :         SAFE_strcat(szPROJ4, " +k=");
     414           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     415             : 
     416           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     417           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     418             : 
     419           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     420           0 :         SAFE_strcat(szPROJ4, papszMethods[5]);
     421             :     }
     422             : 
     423           0 :     else if (EQUAL(papszMethods[0], "*Equidistant Conic") &&
     424           0 :              CSLCount(papszMethods) > 6)
     425             :     {
     426           0 :         SAFE_strcat(szPROJ4, "+proj=eqdc");
     427             : 
     428           0 :         SAFE_strcat(szPROJ4, " +lat_1=");
     429           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     430             : 
     431           0 :         SAFE_strcat(szPROJ4, " +lat_2=");
     432           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     433             : 
     434           0 :         SAFE_strcat(szPROJ4, " +lat_0=");
     435           0 :         SAFE_strcat(szPROJ4, papszMethods[3]);
     436             : 
     437           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     438           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     439             : 
     440           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     441           0 :         SAFE_strcat(szPROJ4, papszMethods[5]);
     442             : 
     443           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     444           0 :         SAFE_strcat(szPROJ4, papszMethods[6]);
     445             :     }
     446             : 
     447           0 :     else if (EQUAL(papszMethods[0], "*Polyconic") && CSLCount(papszMethods) > 5)
     448             :     {
     449           0 :         SAFE_strcat(szPROJ4, "+proj=poly");
     450             : 
     451           0 :         SAFE_strcat(szPROJ4, " +lat_0=");
     452           0 :         SAFE_strcat(szPROJ4, papszMethods[1]);
     453             : 
     454           0 :         SAFE_strcat(szPROJ4, " +lon_0=");
     455           0 :         SAFE_strcat(szPROJ4, papszMethods[2]);
     456             : 
     457             : #ifdef notdef
     458             :         /*not supported by PROJ.4 */
     459             :         SAFE_strcat(szPROJ4, " +k=");
     460             :         SAFE_strcat(szPROJ4, papszMethods[3]);
     461             : #endif
     462           0 :         SAFE_strcat(szPROJ4, " +x_0=");
     463           0 :         SAFE_strcat(szPROJ4, papszMethods[4]);
     464             : 
     465           0 :         SAFE_strcat(szPROJ4, " +y_0=");
     466           0 :         SAFE_strcat(szPROJ4, papszMethods[5]);
     467             :     }
     468             : 
     469             :     else
     470             :     {
     471           0 :         SAFE_strcat(szPROJ4, "unknown");
     472             :     }
     473             : 
     474           0 :     CSLDestroy(papszMethods);
     475             : 
     476             :     /* -------------------------------------------------------------------- */
     477             :     /*      Now get the ellipsoid parameters.  For a bunch of common        */
     478             :     /*      ones we preserve the name.  For the rest we just carry over     */
     479             :     /*      the parameters.                                                 */
     480             :     /* -------------------------------------------------------------------- */
     481           0 :     if (CSLCount(psGXF->papszMapProjection) > 1)
     482             :     {
     483             :         char **papszTokens;
     484             : 
     485           0 :         if (strlen(psGXF->papszMapProjection[1]) > 80)
     486           0 :             return CPLStrdup("");
     487             : 
     488           0 :         papszTokens = CSLTokenizeStringComplex(psGXF->papszMapProjection[1],
     489             :                                                ",", TRUE, TRUE);
     490             : 
     491           0 :         if (EQUAL(papszTokens[0], "WGS 84"))
     492           0 :             SAFE_strcat(szPROJ4, " +ellps=WGS84");
     493           0 :         else if (EQUAL(papszTokens[0], "*WGS 72"))
     494           0 :             SAFE_strcat(szPROJ4, " +ellps=WGS72");
     495           0 :         else if (EQUAL(papszTokens[0], "*WGS 66"))
     496           0 :             SAFE_strcat(szPROJ4, " +ellps=WGS66");
     497           0 :         else if (EQUAL(papszTokens[0], "*WGS 60"))
     498           0 :             SAFE_strcat(szPROJ4, " +ellps=WGS60");
     499           0 :         else if (EQUAL(papszTokens[0], "Clarke 1866"))
     500           0 :             SAFE_strcat(szPROJ4, " +ellps=clrk66");
     501           0 :         else if (EQUAL(papszTokens[0], "Clarke 1880"))
     502           0 :             SAFE_strcat(szPROJ4, " +ellps=clrk80");
     503           0 :         else if (EQUAL(papszTokens[0], "GRS 1980"))
     504           0 :             SAFE_strcat(szPROJ4, " +ellps=GRS80");
     505           0 :         else if (CSLCount(papszTokens) > 2)
     506             :         {
     507           0 :             snprintf(szPROJ4 + strlen(szPROJ4),
     508           0 :                      sizeof(szPROJ4) - strlen(szPROJ4), " +a=%s +e=%s",
     509           0 :                      papszTokens[1], papszTokens[2]);
     510             :         }
     511             : 
     512           0 :         CSLDestroy(papszTokens);
     513             :     }
     514             : 
     515             :     /* -------------------------------------------------------------------- */
     516             :     /*      Extract the units specification.                                */
     517             :     /* -------------------------------------------------------------------- */
     518           0 :     if (psGXF->pszUnitName != NULL)
     519             :     {
     520           0 :         if (EQUAL(psGXF->pszUnitName, "ft"))
     521             :         {
     522           0 :             SAFE_strcat(szPROJ4, " +units=ft");
     523             :         }
     524           0 :         else if (EQUAL(psGXF->pszUnitName, "ftUS"))
     525             :         {
     526           0 :             SAFE_strcat(szPROJ4, " +units=us-ft");
     527             :         }
     528           0 :         else if (EQUAL(psGXF->pszUnitName, "km"))
     529             :         {
     530           0 :             SAFE_strcat(szPROJ4, " +units=km");
     531             :         }
     532           0 :         else if (EQUAL(psGXF->pszUnitName, "mm"))
     533             :         {
     534           0 :             SAFE_strcat(szPROJ4, " +units=mm");
     535             :         }
     536           0 :         else if (EQUAL(psGXF->pszUnitName, "in"))
     537             :         {
     538           0 :             SAFE_strcat(szPROJ4, " +units=in");
     539             :         }
     540           0 :         else if (EQUAL(psGXF->pszUnitName, "ftInd"))
     541             :         {
     542           0 :             SAFE_strcat(szPROJ4, " +units=ind-ft");
     543             :         }
     544           0 :         else if (EQUAL(psGXF->pszUnitName, "lk"))
     545             :         {
     546           0 :             SAFE_strcat(szPROJ4, " +units=link");
     547             :         }
     548             :     }
     549             : 
     550           0 :     return (CPLStrdup(szPROJ4));
     551             : }
     552             : 
     553             : /************************************************************************/
     554             : /*                        GXFGetPROJ4Position()                         */
     555             : /*                                                                      */
     556             : /*      Get the same information as GXFGetPosition(), but adjust        */
     557             : /*      to units to meters if we don't ``know'' the indicated           */
     558             : /*      units.                                                          */
     559             : /************************************************************************/
     560             : 
     561           0 : CPLErr GXFGetPROJ4Position(GXFHandle hGXF, double *pdfXOrigin,
     562             :                            double *pdfYOrigin, double *pdfXPixelSize,
     563             :                            double *pdfYPixelSize, double *pdfRotation)
     564             : 
     565             : {
     566           0 :     GXFInfo_t *psGXF = hGXF;
     567             :     char *pszProj;
     568             : 
     569             :     /* -------------------------------------------------------------------- */
     570             :     /*      Get the raw position.                                           */
     571             :     /* -------------------------------------------------------------------- */
     572           0 :     if (GXFGetPosition(hGXF, pdfXOrigin, pdfYOrigin, pdfXPixelSize,
     573             :                        pdfYPixelSize, pdfRotation) == CE_Failure)
     574           0 :         return (CE_Failure);
     575             : 
     576             :     /* -------------------------------------------------------------------- */
     577             :     /*      Do we know the units in PROJ.4?  Get the PROJ.4 string, and     */
     578             :     /*      check for a +units definition.                                  */
     579             :     /* -------------------------------------------------------------------- */
     580           0 :     pszProj = GXFGetMapProjectionAsPROJ4(hGXF);
     581           0 :     if (strstr(pszProj, "+unit") == NULL && psGXF->pszUnitName != NULL)
     582             :     {
     583           0 :         if (pdfXOrigin != NULL)
     584           0 :             *pdfXOrigin *= psGXF->dfUnitToMeter;
     585           0 :         if (pdfYOrigin != NULL)
     586           0 :             *pdfYOrigin *= psGXF->dfUnitToMeter;
     587           0 :         if (pdfXPixelSize != NULL)
     588           0 :             *pdfXPixelSize *= psGXF->dfUnitToMeter;
     589           0 :         if (pdfYPixelSize != NULL)
     590           0 :             *pdfYPixelSize *= psGXF->dfUnitToMeter;
     591             :     }
     592           0 :     CPLFree(pszProj);
     593             : 
     594           0 :     return (CE_None);
     595             : }

Generated by: LCOV version 1.14