LCOV - code coverage report
Current view: top level - apps - gdalsrsinfo.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 220 247 89.1 %
Date: 2024-05-03 15:49:35 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL Utilities
       4             :  * Purpose:  Command line application to list info about a given CRS.
       5             :  *           Outputs a number of formats (WKT, PROJ.4, etc.).
       6             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7             :  *           Etienne Tourigny, etourigny.dev-at-gmail-dot-com
       8             :  *
       9             :  * ****************************************************************************
      10             :  * Copyright (c) 1998, Frank Warmerdam
      11             :  * Copyright (c) 2011-2013, Even Rouault <even dot rouault at spatialys.com>
      12             :  *
      13             :  * Permission is hereby granted, free of charge, to any person obtaining a
      14             :  * copy of this software and associated documentation files (the "Software"),
      15             :  * to deal in the Software without restriction, including without limitation
      16             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17             :  * and/or sell copies of the Software, and to permit persons to whom the
      18             :  * Software is furnished to do so, subject to the following conditions:
      19             :  *
      20             :  * The above copyright notice and this permission notice shall be included
      21             :  * in all copies or substantial portions of the Software.
      22             :  *
      23             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29             :  * DEALINGS IN THE SOFTWARE.
      30             :  ****************************************************************************/
      31             : 
      32             : #include "cpl_string.h"
      33             : #include "gdal_version.h"
      34             : #include "gdal_priv.h"
      35             : #include "ogr_spatialref.h"
      36             : #include "ogr_api.h"
      37             : #include "ogrsf_frmts.h"
      38             : #include "commonutils.h"
      39             : 
      40             : #include "proj.h"
      41             : 
      42             : bool FindSRS(const char *pszInput, OGRSpatialReference &oSRS);
      43             : CPLErr PrintSRS(const OGRSpatialReference &oSRS, const char *pszOutputType,
      44             :                 bool bPretty, bool bPrintSep);
      45             : void PrintSRSOutputTypes(const OGRSpatialReference &oSRS,
      46             :                          const char *const *papszOutputTypes, bool bPretty);
      47             : 
      48             : /************************************************************************/
      49             : /*                               Usage()                                */
      50             : /************************************************************************/
      51             : 
      52           0 : static void Usage(bool bIsError, const char *pszErrorMsg = nullptr)
      53             : 
      54             : {
      55           0 :     fprintf(bIsError ? stderr : stdout,
      56             :             "Usage: gdalsrsinfo [options] <srs_def>\n"
      57             :             "\n"
      58             :             "srs_def may be the filename of a dataset supported by GDAL/OGR "
      59             :             "from which to extract SRS information\n"
      60             :             "OR any of the usual GDAL/OGR forms "
      61             :             "(complete WKT, PROJ.4, EPSG:n or a file containing the SRS)\n"
      62             :             "\n"
      63             :             "Options: \n"
      64             :             "   [--help-general]       Show help on general options and exit\n"
      65             :             "   [--help] [-h]          Show help and exit\n"
      66             :             "   [--single-line]        Print WKT on single line\n"
      67             :             "   [-V]                   Validate SRS\n"
      68             :             "   [-e]                   Search for EPSG number(s) corresponding "
      69             :             "to SRS\n"
      70             :             "   [-o <out_type>]          Output type { default, all, wkt_all,\n"
      71             : #if PROJ_VERSION_MAJOR > 6 || PROJ_VERSION_MINOR >= 2
      72             :             "                                        PROJJSON, proj4, epsg,\n"
      73             : #else
      74             :             "                                        proj4, epsg,\n"
      75             : #endif
      76             :             "                                        wkt1, wkt_simple, "
      77             :             "wkt_noct, wkt_esri,\n"
      78             :             "                                        wkt2, wkt2_2015, "
      79             :             "wkt2_2019, mapinfo, xml }\n\n");
      80             : 
      81           0 :     if (pszErrorMsg != nullptr)
      82           0 :         fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg);
      83             : 
      84           0 :     exit(bIsError ? 1 : 0);
      85             : }
      86             : 
      87             : /************************************************************************/
      88             : /*                                main()                                */
      89             : /************************************************************************/
      90             : 
      91             : #define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg)                            \
      92             :     do                                                                         \
      93             :     {                                                                          \
      94             :         if (i + nExtraArg >= argc)                                             \
      95             :             Usage(true, CPLSPrintf("%s option requires %d argument(s)",        \
      96             :                                    argv[i], nExtraArg));                       \
      97             :     } while (false)
      98             : 
      99          21 : MAIN_START(argc, argv)
     100             : 
     101             : {
     102          21 :     bool bGotSRS = false;
     103          21 :     bool bPretty = true;
     104          21 :     bool bValidate = false;
     105          21 :     bool bFindEPSG = false;
     106          41 :     std::string osIdentifiedCode = "EPSG:-1";
     107          21 :     const char *pszInput = nullptr;
     108          21 :     const char *pszOutputType = "default";
     109          41 :     OGRSpatialReference oSRS;
     110             : 
     111             :     /* Check strict compilation and runtime library version as we use C++ API */
     112          21 :     if (!GDAL_CHECK_VERSION(argv[0]))
     113           0 :         exit(1);
     114             : 
     115          21 :     EarlySetConfigOptions(argc, argv);
     116             : 
     117             :     /* -------------------------------------------------------------------- */
     118             :     /*      Register standard GDAL and OGR drivers.                         */
     119             :     /* -------------------------------------------------------------------- */
     120          21 :     GDALAllRegister();
     121             : 
     122             :     /* -------------------------------------------------------------------- */
     123             :     /*      Register standard GDAL drivers, and process generic GDAL        */
     124             :     /*      command options.                                                */
     125             :     /* -------------------------------------------------------------------- */
     126          21 :     argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
     127          21 :     if (argc < 1)
     128           0 :         exit(-argc);
     129             : 
     130             :     /* -------------------------------------------------------------------- */
     131             :     /*      Parse arguments.                                                */
     132             :     /* -------------------------------------------------------------------- */
     133          66 :     for (int i = 1; i < argc; i++)
     134             :     {
     135          46 :         CPLDebug("gdalsrsinfo", "got arg #%d : [%s]", i, argv[i]);
     136             : 
     137          46 :         if (EQUAL(argv[i], "--utility_version"))
     138             :         {
     139           1 :             printf("%s was compiled against GDAL %s and is running against "
     140             :                    "GDAL %s\n",
     141             :                    argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
     142           1 :             CSLDestroy(argv);
     143           1 :             return 0;
     144             :         }
     145          45 :         else if (EQUAL(argv[i], "-h") || EQUAL(argv[i], "--help"))
     146           0 :             Usage(false);
     147          45 :         else if (EQUAL(argv[i], "-e"))
     148           3 :             bFindEPSG = true;
     149          42 :         else if (EQUAL(argv[i], "-o"))
     150             :         {
     151          14 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     152          14 :             pszOutputType = argv[++i];
     153             :         }
     154          28 :         else if (EQUAL(argv[i], "-p"))
     155           0 :             bPretty = true;
     156          28 :         else if (EQUAL(argv[i], "--single-line"))
     157           6 :             bPretty = false;
     158          22 :         else if (EQUAL(argv[i], "-V"))
     159           2 :             bValidate = true;
     160          20 :         else if (argv[i][0] == '-')
     161             :         {
     162           0 :             Usage(true, CPLSPrintf("Unknown option name '%s'", argv[i]));
     163             :         }
     164             :         else
     165          20 :             pszInput = argv[i];
     166             :     }
     167             : 
     168          20 :     if (pszInput == nullptr)
     169             :     {
     170           0 :         CSLDestroy(argv);
     171           0 :         Usage(true, "No input specified.");
     172             :     }
     173             : 
     174             :     /* Search for SRS */
     175             :     /* coverity[tainted_data] */
     176          20 :     bGotSRS = FindSRS(pszInput, oSRS) == TRUE;
     177             : 
     178          20 :     CPLDebug("gdalsrsinfo",
     179             :              "bGotSRS: %d bValidate: %d pszOutputType: %s bPretty: %d",
     180             :              static_cast<int>(bGotSRS), static_cast<int>(bValidate),
     181             :              pszOutputType, static_cast<int>(bPretty));
     182             : 
     183             :     /* Make sure we got a SRS */
     184          20 :     if (!bGotSRS)
     185             :     {
     186           1 :         CPLError(CE_Failure, CPLE_AppDefined,
     187             :                  "ERROR - failed to load SRS definition from %s", pszInput);
     188           1 :         exit(1);
     189             :     }
     190             : 
     191             :     else
     192             :     {
     193          19 :         int nEntries = 0;
     194          19 :         int *panConfidence = nullptr;
     195          19 :         OGRSpatialReferenceH *pahSRS = nullptr;
     196             : 
     197             :         /* Find EPSG code */
     198          19 :         if (EQUAL(pszOutputType, "epsg"))
     199           0 :             bFindEPSG = true;
     200             : 
     201          19 :         if (bFindEPSG)
     202             :         {
     203             : 
     204             :             pahSRS =
     205           3 :                 OSRFindMatches(reinterpret_cast<OGRSpatialReferenceH>(
     206             :                                    const_cast<OGRSpatialReference *>(&oSRS)),
     207             :                                nullptr, &nEntries, &panConfidence);
     208             :         }
     209             : 
     210          38 :         for (int i = 0; i < (nEntries ? nEntries : 1); i++)
     211             :         {
     212          19 :             if (nEntries)
     213             :             {
     214           2 :                 oSRS = *reinterpret_cast<OGRSpatialReference *>(pahSRS[i]);
     215           2 :                 if (panConfidence[i] != 100)
     216             :                 {
     217           2 :                     printf("Confidence in this match: %d %%\n",
     218           2 :                            panConfidence[i]);
     219             :                 }
     220             : 
     221           2 :                 const char *pszAuthorityName = oSRS.GetAuthorityName(nullptr);
     222           2 :                 const char *pszAuthorityCode = oSRS.GetAuthorityCode(nullptr);
     223           2 :                 if (pszAuthorityName && pszAuthorityCode)
     224             :                 {
     225           2 :                     osIdentifiedCode = pszAuthorityName;
     226           2 :                     osIdentifiedCode += ':';
     227           2 :                     osIdentifiedCode += pszAuthorityCode;
     228             :                 }
     229             :             }
     230             : 
     231             :             /* Validate - not well tested!*/
     232          19 :             if (bValidate)
     233             :             {
     234           2 :                 OGRErr eErr = oSRS.Validate();
     235           2 :                 if (eErr != OGRERR_NONE)
     236             :                 {
     237           1 :                     printf("\nValidate Fails");
     238           1 :                     if (eErr == OGRERR_CORRUPT_DATA)
     239           1 :                         printf(" - SRS is not well formed");
     240           0 :                     else if (eErr == OGRERR_UNSUPPORTED_SRS)
     241           0 :                         printf(" - contains non-standard PROJECTION[] values");
     242           1 :                     printf("\n");
     243             :                 }
     244             :                 else
     245           1 :                     printf("\nValidate Succeeds\n");
     246             :             }
     247             : 
     248             :             /* Output */
     249          19 :             if (EQUAL("default", pszOutputType))
     250             :             {
     251           5 :                 const char *papszOutputTypes[] = {"proj4", "wkt2", nullptr};
     252           5 :                 if (bFindEPSG)
     253           3 :                     printf("\n%s\n", osIdentifiedCode.c_str());
     254           5 :                 PrintSRSOutputTypes(oSRS, papszOutputTypes, bPretty);
     255             :             }
     256          14 :             else if (EQUAL("all", pszOutputType))
     257             :             {
     258           1 :                 if (bFindEPSG)
     259           0 :                     printf("\n%s\n", osIdentifiedCode.c_str());
     260           1 :                 const char *papszOutputTypes[] = {
     261             :                     "proj4",
     262             :                     "wkt1",
     263             :                     "wkt2_2015",
     264             :                     "wkt2_2019",
     265             :                     "wkt_simple",
     266             :                     "wkt_noct",
     267             :                     "wkt_esri",
     268             :                     "mapinfo",
     269             :                     "xml",
     270             : #if PROJ_VERSION_MAJOR > 6 || PROJ_VERSION_MINOR >= 2
     271             :                     "PROJJSON",
     272             : #endif
     273             :                     nullptr
     274             :                 };
     275           1 :                 PrintSRSOutputTypes(oSRS, papszOutputTypes, bPretty);
     276             :             }
     277          13 :             else if (EQUAL("wkt_all", pszOutputType))
     278             :             {
     279           0 :                 const char *papszOutputTypes[] = {
     280             :                     "wkt1",     "wkt2_2015", "wkt2_2019", "wkt_simple",
     281             :                     "wkt_noct", "wkt_esri",  nullptr};
     282           0 :                 PrintSRSOutputTypes(oSRS, papszOutputTypes, bPretty);
     283             :             }
     284             :             else
     285             :             {
     286          13 :                 if (bPretty)
     287           7 :                     printf("\n");
     288          13 :                 if (EQUAL(pszOutputType, "epsg"))
     289           0 :                     printf("\n%s\n", osIdentifiedCode.c_str());
     290             :                 else
     291          13 :                     PrintSRS(oSRS, pszOutputType, bPretty, FALSE);
     292          13 :                 if (bPretty)
     293           7 :                     printf("\n");
     294             :             }
     295             :         }
     296             : 
     297          19 :         OSRFreeSRSArray(pahSRS);
     298          19 :         CPLFree(panConfidence);
     299             :     }
     300             : 
     301             :     /* cleanup anything left */
     302          19 :     GDALDestroyDriverManager();
     303          19 :     OGRCleanupAll();
     304          19 :     CSLDestroy(argv);
     305             : 
     306          19 :     return 0;
     307             : }
     308             : 
     309           0 : MAIN_END
     310             : 
     311             : /************************************************************************/
     312             : /*                      FindSRS()                                       */
     313             : /*                                                                      */
     314             : /*      Search for SRS from pszInput, update oSRS.                      */
     315             : /************************************************************************/
     316          20 : bool FindSRS(const char *pszInput, OGRSpatialReference &oSRS)
     317             : 
     318             : {
     319          20 :     bool bGotSRS = false;
     320          20 :     GDALDataset *poGDALDS = nullptr;
     321          20 :     OGRLayer *poLayer = nullptr;
     322          20 :     bool bIsFile = false;
     323             : 
     324             :     /* temporarily suppress error messages we may get from xOpen() */
     325          20 :     bool bDebug = CPLTestBool(CPLGetConfigOption("CPL_DEBUG", "OFF"));
     326          20 :     if (!bDebug)
     327          20 :         CPLPushErrorHandler(CPLQuietErrorHandler);
     328             : 
     329             :     /* Test if argument is a file */
     330          20 :     VSILFILE *fp = VSIFOpenL(pszInput, "r");
     331          20 :     if (fp)
     332             :     {
     333          13 :         bIsFile = true;
     334          13 :         VSIFCloseL(fp);
     335          13 :         CPLDebug("gdalsrsinfo", "argument is a file");
     336             :     }
     337             : 
     338             :     /* try to open with GDAL */
     339          20 :     if (!STARTS_WITH(pszInput, "http://spatialreference.org/"))
     340             :     {
     341          20 :         CPLDebug("gdalsrsinfo", "trying to open with GDAL");
     342             :         poGDALDS = static_cast<GDALDataset *>(
     343          20 :             GDALOpenEx(pszInput, 0, nullptr, nullptr, nullptr));
     344             :     }
     345          20 :     if (poGDALDS != nullptr)
     346             :     {
     347          11 :         const OGRSpatialReference *poSRS = poGDALDS->GetSpatialRef();
     348          11 :         if (poSRS)
     349             :         {
     350          10 :             oSRS = *poSRS;
     351          10 :             CPLDebug("gdalsrsinfo", "got SRS from GDAL");
     352          10 :             bGotSRS = true;
     353             :         }
     354           1 :         else if (poGDALDS->GetLayerCount() > 0)
     355             :         {
     356           1 :             poLayer = poGDALDS->GetLayer(0);
     357           1 :             if (poLayer != nullptr)
     358             :             {
     359           1 :                 poSRS = poLayer->GetSpatialRef();
     360           1 :                 if (poSRS != nullptr)
     361             :                 {
     362           1 :                     CPLDebug("gdalsrsinfo", "got SRS from OGR");
     363           1 :                     bGotSRS = true;
     364           1 :                     oSRS = *poSRS;
     365             :                 }
     366             :             }
     367             :         }
     368          11 :         GDALClose(poGDALDS);
     369          11 :         if (!bGotSRS)
     370           0 :             CPLDebug("gdalsrsinfo", "did not open with GDAL");
     371             :     }
     372             : 
     373             :     /* Try ESRI file */
     374          20 :     if (!bGotSRS && bIsFile && (strstr(pszInput, ".prj") != nullptr))
     375             :     {
     376           2 :         CPLDebug("gdalsrsinfo", "trying to get SRS from ESRI .prj file [%s]",
     377             :                  pszInput);
     378             : 
     379             :         char **pszTemp;
     380           2 :         if (strstr(pszInput, "ESRI::") != nullptr)
     381           0 :             pszTemp = CSLLoad(pszInput + 6);
     382             :         else
     383           2 :             pszTemp = CSLLoad(pszInput);
     384             : 
     385           2 :         OGRErr eErr = OGRERR_UNSUPPORTED_SRS;
     386           2 :         if (pszTemp)
     387             :         {
     388           2 :             eErr = oSRS.importFromESRI(pszTemp);
     389           2 :             CSLDestroy(pszTemp);
     390             :         }
     391             : 
     392           2 :         if (eErr != OGRERR_NONE)
     393             :         {
     394           2 :             CPLDebug("gdalsrsinfo", "did not get SRS from ESRI .prj file");
     395             :         }
     396             :         else
     397             :         {
     398           0 :             CPLDebug("gdalsrsinfo", "got SRS from ESRI .prj file");
     399           0 :             bGotSRS = true;
     400             :         }
     401             :     }
     402             : 
     403             :     /* restore error messages */
     404          20 :     if (!bDebug)
     405          20 :         CPLPopErrorHandler();
     406             : 
     407             :     /* Last resort, try OSRSetFromUserInput() */
     408          20 :     if (!bGotSRS)
     409             :     {
     410           9 :         CPLDebug("gdalsrsinfo", "trying to get SRS from user input [%s]",
     411             :                  pszInput);
     412             : 
     413           9 :         if (CPLGetConfigOption("CPL_ALLOW_VSISTDIN", nullptr) == nullptr)
     414           9 :             CPLSetConfigOption("CPL_ALLOW_VSISTDIN", "YES");
     415             : 
     416           9 :         const OGRErr eErr = oSRS.SetFromUserInput(pszInput);
     417             : 
     418           9 :         if (eErr != OGRERR_NONE)
     419             :         {
     420           1 :             CPLDebug("gdalsrsinfo", "did not get SRS from user input");
     421             :         }
     422             :         else
     423             :         {
     424           8 :             CPLDebug("gdalsrsinfo", "got SRS from user input");
     425           8 :             bGotSRS = true;
     426             :         }
     427             :     }
     428             : 
     429          20 :     return bGotSRS;
     430             : }
     431             : 
     432             : /************************************************************************/
     433             : /*                      PrintSRS()                                      */
     434             : /*                                                                      */
     435             : /*      Print spatial reference in specified format.                    */
     436             : /************************************************************************/
     437          33 : CPLErr PrintSRS(const OGRSpatialReference &oSRS, const char *pszOutputType,
     438             :                 bool bPretty, bool bPrintSep)
     439             : 
     440             : {
     441          33 :     if (!pszOutputType || EQUAL(pszOutputType, ""))
     442           0 :         return CE_None;
     443             : 
     444          33 :     CPLDebug("gdalsrsinfo", "PrintSRS( oSRS, %s, %d, %d )\n", pszOutputType,
     445             :              static_cast<int>(bPretty), static_cast<int>(bPrintSep));
     446             : 
     447          33 :     char *pszOutput = nullptr;
     448             : 
     449          33 :     if (EQUAL("proj4", pszOutputType))
     450             :     {
     451          12 :         if (bPrintSep)
     452           6 :             printf("PROJ.4 : ");
     453          12 :         oSRS.exportToProj4(&pszOutput);
     454          12 :         printf("%s\n", pszOutput ? pszOutput : "(error)");
     455             :     }
     456             : 
     457          21 :     else if (EQUAL("PROJJSON", pszOutputType))
     458             :     {
     459           1 :         if (bPrintSep)
     460           1 :             printf("PROJJSON :\n");
     461           1 :         const char *const apszOptions[] = {
     462           1 :             bPretty ? "MULTILINE=YES" : "MULTILINE=NO", nullptr};
     463           1 :         oSRS.exportToPROJJSON(&pszOutput, apszOptions);
     464           1 :         printf("%s\n", pszOutput ? pszOutput : "(error)");
     465             :     }
     466             : 
     467          20 :     else if (EQUAL("wkt1", pszOutputType))
     468             :     {
     469           4 :         if (bPrintSep)
     470           1 :             printf("OGC WKT1 :\n");
     471           4 :         const char *const apszOptions[] = {
     472           4 :             "FORMAT=WKT1_GDAL", bPretty ? "MULTILINE=YES" : nullptr, nullptr};
     473           4 :         oSRS.exportToWkt(&pszOutput, apszOptions);
     474           4 :         printf("%s\n", pszOutput ? pszOutput : "(error)");
     475             :     }
     476             : 
     477          16 :     else if (EQUAL("wkt_simple", pszOutputType))
     478             :     {
     479           2 :         if (bPrintSep)
     480           1 :             printf("OGC WKT1 (simple) :\n");
     481           2 :         const char *const apszOptions[] = {
     482           2 :             "FORMAT=WKT1_SIMPLE", bPretty ? "MULTILINE=YES" : nullptr, nullptr};
     483           2 :         oSRS.exportToWkt(&pszOutput, apszOptions);
     484           2 :         printf("%s\n", pszOutput ? pszOutput : "(error)");
     485             :     }
     486             : 
     487          14 :     else if (EQUAL("wkt_noct", pszOutputType))
     488             :     {
     489           2 :         if (bPrintSep)
     490           1 :             printf("OGC WKT1 (no CT) :\n");
     491           2 :         const char *const apszOptions[] = {
     492           2 :             "FORMAT=SFSQL", bPretty ? "MULTILINE=YES" : nullptr, nullptr};
     493           2 :         oSRS.exportToWkt(&pszOutput, apszOptions);
     494           2 :         printf("%s\n", pszOutput ? pszOutput : "(error)");
     495             :     }
     496             : 
     497          12 :     else if (EQUAL("wkt_esri", pszOutputType))
     498             :     {
     499           2 :         if (bPrintSep)
     500           1 :             printf("ESRI WKT :\n");
     501           2 :         const char *const apszOptions[] = {
     502           2 :             "FORMAT=WKT1_ESRI", bPretty ? "MULTILINE=YES" : nullptr, nullptr};
     503           2 :         oSRS.exportToWkt(&pszOutput, apszOptions);
     504           2 :         printf("%s\n", pszOutput ? pszOutput : "(error)");
     505             :     }
     506             : 
     507          10 :     else if (EQUAL("wkt2_2015", pszOutputType))
     508             :     {
     509           1 :         if (bPrintSep)
     510           1 :             printf("OGC WKT2:2015 :\n");
     511           1 :         const char *const apszOptions[] = {
     512           1 :             "FORMAT=WKT2_2015", bPretty ? "MULTILINE=YES" : nullptr, nullptr};
     513           1 :         oSRS.exportToWkt(&pszOutput, apszOptions);
     514           1 :         printf("%s\n", pszOutput ? pszOutput : "(error)");
     515             :     }
     516             : 
     517           9 :     else if (EQUAL("wkt", pszOutputType) || EQUAL("wkt2", pszOutputType) ||
     518           4 :              EQUAL("wkt2_2018", pszOutputType) ||
     519           4 :              EQUAL("wkt2_2019", pszOutputType))
     520             :     {
     521           6 :         if (bPrintSep)
     522           6 :             printf("OGC WKT2:2019 :\n");
     523           6 :         const char *const apszOptions[] = {
     524           6 :             "FORMAT=WKT2_2018", bPretty ? "MULTILINE=YES" : nullptr, nullptr};
     525           6 :         oSRS.exportToWkt(&pszOutput, apszOptions);
     526           6 :         printf("%s\n", pszOutput ? pszOutput : "(error)");
     527             :     }
     528             : 
     529           3 :     else if (EQUAL("mapinfo", pszOutputType))
     530             :     {
     531           2 :         if (bPrintSep)
     532           1 :             printf("MAPINFO : ");
     533           2 :         oSRS.exportToMICoordSys(&pszOutput);
     534           2 :         printf("\'%s\'\n", pszOutput ? pszOutput : "(error)");
     535             :     }
     536             : 
     537           1 :     else if (EQUAL("xml", pszOutputType))
     538             :     {
     539           1 :         if (bPrintSep)
     540           1 :             printf("XML :\n");
     541           1 :         oSRS.exportToXML(&pszOutput, nullptr);
     542           1 :         printf("%s\n", pszOutput ? pszOutput : "(error)");
     543             :     }
     544             : 
     545             :     else
     546             :     {
     547           0 :         CPLError(CE_Failure, CPLE_AppDefined, "ERROR - %s output not supported",
     548             :                  pszOutputType);
     549           0 :         return CE_Failure;
     550             :     }
     551             : 
     552          33 :     CPLFree(pszOutput);
     553             : 
     554          33 :     return CE_None;
     555             : }
     556             : 
     557             : /************************************************************************/
     558             : /*                      PrintSRSOutputTypes()                           */
     559             : /*                                                                      */
     560             : /*      Print spatial reference in specified formats.                   */
     561             : /************************************************************************/
     562           6 : void PrintSRSOutputTypes(const OGRSpatialReference &oSRS,
     563             :                          const char *const *papszOutputTypes, bool bPretty)
     564             : 
     565             : {
     566           6 :     int nOutputTypes = CSLCount(papszOutputTypes);
     567           6 :     printf("\n");
     568          26 :     for (int i = 0; i < nOutputTypes; i++)
     569             :     {
     570          20 :         PrintSRS(oSRS, papszOutputTypes[i], bPretty, true);
     571          20 :         printf("\n");
     572             :     }
     573           6 : }

Generated by: LCOV version 1.14