LCOV - code coverage report
Current view: top level - frmts/gxf - gxf_ogcwkt.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 81 126 64.3 %
Date: 2024-05-02 21:22:03 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  GXF Reader
       5             :  * Purpose:  Handle GXF to OGC WKT projection transformation.
       6             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 1999, Frank Warmerdam
      10             :  * Copyright (c) 2009-2012, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * Permission is hereby granted, free of charge, to any person obtaining a
      13             :  * copy of this software and associated documentation files (the "Software"),
      14             :  * to deal in the Software without restriction, including without limitation
      15             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16             :  * and/or sell copies of the Software, and to permit persons to whom the
      17             :  * Software is furnished to do so, subject to the following conditions:
      18             :  *
      19             :  * The above copyright notice and this permission notice shall be included
      20             :  * in all copies or substantial portions of the Software.
      21             :  *
      22             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28             :  * DEALINGS IN THE SOFTWARE.
      29             :  ****************************************************************************/
      30             : 
      31             : #include "gxfopen.h"
      32             : #include "ogr_srs_api.h"
      33             : 
      34             : /* -------------------------------------------------------------------- */
      35             : /* the following #defines come from ogr_spatialref.h in the GDAL/OGR  */
      36             : /* distribution (see http://gdal.velocet.ca/projects/opengis) and */
      37             : /* should be kept in sync with that file.         */
      38             : /* -------------------------------------------------------------------- */
      39             : 
      40             : #define SRS_PT_ALBERS_CONIC_EQUAL_AREA "Albers_Conic_Equal_Area"
      41             : #define SRS_PT_AZIMUTHAL_EQUIDISTANT "Azimuthal_Equidistant"
      42             : #define SRS_PT_CASSINI_SOLDNER "Cassini_Soldner"
      43             : #define SRS_PT_CYLINDRICAL_EQUAL_AREA "Cylindrical_Equal_Area"
      44             : #define SRS_PT_ECKERT_IV "Eckert_IV"
      45             : #define SRS_PT_ECKERT_VI "Eckert_VI"
      46             : #define SRS_PT_EQUIDISTANT_CONIC "Equidistant_Conic"
      47             : #define SRS_PT_EQUIRECTANGULAR "Equirectangular"
      48             : #define SRS_PT_GALL_STEREOGRAPHIC "Gall_Stereographic"
      49             : #define SRS_PT_GNOMONIC "Gnomonic"
      50             : #define SRS_PT_HOTINE_OBLIQUE_MERCATOR "Hotine_Oblique_Mercator"
      51             : #define SRS_PT_LABORDE_OBLIQUE_MERCATOR "Laborde_Oblique_Mercator"
      52             : #define SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP "Lambert_Conformal_Conic_1SP"
      53             : #define SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP "Lambert_Conformal_Conic_2SP"
      54             : #define SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM                             \
      55             :     "Lambert_Conformal_Conic_2SP_Belgium"
      56             : #define SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA "Lambert_Azimuthal_Equal_Area"
      57             : #define SRS_PT_MERCATOR_1SP "Mercator_1SP"
      58             : #define SRS_PT_MERCATOR_2SP "Mercator_2SP"
      59             : #define SRS_PT_MILLER_CYLINDRICAL "Miller_Cylindrical"
      60             : #define SRS_PT_MOLLWEIDE "Mollweide"
      61             : #define SRS_PT_NEW_ZEALAND_MAP_GRID "New_Zealand_Map_Grid"
      62             : #define SRS_PT_OBLIQUE_STEREOGRAPHIC "Oblique_Stereographic"
      63             : #define SRS_PT_ORTHOGRAPHIC "Orthographic"
      64             : #define SRS_PT_POLAR_STEREOGRAPHIC "Polar_Stereographic"
      65             : #define SRS_PT_POLYCONIC "Polyconic"
      66             : #define SRS_PT_ROBINSON "Robinson"
      67             : #define SRS_PT_SINUSOIDAL "Sinusoidal"
      68             : #define SRS_PT_STEREOGRAPHIC "Stereographic"
      69             : #define SRS_PT_SWISS_OBLIQUE_CYLINDRICAL "Swiss_Oblique_Cylindrical"
      70             : #define SRS_PT_TRANSVERSE_MERCATOR "Transverse_Mercator"
      71             : #define SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED                              \
      72             :     "Transverse_Mercator_South_Orientated"
      73             : #define SRS_PT_TUNISIA_MINING_GRID "Tunisia_Mining_Grid"
      74             : #define SRS_PT_VANDERGRINTEN "VanDerGrinten"
      75             : 
      76             : #define SRS_PP_CENTRAL_MERIDIAN "central_meridian"
      77             : #define SRS_PP_SCALE_FACTOR "scale_factor"
      78             : #define SRS_PP_STANDARD_PARALLEL_1 "standard_parallel_1"
      79             : #define SRS_PP_STANDARD_PARALLEL_2 "standard_parallel_2"
      80             : #define SRS_PP_LONGITUDE_OF_CENTER "longitude_of_center"
      81             : #define SRS_PP_LATITUDE_OF_CENTER "latitude_of_center"
      82             : #define SRS_PP_LONGITUDE_OF_ORIGIN "longitude_of_origin"
      83             : #define SRS_PP_LATITUDE_OF_ORIGIN "latitude_of_origin"
      84             : #define SRS_PP_FALSE_EASTING "false_easting"
      85             : #define SRS_PP_FALSE_NORTHING "false_northing"
      86             : #define SRS_PP_AZIMUTH "azimuth"
      87             : #define SRS_PP_LONGITUDE_OF_POINT_1 "longitude_of_point_1"
      88             : #define SRS_PP_LATITUDE_OF_POINT_1 "latitude_of_point_1"
      89             : #define SRS_PP_LONGITUDE_OF_POINT_2 "longitude_of_point_2"
      90             : #define SRS_PP_LATITUDE_OF_POINT_2 "latitude_of_point_2"
      91             : #define SRS_PP_LONGITUDE_OF_POINT_3 "longitude_of_point_3"
      92             : #define SRS_PP_LATITUDE_OF_POINT_3 "latitude_of_point_3"
      93             : #define SRS_PP_RECTIFIED_GRID_ANGLE "rectified_grid_angle"
      94             : 
      95             : /* -------------------------------------------------------------------- */
      96             : /*      This table was copied from gt_wkt_srs.cpp in the libgeotiff     */
      97             : /*      distribution.  Please keep changes in sync.                     */
      98             : /* -------------------------------------------------------------------- */
      99             : static const char *const papszDatumEquiv[] = {
     100             :     "Militar_Geographische_Institut",
     101             :     "Militar_Geographische_Institute",
     102             :     "World_Geodetic_System_1984",
     103             :     "WGS_1984",
     104             :     "WGS_72_Transit_Broadcast_Ephemeris",
     105             :     "WGS_1972_Transit_Broadcast_Ephemeris",
     106             :     "World_Geodetic_System_1972",
     107             :     "WGS_1972",
     108             :     "European_Terrestrial_Reference_System_89",
     109             :     "European_Reference_System_1989",
     110             :     NULL};
     111             : 
     112             : /************************************************************************/
     113             : /*                          WKTMassageDatum()                           */
     114             : /*                                                                      */
     115             : /*      Massage an EPSG datum name into WMT format.  Also transform     */
     116             : /*      specific exception cases into WKT versions.                     */
     117             : /*                                                                      */
     118             : /*      This function was copied from the gt_wkt_srs.cpp file in the    */
     119             : /*      libgeotiff distribution.  Please keep changes in sync.          */
     120             : /************************************************************************/
     121             : 
     122           2 : static void WKTMassageDatum(char **ppszDatum)
     123             : 
     124             : {
     125             :     int i, j;
     126             :     char *pszDatum;
     127             : 
     128           2 :     pszDatum = *ppszDatum;
     129           2 :     if (pszDatum[0] == '\0')
     130           0 :         return;
     131             : 
     132             :     /* -------------------------------------------------------------------- */
     133             :     /*      Translate non-alphanumeric values to underscores.               */
     134             :     /* -------------------------------------------------------------------- */
     135          12 :     for (i = 0; pszDatum[i] != '\0'; i++)
     136             :     {
     137          10 :         if (pszDatum[i] != '+' && !(pszDatum[i] >= 'A' && pszDatum[i] <= 'Z') &&
     138           4 :             !(pszDatum[i] >= 'a' && pszDatum[i] <= 'z') &&
     139           4 :             !(pszDatum[i] >= '0' && pszDatum[i] <= '9'))
     140             :         {
     141           0 :             pszDatum[i] = '_';
     142             :         }
     143             :     }
     144             : 
     145             :     /* -------------------------------------------------------------------- */
     146             :     /*      Remove repeated and trailing underscores.                       */
     147             :     /* -------------------------------------------------------------------- */
     148          10 :     for (i = 1, j = 0; pszDatum[i] != '\0'; i++)
     149             :     {
     150           8 :         if (pszDatum[j] == '_' && pszDatum[i] == '_')
     151           0 :             continue;
     152             : 
     153           8 :         pszDatum[++j] = pszDatum[i];
     154             :     }
     155           2 :     if (pszDatum[j] == '_')
     156           0 :         pszDatum[j] = '\0';
     157             :     else
     158           2 :         pszDatum[j + 1] = '\0';
     159             : 
     160             :     /* -------------------------------------------------------------------- */
     161             :     /*      Search for datum equivalences.  Specific massaged names get     */
     162             :     /*      mapped to OpenGIS specified names.                              */
     163             :     /* -------------------------------------------------------------------- */
     164          12 :     for (i = 0; papszDatumEquiv[i] != NULL; i += 2)
     165             :     {
     166          10 :         if (EQUAL(*ppszDatum, papszDatumEquiv[i]))
     167             :         {
     168           0 :             CPLFree(*ppszDatum);
     169           0 :             *ppszDatum = CPLStrdup(papszDatumEquiv[i + 1]);
     170           0 :             return;
     171             :         }
     172             :     }
     173             : }
     174             : 
     175             : /************************************************************************/
     176             : /*                           OGCWKTSetProj()                            */
     177             : /************************************************************************/
     178             : 
     179           2 : static void OGCWKTSetProj(char *pszProjection, size_t nProjectionSize,
     180             :                           char **papszMethods, const char *pszTransformName,
     181             :                           const char *pszParm1, const char *pszParm2,
     182             :                           const char *pszParm3, const char *pszParm4,
     183             :                           const char *pszParm5, const char *pszParm6,
     184             :                           const char *pszParm7)
     185             : 
     186             : {
     187           2 :     int iParam, nCount = CSLCount(papszMethods);
     188           2 :     const char *apszParamNames[8] = {NULL};
     189             : 
     190           2 :     apszParamNames[0] = pszParm1;
     191           2 :     apszParamNames[1] = pszParm2;
     192           2 :     apszParamNames[2] = pszParm3;
     193           2 :     apszParamNames[3] = pszParm4;
     194           2 :     apszParamNames[4] = pszParm5;
     195           2 :     apszParamNames[5] = pszParm6;
     196           2 :     apszParamNames[6] = pszParm7;
     197           2 :     apszParamNames[7] = NULL;
     198             : 
     199           2 :     snprintf(pszProjection, nProjectionSize, "PROJECTION[\"%s\"]",
     200             :              pszTransformName);
     201             : 
     202          12 :     for (iParam = 0; iParam < nCount - 1 && apszParamNames[iParam] != NULL;
     203          10 :          iParam++)
     204             :     {
     205          10 :         snprintf(pszProjection + strlen(pszProjection),
     206          10 :                  nProjectionSize - strlen(pszProjection),
     207             :                  ",PARAMETER[\"%s\",%s]", apszParamNames[iParam],
     208          10 :                  papszMethods[iParam + 1]);
     209             :     }
     210           2 : }
     211             : 
     212             : /************************************************************************/
     213             : /*                    GXFGetMapProjectionAsOGCWKT()                     */
     214             : /************************************************************************/
     215             : 
     216             : /**
     217             :  * Return the GXF Projection in OpenGIS Well Known Text format.
     218             :  *
     219             :  * The returned string becomes owned by the caller, and should be freed
     220             :  * with CPLFree() or VSIFree().  The return value will be "" if
     221             :  * no projection information is passed.
     222             :  *
     223             :  * The mapping of GXF projections to OGC WKT format is not complete.  Please
     224             :  * see the gxf_ogcwkt.c code to better understand limitations of this
     225             :  * translation.  More information about OGC WKT format can be found in
     226             :  * the OpenGIS Simple Features specification for OLEDB/COM found on the
     227             :  * OpenGIS web site at <a href="http://www.opengis.org/">www.opengis.org</a>.
     228             :  * The translation uses some code cribbed from the OGR library, about which
     229             :  * more can be learned from <a href="http://gdal.velocet.ca/projects/opengis/">
     230             :  * http://gdal.velocet.ca/projects/opengis/</a>.
     231             :  *
     232             :  * For example, the following GXF definitions:
     233             :  * <pre>
     234             :  * #UNIT_LENGTH
     235             :  * m,1
     236             :  * #MAP_PROJECTION
     237             :  * "NAD83 / UTM zone 19N"
     238             :  * "GRS 1980",6378137,0.081819191,0
     239             :  * "Transverse Mercator",0,-69,0.9996,500000,0
     240             :  * </pre>
     241             :  *
     242             :  * Would translate to (without the nice formatting):
     243             :  * <pre>
     244             :    PROJCS["NAD83 / UTM zone 19N",
     245             :           GEOGCS["GRS 1980",
     246             :                  DATUM["GRS_1980",
     247             :                      SPHEROID["GRS 1980",6378137,298.257222413684]],
     248             :                  PRIMEM["unnamed",0],
     249             :                  UNIT["degree",0.0174532925199433]],
     250             :           PROJECTION["Transverse_Mercator"],
     251             :           PARAMETER["latitude_of_origin",0],
     252             :           PARAMETER["central_meridian",-69],
     253             :           PARAMETER["scale_factor",0.9996],
     254             :           PARAMETER["false_easting",500000],
     255             :           PARAMETER["false_northing",0],
     256             :           UNIT["m",1]]
     257             :  * </pre>
     258             :  *
     259             :  * @param hGXF handle to GXF file, as returned by GXFOpen().
     260             :  *
     261             :  * @return string containing OGC WKT projection.
     262             :  */
     263             : 
     264           4 : char *GXFGetMapProjectionAsOGCWKT(GXFHandle hGXF)
     265             : 
     266             : {
     267           4 :     GXFInfo_t *psGXF = (GXFInfo_t *)hGXF;
     268           4 :     char **papszMethods = NULL;
     269             :     char szWKT[1024 + 32];
     270             :     char szGCS[512];
     271             :     char szProjection[512];
     272             : 
     273             :     /* -------------------------------------------------------------------- */
     274             :     /*      If there was nothing in the file return "unknown".              */
     275             :     /* -------------------------------------------------------------------- */
     276           4 :     if (CSLCount(psGXF->papszMapProjection) < 2)
     277           2 :         return (CPLStrdup(""));
     278             : 
     279           2 :     strcpy(szWKT, "");
     280           2 :     strcpy(szGCS, "");
     281           2 :     strcpy(szProjection, "");
     282             : 
     283             :     /* -------------------------------------------------------------------- */
     284             :     /*      Parse the third line, looking for known projection methods.     */
     285             :     /* -------------------------------------------------------------------- */
     286           2 :     if (psGXF->papszMapProjection[2] != NULL)
     287             :     {
     288             :         /* We allow more than 80 characters if the projection parameters */
     289             :         /* are on 2 lines as allowed by GXF 3 */
     290           2 :         if (strlen(psGXF->papszMapProjection[2]) > 120)
     291           0 :             return (CPLStrdup(""));
     292           2 :         papszMethods = CSLTokenizeStringComplex(psGXF->papszMapProjection[2],
     293             :                                                 ",", TRUE, TRUE);
     294             :     }
     295             : 
     296             :     /* -------------------------------------------------------------------- */
     297             :     /*      Create the PROJCS.                                              */
     298             :     /* -------------------------------------------------------------------- */
     299           2 :     if (papszMethods == NULL || papszMethods[0] == NULL ||
     300           2 :         EQUAL(papszMethods[0], "Geographic"))
     301             :     {
     302             :         /* do nothing */
     303             :     }
     304             : 
     305           2 :     else if (EQUAL(papszMethods[0], "Lambert Conic Conformal (1SP)"))
     306             :     {
     307           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     308             :                       SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP,
     309             :                       SRS_PP_LATITUDE_OF_ORIGIN, SRS_PP_CENTRAL_MERIDIAN,
     310             :                       SRS_PP_SCALE_FACTOR, SRS_PP_FALSE_EASTING,
     311             :                       SRS_PP_FALSE_NORTHING, NULL, NULL);
     312             :     }
     313             : 
     314           2 :     else if (EQUAL(papszMethods[0], "Lambert Conic Conformal (2SP)"))
     315             :     {
     316           2 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     317             :                       SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP,
     318             :                       SRS_PP_STANDARD_PARALLEL_1, SRS_PP_STANDARD_PARALLEL_2,
     319             :                       SRS_PP_LATITUDE_OF_ORIGIN, SRS_PP_CENTRAL_MERIDIAN,
     320             :                       SRS_PP_FALSE_EASTING, SRS_PP_FALSE_NORTHING, NULL);
     321             :     }
     322             : 
     323           0 :     else if (EQUAL(papszMethods[0], "Lambert Conformal (2SP Belgium)"))
     324             :     {
     325           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     326             :                       SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM,
     327             :                       SRS_PP_STANDARD_PARALLEL_1, SRS_PP_STANDARD_PARALLEL_2,
     328             :                       SRS_PP_LATITUDE_OF_ORIGIN, SRS_PP_CENTRAL_MERIDIAN,
     329             :                       SRS_PP_FALSE_EASTING, SRS_PP_FALSE_NORTHING, NULL);
     330             :     }
     331             : 
     332           0 :     else if (EQUAL(papszMethods[0], "Mercator (1SP)"))
     333             :     {
     334           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     335             :                       SRS_PT_MERCATOR_1SP, SRS_PP_LATITUDE_OF_ORIGIN,
     336             :                       SRS_PP_CENTRAL_MERIDIAN, SRS_PP_SCALE_FACTOR,
     337             :                       SRS_PP_FALSE_EASTING, SRS_PP_FALSE_NORTHING, NULL, NULL);
     338             :     }
     339             : 
     340           0 :     else if (EQUAL(papszMethods[0], "Mercator (2SP)"))
     341             :     {
     342           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     343             :                       SRS_PT_MERCATOR_2SP,
     344             :                       SRS_PP_LATITUDE_OF_ORIGIN, /* should it be StdParalle1?*/
     345             :                       SRS_PP_CENTRAL_MERIDIAN, SRS_PP_FALSE_EASTING,
     346             :                       SRS_PP_FALSE_NORTHING, NULL, NULL, NULL);
     347             :     }
     348             : 
     349           0 :     else if (EQUAL(papszMethods[0], "Laborde Oblique Mercator"))
     350             :     {
     351           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     352             :                       SRS_PT_LABORDE_OBLIQUE_MERCATOR,
     353             :                       SRS_PP_LATITUDE_OF_CENTER, SRS_PP_LONGITUDE_OF_CENTER,
     354             :                       SRS_PP_AZIMUTH, SRS_PP_SCALE_FACTOR, SRS_PP_FALSE_EASTING,
     355             :                       SRS_PP_FALSE_NORTHING, NULL);
     356             :     }
     357             : 
     358           0 :     else if (EQUAL(papszMethods[0], "Hotine Oblique Mercator"))
     359             :     {
     360           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     361             :                       SRS_PT_HOTINE_OBLIQUE_MERCATOR, SRS_PP_LATITUDE_OF_CENTER,
     362             :                       SRS_PP_LONGITUDE_OF_CENTER, SRS_PP_AZIMUTH,
     363             :                       SRS_PP_RECTIFIED_GRID_ANGLE,
     364             :                       SRS_PP_SCALE_FACTOR, /* not in normal formulation */
     365             :                       SRS_PP_FALSE_EASTING, SRS_PP_FALSE_NORTHING);
     366             :     }
     367             : 
     368           0 :     else if (EQUAL(papszMethods[0], "New Zealand Map Grid"))
     369             : 
     370             :     {
     371           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     372             :                       SRS_PT_NEW_ZEALAND_MAP_GRID, SRS_PP_LATITUDE_OF_ORIGIN,
     373             :                       SRS_PP_CENTRAL_MERIDIAN, SRS_PP_FALSE_EASTING,
     374             :                       SRS_PP_FALSE_NORTHING, NULL, NULL, NULL);
     375             :     }
     376             : 
     377           0 :     else if (EQUAL(papszMethods[0], "Oblique Stereographic"))
     378             :     {
     379           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     380             :                       SRS_PT_OBLIQUE_STEREOGRAPHIC, SRS_PP_LATITUDE_OF_ORIGIN,
     381             :                       SRS_PP_CENTRAL_MERIDIAN, SRS_PP_SCALE_FACTOR,
     382             :                       SRS_PP_FALSE_EASTING, SRS_PP_FALSE_NORTHING, NULL, NULL);
     383             :     }
     384             : 
     385           0 :     else if (EQUAL(papszMethods[0], "Polar Stereographic"))
     386             :     {
     387           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     388             :                       SRS_PT_POLAR_STEREOGRAPHIC, SRS_PP_LATITUDE_OF_ORIGIN,
     389             :                       SRS_PP_CENTRAL_MERIDIAN, SRS_PP_SCALE_FACTOR,
     390             :                       SRS_PP_FALSE_EASTING, SRS_PP_FALSE_NORTHING, NULL, NULL);
     391             :     }
     392             : 
     393           0 :     else if (EQUAL(papszMethods[0], "Swiss Oblique Cylindrical"))
     394             :     {
     395           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     396             :                       SRS_PT_SWISS_OBLIQUE_CYLINDRICAL,
     397             :                       SRS_PP_LATITUDE_OF_CENTER, SRS_PP_LONGITUDE_OF_CENTER,
     398             :                       SRS_PP_FALSE_EASTING, SRS_PP_FALSE_NORTHING, NULL, NULL,
     399             :                       NULL);
     400             :     }
     401             : 
     402           0 :     else if (EQUAL(papszMethods[0], "Transverse Mercator"))
     403             :     {
     404           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     405             :                       SRS_PT_TRANSVERSE_MERCATOR, SRS_PP_LATITUDE_OF_ORIGIN,
     406             :                       SRS_PP_CENTRAL_MERIDIAN, SRS_PP_SCALE_FACTOR,
     407             :                       SRS_PP_FALSE_EASTING, SRS_PP_FALSE_NORTHING, NULL, NULL);
     408             :     }
     409             : 
     410           0 :     else if (EQUAL(papszMethods[0], "Transverse Mercator (South Oriented)") ||
     411           0 :              EQUAL(papszMethods[0], "Transverse Mercator (South Orientated)"))
     412             :     {
     413           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     414             :                       SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED,
     415             :                       SRS_PP_LATITUDE_OF_ORIGIN, SRS_PP_CENTRAL_MERIDIAN,
     416             :                       SRS_PP_SCALE_FACTOR, SRS_PP_FALSE_EASTING,
     417             :                       SRS_PP_FALSE_NORTHING, NULL, NULL);
     418             :     }
     419             : 
     420           0 :     else if (EQUAL(papszMethods[0], "*Albers Conic"))
     421             :     {
     422           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     423             :                       SRS_PT_ALBERS_CONIC_EQUAL_AREA,
     424             :                       SRS_PP_STANDARD_PARALLEL_1, SRS_PP_STANDARD_PARALLEL_2,
     425             :                       SRS_PP_LATITUDE_OF_CENTER, SRS_PP_LONGITUDE_OF_CENTER,
     426             :                       SRS_PP_FALSE_EASTING, SRS_PP_FALSE_NORTHING, NULL);
     427             :     }
     428             : 
     429           0 :     else if (EQUAL(papszMethods[0], "*Equidistant Conic"))
     430             :     {
     431           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     432             :                       SRS_PT_EQUIDISTANT_CONIC, SRS_PP_STANDARD_PARALLEL_1,
     433             :                       SRS_PP_STANDARD_PARALLEL_2, SRS_PP_LATITUDE_OF_CENTER,
     434             :                       SRS_PP_LONGITUDE_OF_CENTER, SRS_PP_FALSE_EASTING,
     435             :                       SRS_PP_FALSE_NORTHING, NULL);
     436             :     }
     437             : 
     438           0 :     else if (EQUAL(papszMethods[0], "*Polyconic"))
     439             :     {
     440           0 :         OGCWKTSetProj(szProjection, sizeof(szProjection), papszMethods,
     441             :                       SRS_PT_POLYCONIC, SRS_PP_LATITUDE_OF_ORIGIN,
     442             :                       SRS_PP_CENTRAL_MERIDIAN,
     443             :                       SRS_PP_SCALE_FACTOR, /* not normally expected */
     444             :                       SRS_PP_FALSE_EASTING, SRS_PP_FALSE_NORTHING, NULL, NULL);
     445             :     }
     446             : 
     447           2 :     CSLDestroy(papszMethods);
     448             : 
     449             :     /* -------------------------------------------------------------------- */
     450             :     /*      Extract the linear Units specification.                         */
     451             :     /* -------------------------------------------------------------------- */
     452           2 :     if (psGXF->pszUnitName != NULL && strlen(szProjection) > 0)
     453             :     {
     454           2 :         if (strlen(psGXF->pszUnitName) > 80)
     455           0 :             return CPLStrdup("");
     456             : 
     457           2 :         CPLsnprintf(szProjection + strlen(szProjection),
     458           2 :                     sizeof(szProjection) - strlen(szProjection),
     459             :                     ",UNIT[\"%s\",%.15g]", psGXF->pszUnitName,
     460             :                     psGXF->dfUnitToMeter);
     461             :     }
     462             : 
     463             :     /* -------------------------------------------------------------------- */
     464             :     /*      Build GEOGCS.  There are still "issues" with the generation     */
     465             :     /*      of the GEOGCS/Datum and Spheroid names.  Of these, only the     */
     466             :     /*      datum name is really significant.                               */
     467             :     /* -------------------------------------------------------------------- */
     468           2 :     if (CSLCount(psGXF->papszMapProjection) > 1)
     469             :     {
     470             :         char **papszTokens;
     471             : 
     472           2 :         if (strlen(psGXF->papszMapProjection[1]) > 80)
     473           0 :             return CPLStrdup("");
     474             : 
     475           2 :         papszTokens = CSLTokenizeStringComplex(psGXF->papszMapProjection[1],
     476             :                                                ",", TRUE, TRUE);
     477             : 
     478           2 :         if (CSLCount(papszTokens) > 2)
     479             :         {
     480           2 :             double dfMajor = CPLAtof(papszTokens[1]);
     481           2 :             double dfEccentricity = CPLAtof(papszTokens[2]);
     482             :             double dfInvFlattening, dfMinor;
     483             :             char *pszOGCDatum;
     484             : 
     485             :             /* translate eccentricity to inv flattening. */
     486           2 :             if (dfEccentricity == 0.0)
     487           0 :                 dfInvFlattening = 0.0;
     488             :             else
     489             :             {
     490           2 :                 dfMinor =
     491           2 :                     dfMajor * pow(1.0 - dfEccentricity * dfEccentricity, 0.5);
     492           2 :                 dfInvFlattening = OSRCalcInvFlattening(dfMajor, dfMinor);
     493             :             }
     494             : 
     495           2 :             pszOGCDatum = CPLStrdup(papszTokens[0]);
     496           2 :             WKTMassageDatum(&pszOGCDatum);
     497             : 
     498           2 :             CPLsnprintf(
     499             :                 szGCS, sizeof(szGCS),
     500             :                 "GEOGCS[\"%s\","
     501             :                 "DATUM[\"%s\","
     502             :                 "SPHEROID[\"%s\",%s,%.15g]],",
     503             :                 papszTokens[0], pszOGCDatum,
     504             :                 papszTokens[0], /* this is datum, but should be ellipse*/
     505           2 :                 papszTokens[1], dfInvFlattening);
     506           2 :             CPLFree(pszOGCDatum);
     507             :         }
     508             : 
     509           2 :         if (CSLCount(papszTokens) > 3)
     510           2 :             CPLsnprintf(szGCS + strlen(szGCS), sizeof(szGCS) - strlen(szGCS),
     511           2 :                         "PRIMEM[\"unnamed\",%s],", papszTokens[3]);
     512             : 
     513           2 :         CPLsnprintf(szGCS + strlen(szGCS), sizeof(szGCS) - strlen(szGCS), "%s",
     514             :                     "UNIT[\"degree\",0.0174532925199433]]");
     515             : 
     516           2 :         CSLDestroy(papszTokens);
     517             :     }
     518             : 
     519           2 :     CPLAssert(strlen(szProjection) < sizeof(szProjection));
     520           2 :     CPLAssert(strlen(szGCS) < sizeof(szGCS));
     521             : 
     522             :     /* -------------------------------------------------------------------- */
     523             :     /*      Put this all together into a full projection.                   */
     524             :     /* -------------------------------------------------------------------- */
     525           2 :     if (strlen(szProjection) > 0)
     526             :     {
     527           2 :         if (strlen(psGXF->papszMapProjection[0]) > 80)
     528           0 :             return CPLStrdup("");
     529             : 
     530           2 :         if (psGXF->papszMapProjection[0][0] == '"')
     531           2 :             snprintf(szWKT, sizeof(szWKT), "PROJCS[%s,%s,%s]",
     532           2 :                      psGXF->papszMapProjection[0], szGCS, szProjection);
     533             :         else
     534           0 :             snprintf(szWKT, sizeof(szWKT), "PROJCS[\"%s\",%s,%s]",
     535           0 :                      psGXF->papszMapProjection[0], szGCS, szProjection);
     536             :     }
     537             :     else
     538             :     {
     539           0 :         strcpy(szWKT, szGCS);
     540             :     }
     541             : 
     542           2 :     return (CPLStrdup(szWKT));
     543             : }

Generated by: LCOV version 1.14