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-05-03 15:49:35 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             :  * 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_port.h"
      33             : 
      34             : #include <cstdlib>
      35             : #include <cstring>
      36             : 
      37             : #include "cpl_error.h"
      38             : #include "cpl_minixml.h"
      39             : #include "iso19115_srs.h"
      40             : #include "ogr_core.h"
      41             : #include "ogr_spatialref.h"
      42             : 
      43             : /************************************************************************/
      44             : /*                     OGR_SRS_ImportFromISO19115()                     */
      45             : /************************************************************************/
      46             : 
      47          80 : OGRErr OGR_SRS_ImportFromISO19115(OGRSpatialReference *poThis,
      48             :                                   const char *pszISOXML)
      49             : 
      50             : {
      51             :     // Parse the XML into tree form.
      52          80 :     CPLXMLNode *psRoot = CPLParseXMLString(pszISOXML);
      53             : 
      54          80 :     if (psRoot == nullptr)
      55           0 :         return OGRERR_FAILURE;
      56             : 
      57          80 :     CPLStripXMLNamespace(psRoot, nullptr, TRUE);
      58             : 
      59             :     // For now we look for projection codes recognised in the BAG
      60             :     // format (see ons_fsd.pdf: Metadata Dataset Character String
      61             :     // Constants).
      62          80 :     CPLXMLNode *psRSI = CPLSearchXMLNode(psRoot, "=referenceSystemInfo");
      63          80 :     if (psRSI == nullptr)
      64             :     {
      65           0 :         CPLError(CE_Failure, CPLE_AppDefined,
      66             :                  "Unable to find <referenceSystemInfo> in metadata.");
      67           0 :         CPLDestroyXMLNode(psRoot);
      68           0 :         return OGRERR_FAILURE;
      69             :     }
      70             : 
      71          80 :     poThis->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
      72          80 :     poThis->Clear();
      73             : 
      74             :     // First, set the datum.
      75             :     const char *pszDatum =
      76          80 :         CPLGetXMLValue(psRSI, "MD_CRS.datum.RS_Identifier.code", "");
      77             : 
      78          84 :     if (strlen(pszDatum) > 0 &&
      79           4 :         poThis->SetWellKnownGeogCS(pszDatum) != OGRERR_NONE)
      80             :     {
      81           2 :         CPLDestroyXMLNode(psRoot);
      82           2 :         return OGRERR_FAILURE;
      83             :     }
      84             : 
      85             :     // Then try to extract the projection.
      86             :     const char *pszProjection =
      87          78 :         CPLGetXMLValue(psRSI, "MD_CRS.projection.RS_Identifier.code", "");
      88             : 
      89          78 :     if (EQUAL(pszProjection, "UTM"))
      90             :     {
      91           2 :         int nZone = atoi(CPLGetXMLValue(
      92             :             psRSI, "MD_CRS.projectionParameters.MD_ProjectionParameters.zone",
      93             :             "0"));
      94             : 
      95             :         // We have encountered files (#5152) that identify the southern
      96             :         // hemisphere with a false northing of 10000000 value.  The existing
      97             :         // code checked for negative zones, but it isn't clear if any actual
      98             :         // files use that.
      99           2 :         int bNorth = nZone > 0;
     100           2 :         if (bNorth)
     101             :         {
     102             :             const char *pszFalseNorthing =
     103           2 :                 CPLGetXMLValue(psRSI,
     104             :                                "MD_CRS.projectionParameters.MD_"
     105             :                                "ProjectionParameters.falseNorthing",
     106             :                                "");
     107           2 :             if (strlen(pszFalseNorthing) > 0)
     108             :             {
     109           2 :                 if (CPLAtof(pszFalseNorthing) == 0.0)
     110             :                 {
     111           0 :                     bNorth = TRUE;
     112             :                 }
     113           2 :                 else if (CPLAtof(pszFalseNorthing) == 10000000.0)
     114             :                 {
     115           2 :                     bNorth = FALSE;
     116             :                 }
     117             :                 else
     118             :                 {
     119           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
     120             :                              "falseNorthing value not recognized: %s",
     121             :                              pszFalseNorthing);
     122             :                 }
     123             :             }
     124             :         }
     125           2 :         poThis->SetUTM(std::abs(nZone), bNorth);
     126             :     }
     127          76 :     else if (EQUAL(pszProjection, "Geodetic"))
     128             :     {
     129             :         const char *pszEllipsoid =
     130           0 :             CPLGetXMLValue(psRSI, "MD_CRS.ellipsoid.RS_Identifier.code", "");
     131             : 
     132           0 :         if (!EQUAL(pszDatum, "WGS84") || !EQUAL(pszEllipsoid, "WGS84"))
     133             :         {
     134           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     135             :                      "ISO 19115 parser does not support custom GCS.");
     136           0 :             CPLDestroyXMLNode(psRoot);
     137           0 :             return OGRERR_FAILURE;
     138             :         }
     139             :     }
     140             :     else
     141             :     {
     142          76 :         if (!EQUAL(pszProjection, ""))
     143             :         {
     144           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     145             :                      "projection = %s not recognised by ISO 19115 parser.",
     146             :                      pszProjection);
     147             :         }
     148          76 :         CPLDestroyXMLNode(psRoot);
     149          76 :         return OGRERR_FAILURE;
     150             :     }
     151             : 
     152           2 :     CPLDestroyXMLNode(psRoot);
     153             : 
     154           2 :     return OGRERR_NONE;
     155             : }

Generated by: LCOV version 1.14