LCOV - code coverage report
Current view: top level - ogr - ogr_spatialref.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 26 37 70.3 %
Date: 2024-11-21 22:18:42 Functions: 12 17 70.6 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  OpenGIS Simple Features Reference Implementation
       5             :  * Purpose:  Classes for manipulating spatial reference systems in a
       6             :  *           platform non-specific manner.
       7             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8             :  *
       9             :  ******************************************************************************
      10             :  * Copyright (c) 1999,  Les Technologies SoftMap Inc.
      11             :  * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
      12             :  *
      13             :  * SPDX-License-Identifier: MIT
      14             :  ****************************************************************************/
      15             : 
      16             : #ifndef OGR_SPATIALREF_H_INCLUDED
      17             : #define OGR_SPATIALREF_H_INCLUDED
      18             : 
      19             : #include "cpl_string.h"
      20             : #include "ogr_srs_api.h"
      21             : 
      22             : #include <cstddef>
      23             : #include <map>
      24             : #include <memory>
      25             : #include <vector>
      26             : 
      27             : /**
      28             :  * \file ogr_spatialref.h
      29             :  *
      30             :  * Coordinate systems services.
      31             :  */
      32             : 
      33             : /************************************************************************/
      34             : /*                             OGR_SRSNode                              */
      35             : /************************************************************************/
      36             : 
      37             : /**
      38             :  * Objects of this class are used to represent value nodes in the parsed
      39             :  * representation of the WKT SRS format.  For instance UNIT["METER",1]
      40             :  * would be rendered into three OGR_SRSNodes.  The root node would have a
      41             :  * value of UNIT, and two children, the first with a value of METER, and the
      42             :  * second with a value of 1.
      43             :  *
      44             :  * Normally application code just interacts with the OGRSpatialReference
      45             :  * object, which uses the OGR_SRSNode to implement its data structure;
      46             :  * however, this class is user accessible for detailed access to components
      47             :  * of an SRS definition.
      48             :  */
      49             : 
      50             : class CPL_DLL OGR_SRSNode
      51             : {
      52             :   public:
      53             :     /** Listener that is notified of modification to nodes. */
      54      194100 :     struct Listener
      55             :     {
      56             :         virtual ~Listener();
      57             :         /** Method triggered when a node is modified. */
      58             :         virtual void notifyChange(OGR_SRSNode *) = 0;
      59             :     };
      60             : 
      61             :     explicit OGR_SRSNode(const char * = nullptr);
      62             :     ~OGR_SRSNode();
      63             : 
      64             :     /** Register a (single) listener. */
      65             :     void RegisterListener(const std::shared_ptr<Listener> &listener);
      66             : 
      67             :     /** Return whether this is a leaf node.
      68             :      * @return TRUE or FALSE
      69             :      */
      70             :     int IsLeafNode() const
      71             :     {
      72             :         return nChildren == 0;
      73             :     }
      74             : 
      75      376783 :     int GetChildCount() const
      76             :     {
      77      376783 :         return nChildren;
      78             :     }
      79             : 
      80             :     OGR_SRSNode *GetChild(int);
      81             :     const OGR_SRSNode *GetChild(int) const;
      82             : 
      83             :     OGR_SRSNode *GetNode(const char *);
      84             :     const OGR_SRSNode *GetNode(const char *) const;
      85             : 
      86             :     void InsertChild(OGR_SRSNode *, int);
      87             :     void AddChild(OGR_SRSNode *);
      88             :     int FindChild(const char *) const;
      89             :     void DestroyChild(int);
      90             :     void ClearChildren();
      91             :     void StripNodes(const char *);
      92             : 
      93      523055 :     const char *GetValue() const
      94             :     {
      95      523055 :         return pszValue;
      96             :     }
      97             : 
      98             :     void SetValue(const char *);
      99             : 
     100             :     void MakeValueSafe();
     101             : 
     102             :     OGR_SRSNode *Clone() const;
     103             : 
     104             :     OGRErr importFromWkt(char **)
     105             :         /*! @cond Doxygen_Suppress */
     106             :         CPL_WARN_DEPRECATED("Use importFromWkt(const char**)")
     107             :         /*! @endcond */
     108             :         ;
     109             :     OGRErr importFromWkt(const char **);
     110             :     OGRErr exportToWkt(char **) const;
     111             :     OGRErr exportToPrettyWkt(char **, int = 1) const;
     112             : 
     113             :   private:
     114             :     char *pszValue;
     115             : 
     116             :     OGR_SRSNode **papoChildNodes;
     117             :     OGR_SRSNode *poParent;
     118             : 
     119             :     int nChildren;
     120             : 
     121             :     int NeedsQuoting() const;
     122             :     OGRErr importFromWkt(const char **, int nRecLevel, int *pnNodes);
     123             : 
     124             :     std::weak_ptr<Listener> m_listener{};
     125             :     void notifyChange();
     126             : 
     127             :     CPL_DISALLOW_COPY_ASSIGN(OGR_SRSNode)
     128             : };
     129             : 
     130             : /************************************************************************/
     131             : /*                         OGRSpatialReference                          */
     132             : /************************************************************************/
     133             : 
     134             : /**
     135             :  * This class represents an OpenGIS Spatial Reference System, and contains
     136             :  * methods for converting between this object organization and well known
     137             :  * text (WKT) format.  This object is reference counted as one instance of
     138             :  * the object is normally shared between many OGRGeometry objects.
     139             :  *
     140             :  * Normally application code can fetch needed parameter values for this
     141             :  * SRS using GetAttrValue(), but in special cases the underlying parse tree
     142             :  * (or OGR_SRSNode objects) can be accessed more directly.
     143             :  *
     144             :  * See <a href="https://gdal.org/tutorials/osr_api_tut.html">the tutorial
     145             :  * </a> for more information on how to use this class.
     146             :  *
     147             :  * Consult also the <a href="https://gdal.org/tutorials/wktproblems.html">
     148             :  * OGC WKT Coordinate System Issues</a> page for implementation details of
     149             :  * WKT in OGR.
     150             :  */
     151             : 
     152             : class CPL_DLL OGRSpatialReference
     153             : {
     154             :     struct Private;
     155             :     std::unique_ptr<Private> d;
     156             : 
     157             :     void GetNormInfo() const;
     158             : 
     159             :     // No longer used with PROJ >= 8.1.0
     160             :     OGRErr importFromURNPart(const char *pszAuthority, const char *pszCode,
     161             :                              const char *pszURN);
     162             : 
     163             :     static CPLString lookupInDict(const char *pszDictFile, const char *pszCode);
     164             : 
     165             :     OGRErr GetWKT2ProjectionMethod(const char **ppszMethodName,
     166             :                                    const char **ppszMethodAuthName = nullptr,
     167             :                                    const char **ppszMethodCode = nullptr) const;
     168             : 
     169             :   public:
     170             :     explicit OGRSpatialReference(const char * = nullptr);
     171             :     OGRSpatialReference(const OGRSpatialReference &);
     172             :     OGRSpatialReference(OGRSpatialReference &&);
     173             : 
     174             :     virtual ~OGRSpatialReference();
     175             : 
     176             :     static void DestroySpatialReference(OGRSpatialReference *poSRS);
     177             : 
     178             :     OGRSpatialReference &operator=(const OGRSpatialReference &);
     179             :     OGRSpatialReference &operator=(OGRSpatialReference &&);
     180             : 
     181             :     OGRSpatialReference &AssignAndSetThreadSafe(const OGRSpatialReference &);
     182             : 
     183             :     int Reference();
     184             :     int Dereference();
     185             :     int GetReferenceCount() const;
     186             :     void Release();
     187             : 
     188             :     const char *GetName() const;
     189             : 
     190             :     OGRSpatialReference *Clone() const;
     191             :     OGRSpatialReference *CloneGeogCS() const;
     192             : 
     193             :     void dumpReadable();
     194             :     OGRErr exportToWkt(char **) const;
     195             :     OGRErr exportToWkt(char **ppszWKT, const char *const *papszOptions) const;
     196             :     std::string exportToWkt(const char *const *papszOptions = nullptr) const;
     197             :     OGRErr exportToPrettyWkt(char **, int = FALSE) const;
     198             :     // cppcheck-suppress functionStatic
     199             :     OGRErr exportToPROJJSON(char **, const char *const *papszOptions) const;
     200             :     OGRErr exportToProj4(char **) const;
     201             :     OGRErr exportToPCI(char **, char **, double **) const;
     202             :     OGRErr exportToUSGS(long *, long *, double **, long *) const;
     203             :     OGRErr exportToXML(char **, const char * = nullptr) const;
     204             :     OGRErr exportToPanorama(long *, long *, long *, long *, double *) const;
     205             :     OGRErr exportVertCSToPanorama(int *) const;
     206             :     OGRErr exportToERM(char *pszProj, char *pszDatum, char *pszUnits);
     207             :     OGRErr exportToMICoordSys(char **) const;
     208             :     OGRErr exportToCF1(char **ppszGridMappingName, char ***ppapszKeyValues,
     209             :                        char **ppszUnits, CSLConstList papszOptions) const;
     210             : 
     211             :     OGRErr importFromWkt(char **)
     212             :         /*! @cond Doxygen_Suppress */
     213             :         CPL_WARN_DEPRECATED(
     214             :             "Use importFromWkt(const char**) or importFromWkt(const char*)")
     215             :         /*! @endcond */
     216             :         ;
     217             : 
     218             :     OGRErr importFromWkt(const char **);
     219             :     /*! @cond Doxygen_Suppress */
     220             :     OGRErr importFromWkt(const char *pszInput, CSLConstList papszOptions);
     221             :     OGRErr importFromWkt(const char **ppszInput, CSLConstList papszOptions);
     222             :     /*! @endcond */
     223             :     OGRErr importFromWkt(const char *);
     224             :     OGRErr importFromProj4(const char *);
     225             :     OGRErr importFromEPSG(int);
     226             :     OGRErr importFromEPSGA(int);
     227             :     OGRErr importFromESRI(char **);
     228             :     OGRErr importFromPCI(const char *, const char * = nullptr,
     229             :                          const double * = nullptr);
     230             : 
     231             : #define USGS_ANGLE_DECIMALDEGREES 0 /**< Angle is in decimal degrees. */
     232             : #define USGS_ANGLE_PACKEDDMS                                                   \
     233             :     TRUE                     /**< Angle is in packed degree minute second. */
     234             : #define USGS_ANGLE_RADIANS 2 /**< Angle is in radians. */
     235             :     OGRErr importFromUSGS(long iProjSys, long iZone, double *padfPrjParams,
     236             :                           long iDatum,
     237             :                           int nUSGSAngleFormat = USGS_ANGLE_PACKEDDMS);
     238             :     OGRErr importFromPanorama(long, long, long, double *, bool bNorth = true);
     239             :     OGRErr importVertCSFromPanorama(int);
     240             :     OGRErr importFromOzi(const char *const *papszLines);
     241             :     OGRErr importFromWMSAUTO(const char *pszAutoDef);
     242             :     OGRErr importFromXML(const char *);
     243             :     OGRErr importFromDict(const char *pszDict, const char *pszCode);
     244             :     OGRErr importFromURN(const char *);
     245             :     OGRErr importFromCRSURL(const char *);
     246             :     OGRErr importFromERM(const char *pszProj, const char *pszDatum,
     247             :                          const char *pszUnits);
     248             :     OGRErr importFromUrl(const char *);
     249             :     OGRErr importFromMICoordSys(const char *);
     250             :     OGRErr importFromCF1(CSLConstList papszKeyValues, const char *pszUnits);
     251             : 
     252             :     OGRErr morphToESRI();
     253             :     OGRErr morphFromESRI();
     254             : 
     255             :     OGRSpatialReference *
     256             :     convertToOtherProjection(const char *pszTargetProjection,
     257             :                              const char *const *papszOptions = nullptr) const;
     258             : 
     259             :     OGRErr Validate() const;
     260             :     OGRErr StripVertical();
     261             : 
     262             :     bool StripTOWGS84IfKnownDatumAndAllowed();
     263             :     bool StripTOWGS84IfKnownDatum();
     264             : 
     265             :     int EPSGTreatsAsLatLong() const;
     266             :     int EPSGTreatsAsNorthingEasting() const;
     267             :     int GetAxesCount() const;
     268             :     const char *GetAxis(const char *pszTargetKey, int iAxis,
     269             :                         OGRAxisOrientation *peOrientation,
     270             :                         double *pdfConvFactor = nullptr) const;
     271             :     OGRErr SetAxes(const char *pszTargetKey, const char *pszXAxisName,
     272             :                    OGRAxisOrientation eXAxisOrientation,
     273             :                    const char *pszYAxisName,
     274             :                    OGRAxisOrientation eYAxisOrientation);
     275             : 
     276             :     OSRAxisMappingStrategy GetAxisMappingStrategy() const;
     277             :     void SetAxisMappingStrategy(OSRAxisMappingStrategy);
     278             :     const std::vector<int> &GetDataAxisToSRSAxisMapping() const;
     279             :     OGRErr SetDataAxisToSRSAxisMapping(const std::vector<int> &mapping);
     280             : 
     281             :     // Machinery for accessing parse nodes
     282             : 
     283             :     //! Return root node
     284             :     OGR_SRSNode *GetRoot();
     285             :     //! Return root node
     286             :     const OGR_SRSNode *GetRoot() const;
     287             :     void SetRoot(OGR_SRSNode *);
     288             : 
     289             :     OGR_SRSNode *GetAttrNode(const char *);
     290             :     const OGR_SRSNode *GetAttrNode(const char *) const;
     291             :     const char *GetAttrValue(const char *, int = 0) const;
     292             : 
     293             :     OGRErr SetNode(const char *, const char *);
     294             :     // cppcheck-suppress functionStatic
     295             :     OGRErr SetNode(const char *, double);
     296             : 
     297             :     OGRErr
     298             :     SetLinearUnitsAndUpdateParameters(const char *pszName, double dfInMeters,
     299             :                                       const char *pszUnitAuthority = nullptr,
     300             :                                       const char *pszUnitCode = nullptr);
     301             :     OGRErr SetLinearUnits(const char *pszName, double dfInMeters);
     302             :     OGRErr SetTargetLinearUnits(const char *pszTargetKey, const char *pszName,
     303             :                                 double dfInMeters,
     304             :                                 const char *pszUnitAuthority = nullptr,
     305             :                                 const char *pszUnitCode = nullptr);
     306             : 
     307             :     double GetLinearUnits(char **) const
     308             :         /*! @cond Doxygen_Suppress */
     309             :         CPL_WARN_DEPRECATED("Use GetLinearUnits(const char**) instead")
     310             :         /*! @endcond */
     311             :         ;
     312             :     double GetLinearUnits(const char ** = nullptr) const;
     313             : 
     314             :     /*! @cond Doxygen_Suppress */
     315        4520 :     double GetLinearUnits(std::nullptr_t) const
     316             :     {
     317        4520 :         return GetLinearUnits(static_cast<const char **>(nullptr));
     318             :     }
     319             : 
     320             :     /*! @endcond */
     321             : 
     322             :     double GetTargetLinearUnits(const char *pszTargetKey,
     323             :                                 char **ppszRetName) const
     324             :         /*! @cond Doxygen_Suppress */
     325             :         CPL_WARN_DEPRECATED(
     326             :             "Use GetTargetLinearUnits(const char*, const char**)")
     327             :         /*! @endcond */
     328             :         ;
     329             :     double GetTargetLinearUnits(const char *pszTargetKey,
     330             :                                 const char **ppszRetName = nullptr) const;
     331             : 
     332             :     /*! @cond Doxygen_Suppress */
     333             :     double GetTargetLinearUnits(const char *pszTargetKey, std::nullptr_t) const
     334             :     {
     335             :         return GetTargetLinearUnits(pszTargetKey,
     336             :                                     static_cast<const char **>(nullptr));
     337             :     }
     338             : 
     339             :     /*! @endcond */
     340             : 
     341             :     OGRErr SetAngularUnits(const char *pszName, double dfInRadians);
     342             :     double GetAngularUnits(char **) const
     343             :         /*! @cond Doxygen_Suppress */
     344             :         CPL_WARN_DEPRECATED("Use GetAngularUnits(const char**) instead")
     345             :         /*! @endcond */
     346             :         ;
     347             :     double GetAngularUnits(const char ** = nullptr) const;
     348             : 
     349             :     /*! @cond Doxygen_Suppress */
     350        1413 :     double GetAngularUnits(std::nullptr_t) const
     351             :     {
     352        1413 :         return GetAngularUnits(static_cast<const char **>(nullptr));
     353             :     }
     354             : 
     355             :     /*! @endcond */
     356             : 
     357             :     double GetPrimeMeridian(char **) const
     358             :         /*! @cond Doxygen_Suppress */
     359             :         CPL_WARN_DEPRECATED("Use GetPrimeMeridian(const char**) instead")
     360             :         /*! @endcond */
     361             :         ;
     362             :     double GetPrimeMeridian(const char ** = nullptr) const;
     363             : 
     364             :     /*! @cond Doxygen_Suppress */
     365        1128 :     double GetPrimeMeridian(std::nullptr_t) const
     366             :     {
     367        1128 :         return GetPrimeMeridian(static_cast<const char **>(nullptr));
     368             :     }
     369             : 
     370             :     /*! @endcond */
     371             : 
     372             :     bool IsEmpty() const;
     373             :     int IsGeographic() const;
     374             :     int IsDerivedGeographic() const;
     375             :     int IsProjected() const;
     376             :     int IsDerivedProjected() const;
     377             :     int IsGeocentric() const;
     378             :     bool IsDynamic() const;
     379             : 
     380             :     // cppcheck-suppress functionStatic
     381             :     bool HasPointMotionOperation() const;
     382             : 
     383             :     int IsLocal() const;
     384             :     int IsVertical() const;
     385             :     int IsCompound() const;
     386             :     int IsSameGeogCS(const OGRSpatialReference *) const;
     387             :     int IsSameGeogCS(const OGRSpatialReference *,
     388             :                      const char *const *papszOptions) const;
     389             :     int IsSameVertCS(const OGRSpatialReference *) const;
     390             :     int IsSame(const OGRSpatialReference *) const;
     391             :     int IsSame(const OGRSpatialReference *,
     392             :                const char *const *papszOptions) const;
     393             : 
     394             :     void Clear();
     395             :     OGRErr SetLocalCS(const char *);
     396             :     OGRErr SetProjCS(const char *);
     397             :     OGRErr SetProjection(const char *);
     398             :     OGRErr SetGeocCS(const char *pszGeocName);
     399             :     OGRErr SetGeogCS(const char *pszGeogName, const char *pszDatumName,
     400             :                      const char *pszEllipsoidName, double dfSemiMajor,
     401             :                      double dfInvFlattening, const char *pszPMName = nullptr,
     402             :                      double dfPMOffset = 0.0, const char *pszUnits = nullptr,
     403             :                      double dfConvertToRadians = 0.0);
     404             :     OGRErr SetWellKnownGeogCS(const char *);
     405             :     OGRErr CopyGeogCSFrom(const OGRSpatialReference *poSrcSRS);
     406             :     OGRErr SetVertCS(const char *pszVertCSName, const char *pszVertDatumName,
     407             :                      int nVertDatumClass = 2005);
     408             :     OGRErr SetCompoundCS(const char *pszName,
     409             :                          const OGRSpatialReference *poHorizSRS,
     410             :                          const OGRSpatialReference *poVertSRS);
     411             : 
     412             :     void SetCoordinateEpoch(double dfCoordinateEpoch);
     413             :     double GetCoordinateEpoch() const;
     414             : 
     415             :     // cppcheck-suppress functionStatic
     416             :     OGRErr PromoteTo3D(const char *pszName);
     417             :     // cppcheck-suppress functionStatic
     418             :     OGRErr DemoteTo2D(const char *pszName);
     419             : 
     420             :     OGRErr SetFromUserInput(const char *);
     421             : 
     422             :     static const char *const SET_FROM_USER_INPUT_LIMITATIONS[];
     423             :     static CSLConstList SET_FROM_USER_INPUT_LIMITATIONS_get();
     424             : 
     425             :     OGRErr SetFromUserInput(const char *, CSLConstList papszOptions);
     426             : 
     427             :     OGRErr SetTOWGS84(double, double, double, double = 0.0, double = 0.0,
     428             :                       double = 0.0, double = 0.0);
     429             :     OGRErr GetTOWGS84(double *padfCoef, int nCoeff = 7) const;
     430             :     OGRErr AddGuessedTOWGS84();
     431             : 
     432             :     double GetSemiMajor(OGRErr * = nullptr) const;
     433             :     double GetSemiMinor(OGRErr * = nullptr) const;
     434             :     double GetInvFlattening(OGRErr * = nullptr) const;
     435             :     double GetEccentricity() const;
     436             :     double GetSquaredEccentricity() const;
     437             : 
     438             :     OGRErr SetAuthority(const char *pszTargetKey, const char *pszAuthority,
     439             :                         int nCode);
     440             : 
     441             :     OGRErr AutoIdentifyEPSG();
     442             :     OGRSpatialReferenceH *FindMatches(char **papszOptions, int *pnEntries,
     443             :                                       int **ppanMatchConfidence) const;
     444             :     OGRSpatialReference *
     445             :     FindBestMatch(int nMinimumMatchConfidence = 90,
     446             :                   const char *pszPreferredAuthority = "EPSG",
     447             :                   CSLConstList papszOptions = nullptr) const;
     448             : 
     449             :     int GetEPSGGeogCS() const;
     450             : 
     451             :     const char *GetAuthorityCode(const char *pszTargetKey) const;
     452             :     const char *GetAuthorityName(const char *pszTargetKey) const;
     453             :     char *GetOGCURN() const;
     454             : 
     455             :     bool GetAreaOfUse(double *pdfWestLongitudeDeg, double *pdfSouthLatitudeDeg,
     456             :                       double *pdfEastLongitudeDeg, double *pdfNorthLatitudeDeg,
     457             :                       const char **ppszAreaName) const;
     458             : 
     459             :     const char *GetExtension(const char *pszTargetKey, const char *pszName,
     460             :                              const char *pszDefault = nullptr) const;
     461             :     OGRErr SetExtension(const char *pszTargetKey, const char *pszName,
     462             :                         const char *pszValue);
     463             : 
     464             :     int FindProjParm(const char *pszParameter,
     465             :                      const OGR_SRSNode *poPROJCS = nullptr) const;
     466             :     OGRErr SetProjParm(const char *, double);
     467             :     double GetProjParm(const char *, double = 0.0, OGRErr * = nullptr) const;
     468             : 
     469             :     OGRErr SetNormProjParm(const char *, double);
     470             :     double GetNormProjParm(const char *, double = 0.0,
     471             :                            OGRErr * = nullptr) const;
     472             : 
     473             :     static int IsAngularParameter(const char *);
     474             :     static int IsLongitudeParameter(const char *);
     475             :     static int IsLinearParameter(const char *);
     476             : 
     477             :     /** Albers Conic Equal Area */
     478             :     OGRErr SetACEA(double dfStdP1, double dfStdP2, double dfCenterLat,
     479             :                    double dfCenterLong, double dfFalseEasting,
     480             :                    double dfFalseNorthing);
     481             : 
     482             :     /** Azimuthal Equidistant */
     483             :     OGRErr SetAE(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
     484             :                  double dfFalseNorthing);
     485             : 
     486             :     /** Bonne */
     487             :     OGRErr SetBonne(double dfStdP1, double dfCentralMeridian,
     488             :                     double dfFalseEasting, double dfFalseNorthing);
     489             : 
     490             :     /** Cylindrical Equal Area */
     491             :     OGRErr SetCEA(double dfStdP1, double dfCentralMeridian,
     492             :                   double dfFalseEasting, double dfFalseNorthing);
     493             : 
     494             :     /** Cassini-Soldner */
     495             :     OGRErr SetCS(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
     496             :                  double dfFalseNorthing);
     497             : 
     498             :     /** Equidistant Conic */
     499             :     OGRErr SetEC(double dfStdP1, double dfStdP2, double dfCenterLat,
     500             :                  double dfCenterLong, double dfFalseEasting,
     501             :                  double dfFalseNorthing);
     502             : 
     503             :     /** Eckert I */
     504             :     OGRErr SetEckert(int nVariation, double dfCentralMeridian,
     505             :                      double dfFalseEasting, double dfFalseNorthing);
     506             : 
     507             :     /** Eckert IV */
     508             :     OGRErr SetEckertIV(double dfCentralMeridian, double dfFalseEasting,
     509             :                        double dfFalseNorthing);
     510             : 
     511             :     /** Eckert VI */
     512             :     OGRErr SetEckertVI(double dfCentralMeridian, double dfFalseEasting,
     513             :                        double dfFalseNorthing);
     514             : 
     515             :     /** Equirectangular */
     516             :     OGRErr SetEquirectangular(double dfCenterLat, double dfCenterLong,
     517             :                               double dfFalseEasting, double dfFalseNorthing);
     518             :     /** Equirectangular generalized form : */
     519             :     OGRErr SetEquirectangular2(double dfCenterLat, double dfCenterLong,
     520             :                                double dfPseudoStdParallel1,
     521             :                                double dfFalseEasting, double dfFalseNorthing);
     522             : 
     523             :     /** Geostationary Satellite */
     524             :     OGRErr SetGEOS(double dfCentralMeridian, double dfSatelliteHeight,
     525             :                    double dfFalseEasting, double dfFalseNorthing);
     526             : 
     527             :     /** Goode Homolosine */
     528             :     OGRErr SetGH(double dfCentralMeridian, double dfFalseEasting,
     529             :                  double dfFalseNorthing);
     530             : 
     531             :     /** Interrupted Goode Homolosine */
     532             :     OGRErr SetIGH();
     533             : 
     534             :     /** Gall Stereographic */
     535             :     OGRErr SetGS(double dfCentralMeridian, double dfFalseEasting,
     536             :                  double dfFalseNorthing);
     537             : 
     538             :     /** Gauss Schreiber Transverse Mercator */
     539             :     OGRErr SetGaussSchreiberTMercator(double dfCenterLat, double dfCenterLong,
     540             :                                       double dfScale, double dfFalseEasting,
     541             :                                       double dfFalseNorthing);
     542             : 
     543             :     /** Gnomonic */
     544             :     OGRErr SetGnomonic(double dfCenterLat, double dfCenterLong,
     545             :                        double dfFalseEasting, double dfFalseNorthing);
     546             : 
     547             :     /** Hotine Oblique Mercator */
     548             :     OGRErr SetHOM(double dfCenterLat, double dfCenterLong, double dfAzimuth,
     549             :                   double dfRectToSkew, double dfScale, double dfFalseEasting,
     550             :                   double dfFalseNorthing);
     551             : 
     552             :     /**  Hotine Oblique Mercator 2 points */
     553             :     OGRErr SetHOM2PNO(double dfCenterLat, double dfLat1, double dfLong1,
     554             :                       double dfLat2, double dfLong2, double dfScale,
     555             :                       double dfFalseEasting, double dfFalseNorthing);
     556             : 
     557             :     /** Hotine Oblique Mercator Azimuth Center / Variant B */
     558             :     OGRErr SetHOMAC(double dfCenterLat, double dfCenterLong, double dfAzimuth,
     559             :                     double dfRectToSkew, double dfScale, double dfFalseEasting,
     560             :                     double dfFalseNorthing);
     561             : 
     562             :     /** Laborde Oblique Mercator */
     563             :     OGRErr SetLOM(double dfCenterLat, double dfCenterLong, double dfAzimuth,
     564             :                   double dfScale, double dfFalseEasting,
     565             :                   double dfFalseNorthing);
     566             : 
     567             :     /** International Map of the World Polyconic */
     568             :     OGRErr SetIWMPolyconic(double dfLat1, double dfLat2, double dfCenterLong,
     569             :                            double dfFalseEasting, double dfFalseNorthing);
     570             : 
     571             :     /** Krovak Oblique Conic Conformal */
     572             :     OGRErr SetKrovak(double dfCenterLat, double dfCenterLong, double dfAzimuth,
     573             :                      double dfPseudoStdParallelLat, double dfScale,
     574             :                      double dfFalseEasting, double dfFalseNorthing);
     575             : 
     576             :     /** Lambert Azimuthal Equal-Area */
     577             :     OGRErr SetLAEA(double dfCenterLat, double dfCenterLong,
     578             :                    double dfFalseEasting, double dfFalseNorthing);
     579             : 
     580             :     /** Lambert Conformal Conic */
     581             :     OGRErr SetLCC(double dfStdP1, double dfStdP2, double dfCenterLat,
     582             :                   double dfCenterLong, double dfFalseEasting,
     583             :                   double dfFalseNorthing);
     584             : 
     585             :     /** Lambert Conformal Conic 1SP */
     586             :     OGRErr SetLCC1SP(double dfCenterLat, double dfCenterLong, double dfScale,
     587             :                      double dfFalseEasting, double dfFalseNorthing);
     588             : 
     589             :     /** Lambert Conformal Conic (Belgium) */
     590             :     OGRErr SetLCCB(double dfStdP1, double dfStdP2, double dfCenterLat,
     591             :                    double dfCenterLong, double dfFalseEasting,
     592             :                    double dfFalseNorthing);
     593             : 
     594             :     /** Miller Cylindrical */
     595             :     OGRErr SetMC(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
     596             :                  double dfFalseNorthing);
     597             : 
     598             :     /** Mercator 1SP */
     599             :     OGRErr SetMercator(double dfCenterLat, double dfCenterLong, double dfScale,
     600             :                        double dfFalseEasting, double dfFalseNorthing);
     601             : 
     602             :     /** Mercator 2SP */
     603             :     OGRErr SetMercator2SP(double dfStdP1, double dfCenterLat,
     604             :                           double dfCenterLong, double dfFalseEasting,
     605             :                           double dfFalseNorthing);
     606             : 
     607             :     /** Mollweide */
     608             :     OGRErr SetMollweide(double dfCentralMeridian, double dfFalseEasting,
     609             :                         double dfFalseNorthing);
     610             : 
     611             :     /** New Zealand Map Grid */
     612             :     OGRErr SetNZMG(double dfCenterLat, double dfCenterLong,
     613             :                    double dfFalseEasting, double dfFalseNorthing);
     614             : 
     615             :     /** Oblique Stereographic */
     616             :     OGRErr SetOS(double dfOriginLat, double dfCMeridian, double dfScale,
     617             :                  double dfFalseEasting, double dfFalseNorthing);
     618             : 
     619             :     /** Orthographic */
     620             :     OGRErr SetOrthographic(double dfCenterLat, double dfCenterLong,
     621             :                            double dfFalseEasting, double dfFalseNorthing);
     622             : 
     623             :     /** Polyconic */
     624             :     OGRErr SetPolyconic(double dfCenterLat, double dfCenterLong,
     625             :                         double dfFalseEasting, double dfFalseNorthing);
     626             : 
     627             :     /** Polar Stereographic */
     628             :     OGRErr SetPS(double dfCenterLat, double dfCenterLong, double dfScale,
     629             :                  double dfFalseEasting, double dfFalseNorthing);
     630             : 
     631             :     /** Robinson */
     632             :     OGRErr SetRobinson(double dfCenterLong, double dfFalseEasting,
     633             :                        double dfFalseNorthing);
     634             : 
     635             :     /** Sinusoidal */
     636             :     OGRErr SetSinusoidal(double dfCenterLong, double dfFalseEasting,
     637             :                          double dfFalseNorthing);
     638             : 
     639             :     /** Stereographic */
     640             :     OGRErr SetStereographic(double dfCenterLat, double dfCenterLong,
     641             :                             double dfScale, double dfFalseEasting,
     642             :                             double dfFalseNorthing);
     643             : 
     644             :     /** Swiss Oblique Cylindrical */
     645             :     OGRErr SetSOC(double dfLatitudeOfOrigin, double dfCentralMeridian,
     646             :                   double dfFalseEasting, double dfFalseNorthing);
     647             : 
     648             :     /** Transverse Mercator */
     649             :     OGRErr SetTM(double dfCenterLat, double dfCenterLong, double dfScale,
     650             :                  double dfFalseEasting, double dfFalseNorthing);
     651             : 
     652             :     /** Transverse Mercator variants. */
     653             :     OGRErr SetTMVariant(const char *pszVariantName, double dfCenterLat,
     654             :                         double dfCenterLong, double dfScale,
     655             :                         double dfFalseEasting, double dfFalseNorthing);
     656             : 
     657             :     /** Tunesia Mining Grid  */
     658             :     OGRErr SetTMG(double dfCenterLat, double dfCenterLong,
     659             :                   double dfFalseEasting, double dfFalseNorthing);
     660             : 
     661             :     /** Transverse Mercator (South Oriented) */
     662             :     OGRErr SetTMSO(double dfCenterLat, double dfCenterLong, double dfScale,
     663             :                    double dfFalseEasting, double dfFalseNorthing);
     664             : 
     665             :     /** Two Point Equidistant */
     666             :     OGRErr SetTPED(double dfLat1, double dfLong1, double dfLat2, double dfLong2,
     667             :                    double dfFalseEasting, double dfFalseNorthing);
     668             : 
     669             :     /** VanDerGrinten */
     670             :     OGRErr SetVDG(double dfCenterLong, double dfFalseEasting,
     671             :                   double dfFalseNorthing);
     672             : 
     673             :     /** Universal Transverse Mercator */
     674             :     OGRErr SetUTM(int nZone, int bNorth = TRUE);
     675             :     int GetUTMZone(int *pbNorth = nullptr) const;
     676             : 
     677             :     /** Wagner I -- VII */
     678             :     OGRErr SetWagner(int nVariation, double dfCenterLat, double dfFalseEasting,
     679             :                      double dfFalseNorthing);
     680             : 
     681             :     /** Quadrilateralized Spherical Cube */
     682             :     OGRErr SetQSC(double dfCenterLat, double dfCenterLong);
     683             : 
     684             :     /** Spherical, Cross-track, Height */
     685             :     OGRErr SetSCH(double dfPegLat, double dfPegLong, double dfPegHeading,
     686             :                   double dfPegHgt);
     687             : 
     688             :     /** Vertical Perspective / Near-sided Perspective */
     689             :     OGRErr
     690             :     SetVerticalPerspective(double dfTopoOriginLat, double dfTopoOriginLon,
     691             :                            double dfTopoOriginHeight, double dfViewPointHeight,
     692             :                            double dfFalseEasting, double dfFalseNorthing);
     693             : 
     694             :     /** Pole rotation (GRIB convention) */
     695             :     OGRErr SetDerivedGeogCRSWithPoleRotationGRIBConvention(
     696             :         const char *pszCRSName, double dfSouthPoleLat, double dfSouthPoleLon,
     697             :         double dfAxisRotation);
     698             : 
     699             :     /** Pole rotation (netCDF CF convention) */
     700             :     OGRErr SetDerivedGeogCRSWithPoleRotationNetCDFCFConvention(
     701             :         const char *pszCRSName, double dfGridNorthPoleLat,
     702             :         double dfGridNorthPoleLon, double dfNorthPoleGridLon);
     703             : 
     704             :     /** State Plane */
     705             :     OGRErr SetStatePlane(int nZone, int bNAD83 = TRUE,
     706             :                          const char *pszOverrideUnitName = nullptr,
     707             :                          double dfOverrideUnit = 0.0);
     708             : 
     709             :     /** ImportFromESRIStatePlaneWKT */
     710             :     OGRErr ImportFromESRIStatePlaneWKT(int nCode, const char *pszDatumName,
     711             :                                        const char *pszUnitsName, int nPCSCode,
     712             :                                        const char *pszCRSName = nullptr);
     713             : 
     714             :     /** ImportFromESRIWisconsinWKT */
     715             :     OGRErr ImportFromESRIWisconsinWKT(const char *pszPrjName,
     716             :                                       double dfCentralMeridian,
     717             :                                       double dfLatOfOrigin,
     718             :                                       const char *pszUnitsName,
     719             :                                       const char *pszCRSName = nullptr);
     720             : 
     721             :     /*! @cond Doxygen_Suppress */
     722             :     void UpdateCoordinateSystemFromGeogCRS();
     723             :     /*! @endcond */
     724             : 
     725             :     static OGRSpatialReference *GetWGS84SRS();
     726             : 
     727             :     /** Convert a OGRSpatialReference* to a OGRSpatialReferenceH.
     728             :      * @since GDAL 2.3
     729             :      */
     730       27758 :     static inline OGRSpatialReferenceH ToHandle(OGRSpatialReference *poSRS)
     731             :     {
     732       27758 :         return reinterpret_cast<OGRSpatialReferenceH>(poSRS);
     733             :     }
     734             : 
     735             :     /** Convert a OGRSpatialReferenceH to a OGRSpatialReference*.
     736             :      * @since GDAL 2.3
     737             :      */
     738      198715 :     static inline OGRSpatialReference *FromHandle(OGRSpatialReferenceH hSRS)
     739             :     {
     740      198715 :         return reinterpret_cast<OGRSpatialReference *>(hSRS);
     741             :     }
     742             : };
     743             : 
     744             : /*! @cond Doxygen_Suppress */
     745             : struct CPL_DLL OGRSpatialReferenceReleaser
     746             : {
     747        3479 :     void operator()(OGRSpatialReference *poSRS) const
     748             :     {
     749        3479 :         if (poSRS)
     750        3479 :             poSRS->Release();
     751        3479 :     }
     752             : };
     753             : 
     754             : /*! @endcond */
     755             : 
     756             : /************************************************************************/
     757             : /*                     OGRCoordinateTransformation                      */
     758             : /*                                                                      */
     759             : /*      This is really just used as a base class for a private          */
     760             : /*      implementation.                                                 */
     761             : /************************************************************************/
     762             : 
     763             : /**
     764             :  * Interface for transforming between coordinate systems.
     765             :  *
     766             :  * Currently, the only implementation within OGR is OGRProjCT, which
     767             :  * requires the PROJ library.
     768             :  *
     769             :  * Also, see OGRCreateCoordinateTransformation() for creating transformations.
     770             :  */
     771             : 
     772             : class CPL_DLL OGRCoordinateTransformation
     773             : {
     774             :   public:
     775       10242 :     virtual ~OGRCoordinateTransformation()
     776       10242 :     {
     777       10242 :     }
     778             : 
     779             :     static void DestroyCT(OGRCoordinateTransformation *poCT);
     780             : 
     781             :     // From CT_CoordinateTransformation
     782             : 
     783             :     /** Fetch internal source coordinate system. */
     784             :     virtual const OGRSpatialReference *GetSourceCS() const = 0;
     785             : 
     786             :     /** Fetch internal target coordinate system. */
     787             :     virtual const OGRSpatialReference *GetTargetCS() const = 0;
     788             : 
     789             :     /** Whether the transformer will emit CPLError */
     790           0 :     virtual bool GetEmitErrors() const
     791             :     {
     792           0 :         return false;
     793             :     }
     794             : 
     795             :     /** Set if the transformer must emit CPLError */
     796           0 :     virtual void SetEmitErrors(bool /*bEmitErrors*/)
     797             :     {
     798           0 :     }
     799             : 
     800             :     // From CT_MathTransform
     801             : 
     802             :     /**
     803             :      * Transform points from source to destination space.
     804             :      *
     805             :      * This method is the same as the C function OCTTransformEx().
     806             :      *
     807             :      * @param nCount number of points to transform (`size_t` type since 3.9,
     808             :      *               `int` in previous versions).
     809             :      * @param x array of nCount X vertices, modified in place. Should not be
     810             :      * NULL.
     811             :      * @param y array of nCount Y vertices, modified in place. Should not be
     812             :      * NULL.
     813             :      * @param z array of nCount Z vertices, modified in place. Might be NULL.
     814             :      * @param pabSuccess array of per-point flags set to TRUE if that point
     815             :      * transforms, or FALSE if it does not. Might be NULL.
     816             :      *
     817             :      * @return TRUE if a transformation could be found (but not all points may
     818             :      * have necessarily succeed to transform), otherwise FALSE.
     819             :      */
     820             :     int Transform(size_t nCount, double *x, double *y, double *z = nullptr,
     821             :                   int *pabSuccess = nullptr);
     822             : 
     823             :     /**
     824             :      * Transform points from source to destination space.
     825             :      *
     826             :      * This method is the same as the C function OCTTransform4D().
     827             :      *
     828             :      * @param nCount number of points to transform (`size_t` type since 3.9,
     829             :      *               `int` in previous versions).
     830             :      * @param x array of nCount X vertices, modified in place. Should not be
     831             :      * NULL.
     832             :      * @param y array of nCount Y vertices, modified in place. Should not be
     833             :      * NULL.
     834             :      * @param z array of nCount Z vertices, modified in place. Might be NULL.
     835             :      * @param t array of nCount time values, modified in place. Might be NULL.
     836             :      * @param pabSuccess array of per-point flags set to TRUE if that point
     837             :      * transforms, or FALSE if it does not. Might be NULL.
     838             :      *
     839             :      * @return TRUE if a transformation could be found (but not all points may
     840             :      * have necessarily succeed to transform), otherwise FALSE.
     841             :      */
     842             :     virtual int Transform(size_t nCount, double *x, double *y, double *z,
     843             :                           double *t, int *pabSuccess) = 0;
     844             : 
     845             :     /**
     846             :      * Transform points from source to destination space.
     847             :      *
     848             :      * This method is the same as the C function OCTTransform4DWithErrorCodes().
     849             :      *
     850             :      * @param nCount number of points to transform (`size_t` type since 3.9,
     851             :      *               `int` in previous versions).
     852             :      * @param x array of nCount X vertices, modified in place. Should not be
     853             :      * NULL.
     854             :      * @param y array of nCount Y vertices, modified in place. Should not be
     855             :      * NULL.
     856             :      * @param z array of nCount Z vertices, modified in place. Might be NULL.
     857             :      * @param t array of nCount time values, modified in place. Might be NULL.
     858             :      * @param panErrorCodes Output array of nCount value that will be set to 0
     859             :      * for success, or a non-zero value for failure. Refer to PROJ 8 public
     860             :      * error codes. Might be NULL
     861             :      * @return TRUE if a transformation could be found (but not all points may
     862             :      * have necessarily succeed to transform), otherwise FALSE.
     863             :      * @since GDAL 3.3, and PROJ 8 to be able to use PROJ public error codes
     864             :      */
     865             :     virtual int TransformWithErrorCodes(size_t nCount, double *x, double *y,
     866             :                                         double *z, double *t,
     867             :                                         int *panErrorCodes);
     868             : 
     869             :     /** \brief Transform boundary.
     870             :      *
     871             :      * This method is the same as the C function OCTTransformBounds().
     872             :      *
     873             :      * Transform boundary densifying the edges to account for nonlinear
     874             :      * transformations along these edges and extracting the outermost bounds.
     875             :      *
     876             :      * If the destination CRS is geographic, the first axis is longitude,
     877             :      * and xmax < xmin then the bounds crossed the antimeridian.
     878             :      * In this scenario there are two polygons, one on each side of the
     879             :      * antimeridian. The first polygon should be constructed with (xmin, ymin,
     880             :      * 180, ymax) and the second with (-180, ymin, xmax, ymax).
     881             :      *
     882             :      * If the destination CRS is geographic, the first axis is latitude,
     883             :      * and ymax < ymin then the bounds crossed the antimeridian.
     884             :      * In this scenario there are two polygons, one on each side of the
     885             :      * antimeridian. The first polygon should be constructed with (ymin, xmin,
     886             :      * ymax, 180) and the second with (ymin, -180, ymax, xmax).
     887             :      *
     888             :      * @param xmin Minimum bounding coordinate of the first axis in source CRS.
     889             :      * @param ymin Minimum bounding coordinate of the second axis in source CRS.
     890             :      * @param xmax Maximum bounding coordinate of the first axis in source CRS.
     891             :      * @param ymax Maximum bounding coordinate of the second axis in source CRS.
     892             :      * @param out_xmin Minimum bounding coordinate of the first axis in target
     893             :      * CRS
     894             :      * @param out_ymin Minimum bounding coordinate of the second axis in target
     895             :      * CRS.
     896             :      * @param out_xmax Maximum bounding coordinate of the first axis in target
     897             :      * CRS.
     898             :      * @param out_ymax Maximum bounding coordinate of the second axis in target
     899             :      * CRS.
     900             :      * @param densify_pts Recommended to use 21. This is the number of points
     901             :      *     to use to densify the bounding polygon in the transformation.
     902             :      * @return TRUE if successful. FALSE if failures encountered.
     903             :      * @since 3.4
     904             :      */
     905           0 :     virtual int TransformBounds(const double xmin, const double ymin,
     906             :                                 const double xmax, const double ymax,
     907             :                                 double *out_xmin, double *out_ymin,
     908             :                                 double *out_xmax, double *out_ymax,
     909             :                                 const int densify_pts)
     910             :     {
     911             :         (void)xmin;
     912             :         (void)xmax;
     913             :         (void)ymin;
     914             :         (void)ymax;
     915             :         (void)densify_pts;
     916           0 :         *out_xmin = HUGE_VAL;
     917           0 :         *out_ymin = HUGE_VAL;
     918           0 :         *out_xmax = HUGE_VAL;
     919           0 :         *out_ymax = HUGE_VAL;
     920           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     921             :                  "TransformBounds not implemented.");
     922           0 :         return false;
     923             :     }
     924             : 
     925             :     /** Convert a OGRCoordinateTransformation* to a
     926             :      * OGRCoordinateTransformationH.
     927             :      * @since GDAL 2.3
     928             :      */
     929             :     static inline OGRCoordinateTransformationH
     930           3 :     ToHandle(OGRCoordinateTransformation *poCT)
     931             :     {
     932           3 :         return reinterpret_cast<OGRCoordinateTransformationH>(poCT);
     933             :     }
     934             : 
     935             :     /** Convert a OGRCoordinateTransformationH to a
     936             :      * OGRCoordinateTransformation*.
     937             :      * @since GDAL 2.3
     938             :      */
     939             :     static inline OGRCoordinateTransformation *
     940        1416 :     FromHandle(OGRCoordinateTransformationH hCT)
     941             :     {
     942        1416 :         return reinterpret_cast<OGRCoordinateTransformation *>(hCT);
     943             :     }
     944             : 
     945             :     /** Clone
     946             :      * @since GDAL 3.1
     947             :      */
     948             :     virtual OGRCoordinateTransformation *Clone() const = 0;
     949             : 
     950             :     /** Return a coordinate transformation that performs the inverse
     951             :      * transformation of the current one.
     952             :      *
     953             :      * In some cases, this is not possible, and this method might return
     954             :      * nullptr, or fail to perform the transformations.
     955             :      *
     956             :      * @return the new coordinate transformation, or nullptr in case of error.
     957             :      * @since GDAL 3.3
     958             :      */
     959             :     virtual OGRCoordinateTransformation *GetInverse() const = 0;
     960             : };
     961             : 
     962             : OGRCoordinateTransformation CPL_DLL *
     963             : OGRCreateCoordinateTransformation(const OGRSpatialReference *poSource,
     964             :                                   const OGRSpatialReference *poTarget);
     965             : 
     966             : /**
     967             :  * Context for coordinate transformation.
     968             :  *
     969             :  * @since GDAL 3.0
     970             :  */
     971             : 
     972             : struct CPL_DLL OGRCoordinateTransformationOptions
     973             : {
     974             :     /*! @cond Doxygen_Suppress */
     975             :   private:
     976             :     friend class OGRProjCT;
     977             :     struct Private;
     978             :     std::unique_ptr<Private> d;
     979             :     /*! @endcond */
     980             : 
     981             :   public:
     982             :     OGRCoordinateTransformationOptions();
     983             :     OGRCoordinateTransformationOptions(
     984             :         const OGRCoordinateTransformationOptions &);
     985             :     OGRCoordinateTransformationOptions &
     986             :     operator=(const OGRCoordinateTransformationOptions &);
     987             :     ~OGRCoordinateTransformationOptions();
     988             : 
     989             :     bool SetAreaOfInterest(double dfWestLongitudeDeg, double dfSouthLatitudeDeg,
     990             :                            double dfEastLongitudeDeg,
     991             :                            double dfNorthLatitudeDeg);
     992             :     bool SetDesiredAccuracy(double dfAccuracy);
     993             :     bool SetBallparkAllowed(bool bAllowBallpark);
     994             :     bool SetOnlyBest(bool bOnlyBest);
     995             : 
     996             :     bool SetCoordinateOperation(const char *pszCT, bool bReverseCT);
     997             :     /*! @cond Doxygen_Suppress */
     998             :     void SetSourceCenterLong(double dfCenterLong);
     999             :     void SetTargetCenterLong(double dfCenterLong);
    1000             :     /*! @endcond */
    1001             : };
    1002             : 
    1003             : OGRCoordinateTransformation CPL_DLL *OGRCreateCoordinateTransformation(
    1004             :     const OGRSpatialReference *poSource, const OGRSpatialReference *poTarget,
    1005             :     const OGRCoordinateTransformationOptions &options);
    1006             : 
    1007             : #endif /* ndef OGR_SPATIALREF_H_INCLUDED */

Generated by: LCOV version 1.14