LCOV - code coverage report
Current view: top level - frmts/hdf5 - iso19115_srs.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 30 42 71.4 %
Date: 2024-11-21 22:18:42 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  BAG Driver
       4             :  * Purpose:  Implements code to parse ISO 19115 metadata to extract a
       5             :  *           spatial reference system.  Eventually intended to be made
       6             :  *           a method on OGRSpatialReference.
       7             :  * Author:   Frank Warmerdam <warmerdam@pobox.com>
       8             :  *
       9             :  ******************************************************************************
      10             :  * Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com>
      11             :  * Copyright (c) 2009-2012, Even Rouault <even dot rouault at spatialys.com>
      12             :  *
      13             :  * SPDX-License-Identifier: MIT
      14             :  ****************************************************************************/
      15             : 
      16             : #include "cpl_port.h"
      17             : 
      18             : #include <cstdlib>
      19             : #include <cstring>
      20             : 
      21             : #include "cpl_error.h"
      22             : #include "cpl_minixml.h"
      23             : #include "iso19115_srs.h"
      24             : #include "ogr_core.h"
      25             : #include "ogr_spatialref.h"
      26             : 
      27             : /************************************************************************/
      28             : /*                     OGR_SRS_ImportFromISO19115()                     */
      29             : /************************************************************************/
      30             : 
      31          80 : OGRErr OGR_SRS_ImportFromISO19115(OGRSpatialReference *poThis,
      32             :                                   const char *pszISOXML)
      33             : 
      34             : {
      35             :     // Parse the XML into tree form.
      36          80 :     CPLXMLNode *psRoot = CPLParseXMLString(pszISOXML);
      37             : 
      38          80 :     if (psRoot == nullptr)
      39           0 :         return OGRERR_FAILURE;
      40             : 
      41          80 :     CPLStripXMLNamespace(psRoot, nullptr, TRUE);
      42             : 
      43             :     // For now we look for projection codes recognised in the BAG
      44             :     // format (see ons_fsd.pdf: Metadata Dataset Character String
      45             :     // Constants).
      46          80 :     CPLXMLNode *psRSI = CPLSearchXMLNode(psRoot, "=referenceSystemInfo");
      47          80 :     if (psRSI == nullptr)
      48             :     {
      49           0 :         CPLError(CE_Failure, CPLE_AppDefined,
      50             :                  "Unable to find <referenceSystemInfo> in metadata.");
      51           0 :         CPLDestroyXMLNode(psRoot);
      52           0 :         return OGRERR_FAILURE;
      53             :     }
      54             : 
      55          80 :     poThis->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
      56          80 :     poThis->Clear();
      57             : 
      58             :     // First, set the datum.
      59             :     const char *pszDatum =
      60          80 :         CPLGetXMLValue(psRSI, "MD_CRS.datum.RS_Identifier.code", "");
      61             : 
      62          84 :     if (strlen(pszDatum) > 0 &&
      63           4 :         poThis->SetWellKnownGeogCS(pszDatum) != OGRERR_NONE)
      64             :     {
      65           2 :         CPLDestroyXMLNode(psRoot);
      66           2 :         return OGRERR_FAILURE;
      67             :     }
      68             : 
      69             :     // Then try to extract the projection.
      70             :     const char *pszProjection =
      71          78 :         CPLGetXMLValue(psRSI, "MD_CRS.projection.RS_Identifier.code", "");
      72             : 
      73          78 :     if (EQUAL(pszProjection, "UTM"))
      74             :     {
      75           2 :         int nZone = atoi(CPLGetXMLValue(
      76             :             psRSI, "MD_CRS.projectionParameters.MD_ProjectionParameters.zone",
      77             :             "0"));
      78             : 
      79             :         // We have encountered files (#5152) that identify the southern
      80             :         // hemisphere with a false northing of 10000000 value.  The existing
      81             :         // code checked for negative zones, but it isn't clear if any actual
      82             :         // files use that.
      83           2 :         int bNorth = nZone > 0;
      84           2 :         if (bNorth)
      85             :         {
      86             :             const char *pszFalseNorthing =
      87           2 :                 CPLGetXMLValue(psRSI,
      88             :                                "MD_CRS.projectionParameters.MD_"
      89             :                                "ProjectionParameters.falseNorthing",
      90             :                                "");
      91           2 :             if (strlen(pszFalseNorthing) > 0)
      92             :             {
      93           2 :                 if (CPLAtof(pszFalseNorthing) == 0.0)
      94             :                 {
      95           0 :                     bNorth = TRUE;
      96             :                 }
      97           2 :                 else if (CPLAtof(pszFalseNorthing) == 10000000.0)
      98             :                 {
      99           2 :                     bNorth = FALSE;
     100             :                 }
     101             :                 else
     102             :                 {
     103           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
     104             :                              "falseNorthing value not recognized: %s",
     105             :                              pszFalseNorthing);
     106             :                 }
     107             :             }
     108             :         }
     109           2 :         poThis->SetUTM(std::abs(nZone), bNorth);
     110             :     }
     111          76 :     else if (EQUAL(pszProjection, "Geodetic"))
     112             :     {
     113             :         const char *pszEllipsoid =
     114           0 :             CPLGetXMLValue(psRSI, "MD_CRS.ellipsoid.RS_Identifier.code", "");
     115             : 
     116           0 :         if (!EQUAL(pszDatum, "WGS84") || !EQUAL(pszEllipsoid, "WGS84"))
     117             :         {
     118           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     119             :                      "ISO 19115 parser does not support custom GCS.");
     120           0 :             CPLDestroyXMLNode(psRoot);
     121           0 :             return OGRERR_FAILURE;
     122             :         }
     123             :     }
     124             :     else
     125             :     {
     126          76 :         if (!EQUAL(pszProjection, ""))
     127             :         {
     128           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     129             :                      "projection = %s not recognised by ISO 19115 parser.",
     130             :                      pszProjection);
     131             :         }
     132          76 :         CPLDestroyXMLNode(psRoot);
     133          76 :         return OGRERR_FAILURE;
     134             :     }
     135             : 
     136           2 :     CPLDestroyXMLNode(psRoot);
     137             : 
     138           2 :     return OGRERR_NONE;
     139             : }

Generated by: LCOV version 1.14