LCOV - code coverage report
Current view: top level - frmts/wcs - gmlcoverage.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 59 77 76.6 %
Date: 2024-05-04 12:52:34 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  Generic support for GML Coverage descriptions.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2006, Frank Warmerdam <warmerdam@pobox.com>
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "cpl_port.h"
      30             : #include "gdal_priv.h"
      31             : 
      32             : #include <cstdlib>
      33             : #include <cstring>
      34             : 
      35             : #include "cpl_conv.h"
      36             : #include "cpl_error.h"
      37             : #include "cpl_minixml.h"
      38             : #include "cpl_string.h"
      39             : #include "ogr_api.h"
      40             : #include "ogr_core.h"
      41             : #include "ogr_geometry.h"
      42             : #include "ogr_spatialref.h"
      43             : #include "gmlcoverage.h"
      44             : 
      45             : /************************************************************************/
      46             : /*                        ParseGMLCoverageDesc()                        */
      47             : /************************************************************************/
      48             : 
      49          15 : CPLErr WCSParseGMLCoverage(CPLXMLNode *psXML, int *pnXSize, int *pnYSize,
      50             :                            double *padfGeoTransform, char **ppszProjection)
      51             : 
      52             : {
      53          15 :     CPLStripXMLNamespace(psXML, nullptr, TRUE);
      54             : 
      55             :     /* -------------------------------------------------------------------- */
      56             :     /*      Isolate RectifiedGrid.  Eventually we will need to support      */
      57             :     /*      other georeferencing objects.                                   */
      58             :     /* -------------------------------------------------------------------- */
      59          15 :     CPLXMLNode *psRG = CPLSearchXMLNode(psXML, "=RectifiedGrid");
      60          15 :     CPLXMLNode *psOriginPoint = nullptr;
      61          15 :     const char *pszOffset1 = nullptr;
      62          15 :     const char *pszOffset2 = nullptr;
      63             : 
      64          15 :     if (psRG != nullptr)
      65             :     {
      66          15 :         psOriginPoint = CPLGetXMLNode(psRG, "origin.Point");
      67          15 :         if (psOriginPoint == nullptr)
      68          15 :             psOriginPoint = CPLGetXMLNode(psRG, "origin");
      69             : 
      70          15 :         CPLXMLNode *psOffset1 = CPLGetXMLNode(psRG, "offsetVector");
      71          15 :         if (psOffset1 != nullptr)
      72             :         {
      73          15 :             pszOffset1 = CPLGetXMLValue(psOffset1, "", nullptr);
      74             :             pszOffset2 =
      75          15 :                 CPLGetXMLValue(psOffset1->psNext, "=offsetVector", nullptr);
      76             :         }
      77             :     }
      78             : 
      79             :     /* -------------------------------------------------------------------- */
      80             :     /*      If we are missing any of the origin or 2 offsets then give up.  */
      81             :     /* -------------------------------------------------------------------- */
      82          15 :     if (psRG == nullptr || psOriginPoint == nullptr || pszOffset1 == nullptr ||
      83             :         pszOffset2 == nullptr)
      84             :     {
      85           0 :         CPLError(CE_Failure, CPLE_AppDefined,
      86             :                  "Unable to find GML RectifiedGrid, origin or offset vectors");
      87           0 :         return CE_Failure;
      88             :     }
      89             : 
      90             :     /* -------------------------------------------------------------------- */
      91             :     /*      Search for the GridEnvelope and derive the raster size.         */
      92             :     /* -------------------------------------------------------------------- */
      93             :     char **papszLow =
      94          15 :         CSLTokenizeString(CPLGetXMLValue(psRG, "limits.GridEnvelope.low", ""));
      95             :     char **papszHigh =
      96          15 :         CSLTokenizeString(CPLGetXMLValue(psRG, "limits.GridEnvelope.high", ""));
      97             : 
      98          15 :     if (CSLCount(papszLow) < 2 || CSLCount(papszHigh) < 2)
      99             :     {
     100           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     101             :                  "Unable to find or parse GridEnvelope.low/high.");
     102           0 :         CSLDestroy(papszLow);
     103           0 :         CSLDestroy(papszHigh);
     104           0 :         return CE_Failure;
     105             :     }
     106             : 
     107          15 :     if (pnXSize != nullptr)
     108          15 :         *pnXSize = atoi(papszHigh[0]) - atoi(papszLow[0]) + 1;
     109          15 :     if (pnYSize != nullptr)
     110          15 :         *pnYSize = atoi(papszHigh[1]) - atoi(papszLow[1]) + 1;
     111             : 
     112          15 :     CSLDestroy(papszLow);
     113          15 :     CSLDestroy(papszHigh);
     114             : 
     115             :     /* -------------------------------------------------------------------- */
     116             :     /*      Extract origin location.                                        */
     117             :     /* -------------------------------------------------------------------- */
     118          15 :     OGRPoint *poOriginGeometry = nullptr;
     119           0 :     std::unique_ptr<OGRGeometry> poGeom;
     120          15 :     const char *pszSRSName = nullptr;
     121             : 
     122             :     {
     123          15 :         bool bOldWrap = false;
     124             : 
     125             :         // Old coverages (i.e. WCS) just have <pos> under <origin>, so we
     126             :         // may need to temporarily force <origin> to <Point>.
     127          15 :         if (psOriginPoint->eType == CXT_Element &&
     128          15 :             EQUAL(psOriginPoint->pszValue, "origin"))
     129             :         {
     130          15 :             strcpy(psOriginPoint->pszValue, "Point");
     131          15 :             bOldWrap = true;
     132             :         }
     133          15 :         poGeom.reset(
     134             :             OGRGeometry::FromHandle(OGR_G_CreateFromGMLTree(psOriginPoint)));
     135             : 
     136          30 :         if (poGeom != nullptr &&
     137          15 :             wkbFlatten(poGeom->getGeometryType()) == wkbPoint)
     138             :         {
     139          15 :             poOriginGeometry = poGeom->toPoint();
     140             :         }
     141             : 
     142          15 :         if (bOldWrap)
     143          15 :             strcpy(psOriginPoint->pszValue, "origin");
     144             : 
     145             :         // SRS?
     146          15 :         pszSRSName = CPLGetXMLValue(psOriginPoint, "srsName", nullptr);
     147             :     }
     148             : 
     149             :     /* -------------------------------------------------------------------- */
     150             :     /*      Extract offset(s)                                               */
     151             :     /* -------------------------------------------------------------------- */
     152          15 :     bool bSuccess = false;
     153             : 
     154             :     char **papszOffset1Tokens =
     155          15 :         CSLTokenizeStringComplex(pszOffset1, " ,", FALSE, FALSE);
     156             :     char **papszOffset2Tokens =
     157          15 :         CSLTokenizeStringComplex(pszOffset2, " ,", FALSE, FALSE);
     158             : 
     159          15 :     if (CSLCount(papszOffset1Tokens) >= 2 &&
     160          15 :         CSLCount(papszOffset2Tokens) >= 2 && poOriginGeometry != nullptr)
     161             :     {
     162          15 :         padfGeoTransform[0] = poOriginGeometry->getX();
     163          15 :         padfGeoTransform[1] = CPLAtof(papszOffset1Tokens[0]);
     164          15 :         padfGeoTransform[2] = CPLAtof(papszOffset1Tokens[1]);
     165          15 :         padfGeoTransform[3] = poOriginGeometry->getY();
     166          15 :         padfGeoTransform[4] = CPLAtof(papszOffset2Tokens[0]);
     167          15 :         padfGeoTransform[5] = CPLAtof(papszOffset2Tokens[1]);
     168             : 
     169             :         // offset from center of pixel.
     170          15 :         padfGeoTransform[0] -= padfGeoTransform[1] * 0.5;
     171          15 :         padfGeoTransform[0] -= padfGeoTransform[2] * 0.5;
     172          15 :         padfGeoTransform[3] -= padfGeoTransform[4] * 0.5;
     173          15 :         padfGeoTransform[3] -= padfGeoTransform[5] * 0.5;
     174             : 
     175          15 :         bSuccess = true;
     176             :     }
     177             : 
     178          15 :     CSLDestroy(papszOffset1Tokens);
     179          15 :     CSLDestroy(papszOffset2Tokens);
     180             : 
     181             :     /* -------------------------------------------------------------------- */
     182             :     /*      If we have gotten a geotransform, then try to interpret the     */
     183             :     /*      srsName.                                                        */
     184             :     /* -------------------------------------------------------------------- */
     185          15 :     if (bSuccess && pszSRSName != nullptr &&
     186           0 :         (*ppszProjection == nullptr || strlen(*ppszProjection) == 0))
     187             :     {
     188           0 :         if (STARTS_WITH_CI(pszSRSName, "epsg:"))
     189             :         {
     190           0 :             OGRSpatialReference oSRS;
     191           0 :             if (oSRS.SetFromUserInput(pszSRSName) == OGRERR_NONE)
     192           0 :                 oSRS.exportToWkt(ppszProjection);
     193             :         }
     194           0 :         else if (STARTS_WITH_CI(pszSRSName, "urn:ogc:def:crs:"))
     195             :         {
     196           0 :             OGRSpatialReference oSRS;
     197           0 :             if (oSRS.importFromURN(pszSRSName) == OGRERR_NONE)
     198           0 :                 oSRS.exportToWkt(ppszProjection);
     199             :         }
     200             :         else
     201           0 :             *ppszProjection = CPLStrdup(pszSRSName);
     202             :     }
     203             : 
     204          15 :     if (*ppszProjection)
     205           0 :         CPLDebug("GDALJP2Metadata", "Got projection from GML box: %s",
     206             :                  *ppszProjection);
     207             : 
     208          15 :     return CE_None;
     209             : }

Generated by: LCOV version 1.14