LCOV - code coverage report
Current view: top level - ogr - ogr_spatialref.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 46 57 80.7 %
Date: 2026-07-24 18:27:47 Functions: 24 29 82.8 %

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

Generated by: LCOV version 1.14