"Fossies" - the Fresh Open Source Software Archive

Member "proj-6.2.1/include/proj/crs.hpp" (28 Oct 2019, 54042 Bytes) of package /linux/privat/proj-6.2.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "crs.hpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 6.2.0_vs_6.2.1.

    1 /******************************************************************************
    2  *
    3  * Project:  PROJ
    4  * Purpose:  ISO19111:2019 implementation
    5  * Author:   Even Rouault <even dot rouault at spatialys dot com>
    6  *
    7  ******************************************************************************
    8  * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
    9  *
   10  * Permission is hereby granted, free of charge, to any person obtaining a
   11  * copy of this software and associated documentation files (the "Software"),
   12  * to deal in the Software without restriction, including without limitation
   13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   14  * and/or sell copies of the Software, and to permit persons to whom the
   15  * Software is furnished to do so, subject to the following conditions:
   16  *
   17  * The above copyright notice and this permission notice shall be included
   18  * in all copies or substantial portions of the Software.
   19  *
   20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   26  * DEALINGS IN THE SOFTWARE.
   27  ****************************************************************************/
   28 
   29 #ifndef CRS_HH_INCLUDED
   30 #define CRS_HH_INCLUDED
   31 
   32 #include <memory>
   33 #include <string>
   34 #include <vector>
   35 
   36 #include "common.hpp"
   37 #include "coordinateoperation.hpp"
   38 #include "coordinatesystem.hpp"
   39 #include "datum.hpp"
   40 #include "io.hpp"
   41 #include "util.hpp"
   42 
   43 NS_PROJ_START
   44 
   45 /** osgeo.proj.crs namespace
   46 
   47     \brief CRS (coordinate reference system = coordinate system with a datum).
   48 */
   49 namespace crs {
   50 
   51 // ---------------------------------------------------------------------------
   52 
   53 class GeographicCRS;
   54 /** Shared pointer of GeographicCRS */
   55 using GeographicCRSPtr = std::shared_ptr<GeographicCRS>;
   56 /** Non-null shared pointer of GeographicCRS */
   57 using GeographicCRSNNPtr = util::nn<GeographicCRSPtr>;
   58 
   59 class VerticalCRS;
   60 /** Shared pointer of VerticalCRS */
   61 using VerticalCRSPtr = std::shared_ptr<VerticalCRS>;
   62 /** Non-null shared pointer of VerticalCRS */
   63 using VerticalCRSNNPtr = util::nn<VerticalCRSPtr>;
   64 
   65 class BoundCRS;
   66 /** Shared pointer of BoundCRS */
   67 using BoundCRSPtr = std::shared_ptr<BoundCRS>;
   68 /** Non-null shared pointer of BoundCRS */
   69 using BoundCRSNNPtr = util::nn<BoundCRSPtr>;
   70 
   71 // ---------------------------------------------------------------------------
   72 
   73 class CRS;
   74 /** Shared pointer of CRS */
   75 using CRSPtr = std::shared_ptr<CRS>;
   76 /** Non-null shared pointer of CRS */
   77 using CRSNNPtr = util::nn<CRSPtr>;
   78 
   79 /** \brief Abstract class modelling a coordinate reference system which is
   80  * usually single but may be compound.
   81  *
   82  * \remark Implements CRS from \ref ISO_19111_2019
   83  */
   84 class PROJ_GCC_DLL CRS : public common::ObjectUsage,
   85                          public io::IJSONExportable {
   86   public:
   87     //! @cond Doxygen_Suppress
   88     PROJ_DLL ~CRS() override;
   89     //! @endcond
   90 
   91     // Non-standard
   92 
   93     PROJ_DLL GeodeticCRSPtr extractGeodeticCRS() const;
   94     PROJ_DLL GeographicCRSPtr extractGeographicCRS() const;
   95     PROJ_DLL VerticalCRSPtr extractVerticalCRS() const;
   96     PROJ_DLL CRSNNPtr createBoundCRSToWGS84IfPossible(
   97         const io::DatabaseContextPtr &dbContext,
   98         operation::CoordinateOperationContext::IntermediateCRSUse
   99             allowIntermediateCRSUse) const;
  100     PROJ_DLL CRSNNPtr stripVerticalComponent() const;
  101 
  102     PROJ_DLL const BoundCRSPtr &canonicalBoundCRS() PROJ_PURE_DECL;
  103 
  104     PROJ_DLL std::list<std::pair<CRSNNPtr, int>>
  105     identify(const io::AuthorityFactoryPtr &authorityFactory) const;
  106 
  107     PROJ_DLL std::list<CRSNNPtr>
  108     getNonDeprecated(const io::DatabaseContextNNPtr &dbContext) const;
  109 
  110     PROJ_DLL CRSNNPtr
  111     promoteTo3D(const std::string &newName,
  112                 const io::DatabaseContextPtr &dbContext) const;
  113 
  114     PROJ_PRIVATE :
  115         //! @cond Doxygen_Suppress
  116         PROJ_INTERNAL const GeodeticCRS *
  117         extractGeodeticCRSRaw() const;
  118 
  119     PROJ_FOR_TEST CRSNNPtr shallowClone() const;
  120 
  121     PROJ_FOR_TEST CRSNNPtr alterName(const std::string &newName) const;
  122 
  123     PROJ_FOR_TEST CRSNNPtr alterId(const std::string &authName,
  124                                    const std::string &code) const;
  125 
  126     PROJ_INTERNAL const std::string &getExtensionProj4() const noexcept;
  127 
  128     PROJ_FOR_TEST CRSNNPtr
  129     alterGeodeticCRS(const GeodeticCRSNNPtr &newGeodCRS) const;
  130 
  131     PROJ_FOR_TEST CRSNNPtr
  132     alterCSLinearUnit(const common::UnitOfMeasure &unit) const;
  133 
  134     PROJ_INTERNAL bool mustAxisOrderBeSwitchedForVisualization() const;
  135 
  136     PROJ_INTERNAL CRSNNPtr normalizeForVisualization() const;
  137 
  138     //! @endcond
  139 
  140   protected:
  141     PROJ_INTERNAL CRS();
  142     PROJ_INTERNAL CRS(const CRS &other);
  143     friend class BoundCRS;
  144     PROJ_INTERNAL void setCanonicalBoundCRS(const BoundCRSNNPtr &boundCRS);
  145 
  146     PROJ_INTERNAL virtual CRSNNPtr _shallowClone() const = 0;
  147 
  148     PROJ_INTERNAL virtual std::list<std::pair<CRSNNPtr, int>>
  149     _identify(const io::AuthorityFactoryPtr &authorityFactory) const;
  150 
  151   private:
  152     PROJ_OPAQUE_PRIVATE_DATA
  153 };
  154 
  155 // ---------------------------------------------------------------------------
  156 
  157 /** \brief Abstract class modelling a coordinate reference system consisting of
  158  * one Coordinate System and either one datum::Datum or one
  159  * datum::DatumEnsemble.
  160  *
  161  * \remark Implements SingleCRS from \ref ISO_19111_2019
  162  */
  163 class PROJ_GCC_DLL SingleCRS : public CRS {
  164   public:
  165     //! @cond Doxygen_Suppress
  166     PROJ_DLL ~SingleCRS() override;
  167     //! @endcond
  168 
  169     PROJ_DLL const datum::DatumPtr &datum() PROJ_PURE_DECL;
  170     PROJ_DLL const datum::DatumEnsemblePtr &datumEnsemble() PROJ_PURE_DECL;
  171     PROJ_DLL const cs::CoordinateSystemNNPtr &coordinateSystem() PROJ_PURE_DECL;
  172 
  173     PROJ_PRIVATE :
  174         //! @cond Doxygen_Suppress
  175         PROJ_INTERNAL void
  176         exportDatumOrDatumEnsembleToWkt(io::WKTFormatter *formatter)
  177             const; // throw(io::FormattingException)
  178                    //! @endcond
  179 
  180   protected:
  181     PROJ_INTERNAL SingleCRS(const datum::DatumPtr &datumIn,
  182                             const datum::DatumEnsemblePtr &datumEnsembleIn,
  183                             const cs::CoordinateSystemNNPtr &csIn);
  184     PROJ_INTERNAL SingleCRS(const SingleCRS &other);
  185 
  186     PROJ_INTERNAL bool
  187     baseIsEquivalentTo(const util::IComparable *other,
  188                        util::IComparable::Criterion criterion =
  189                            util::IComparable::Criterion::STRICT) const;
  190 
  191   private:
  192     PROJ_OPAQUE_PRIVATE_DATA
  193     SingleCRS &operator=(const SingleCRS &other) = delete;
  194 };
  195 
  196 /** Shared pointer of SingleCRS */
  197 using SingleCRSPtr = std::shared_ptr<SingleCRS>;
  198 /** Non-null shared pointer of SingleCRS */
  199 using SingleCRSNNPtr = util::nn<SingleCRSPtr>;
  200 
  201 // ---------------------------------------------------------------------------
  202 
  203 class GeodeticCRS;
  204 /** Shared pointer of GeodeticCRS */
  205 using GeodeticCRSPtr = std::shared_ptr<GeodeticCRS>;
  206 /** Non-null shared pointer of GeodeticCRS */
  207 using GeodeticCRSNNPtr = util::nn<GeodeticCRSPtr>;
  208 
  209 /** \brief A coordinate reference system associated with a geodetic reference
  210  * frame and a three-dimensional Cartesian or spherical coordinate system.
  211  *
  212  * If the geodetic reference frame is dynamic or if the geodetic CRS has an
  213  * association to a velocity model then the geodetic CRS is dynamic, else it
  214  * is static.
  215  *
  216  * \remark Implements GeodeticCRS from \ref ISO_19111_2019
  217  */
  218 class PROJ_GCC_DLL GeodeticCRS : virtual public SingleCRS,
  219                                  public io::IPROJStringExportable {
  220   public:
  221     //! @cond Doxygen_Suppress
  222     PROJ_DLL ~GeodeticCRS() override;
  223     //! @endcond
  224 
  225     PROJ_DLL const datum::GeodeticReferenceFramePtr &datum() PROJ_PURE_DECL;
  226 
  227     PROJ_DLL const datum::PrimeMeridianNNPtr &primeMeridian() PROJ_PURE_DECL;
  228     PROJ_DLL const datum::EllipsoidNNPtr &ellipsoid() PROJ_PURE_DECL;
  229 
  230     // coordinateSystem() returns either a EllipsoidalCS, SphericalCS or
  231     // CartesianCS
  232 
  233     PROJ_DLL const std::vector<operation::PointMotionOperationNNPtr> &
  234     velocityModel() PROJ_PURE_DECL;
  235 
  236     // Non-standard
  237 
  238     PROJ_DLL bool isGeocentric() PROJ_PURE_DECL;
  239 
  240     PROJ_DLL static GeodeticCRSNNPtr
  241     create(const util::PropertyMap &properties,
  242            const datum::GeodeticReferenceFrameNNPtr &datum,
  243            const cs::SphericalCSNNPtr &cs);
  244 
  245     PROJ_DLL static GeodeticCRSNNPtr
  246     create(const util::PropertyMap &properties,
  247            const datum::GeodeticReferenceFrameNNPtr &datum,
  248            const cs::CartesianCSNNPtr &cs);
  249 
  250     PROJ_DLL static GeodeticCRSNNPtr
  251     create(const util::PropertyMap &properties,
  252            const datum::GeodeticReferenceFramePtr &datum,
  253            const datum::DatumEnsemblePtr &datumEnsemble,
  254            const cs::SphericalCSNNPtr &cs);
  255 
  256     PROJ_DLL static GeodeticCRSNNPtr
  257     create(const util::PropertyMap &properties,
  258            const datum::GeodeticReferenceFramePtr &datum,
  259            const datum::DatumEnsemblePtr &datumEnsemble,
  260            const cs::CartesianCSNNPtr &cs);
  261 
  262     PROJ_DLL static const GeodeticCRSNNPtr EPSG_4978; // WGS 84 Geocentric
  263 
  264     PROJ_DLL std::list<std::pair<GeodeticCRSNNPtr, int>>
  265     identify(const io::AuthorityFactoryPtr &authorityFactory) const;
  266 
  267     PROJ_PRIVATE :
  268         //! @cond Doxygen_Suppress
  269         PROJ_INTERNAL void
  270         addDatumInfoToPROJString(io::PROJStringFormatter *formatter) const;
  271 
  272     PROJ_INTERNAL void addGeocentricUnitConversionIntoPROJString(
  273         io::PROJStringFormatter *formatter) const;
  274 
  275     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
  276         const override; // throw(io::FormattingException)
  277 
  278     PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
  279         const override; // throw(FormattingException)
  280 
  281     PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
  282         const override; // throw(FormattingException)
  283 
  284     PROJ_INTERNAL bool
  285     _isEquivalentTo(const util::IComparable *other,
  286                     util::IComparable::Criterion criterion =
  287                         util::IComparable::Criterion::STRICT) const override;
  288 
  289     //! @endcond
  290 
  291   protected:
  292     PROJ_INTERNAL GeodeticCRS(const datum::GeodeticReferenceFramePtr &datumIn,
  293                               const datum::DatumEnsemblePtr &datumEnsembleIn,
  294                               const cs::EllipsoidalCSNNPtr &csIn);
  295     PROJ_INTERNAL GeodeticCRS(const datum::GeodeticReferenceFramePtr &datumIn,
  296                               const datum::DatumEnsemblePtr &datumEnsembleIn,
  297                               const cs::SphericalCSNNPtr &csIn);
  298     PROJ_INTERNAL GeodeticCRS(const datum::GeodeticReferenceFramePtr &datumIn,
  299                               const datum::DatumEnsemblePtr &datumEnsembleIn,
  300                               const cs::CartesianCSNNPtr &csIn);
  301     PROJ_INTERNAL GeodeticCRS(const GeodeticCRS &other);
  302 
  303     PROJ_INTERNAL static GeodeticCRSNNPtr createEPSG_4978();
  304 
  305     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
  306 
  307     PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
  308     _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
  309 
  310     INLINED_MAKE_SHARED
  311 
  312   private:
  313     PROJ_OPAQUE_PRIVATE_DATA
  314 
  315     GeodeticCRS &operator=(const GeodeticCRS &other) = delete;
  316 };
  317 
  318 // ---------------------------------------------------------------------------
  319 
  320 /** \brief A coordinate reference system associated with a geodetic reference
  321  * frame and a two- or three-dimensional ellipsoidal coordinate system.
  322  *
  323  * If the geodetic reference frame is dynamic or if the geographic CRS has an
  324  * association to a velocity model then the geodetic CRS is dynamic, else it is
  325  * static.
  326  *
  327  * \remark Implements GeographicCRS from \ref ISO_19111_2019
  328  */
  329 class PROJ_GCC_DLL GeographicCRS : public GeodeticCRS {
  330   public:
  331     //! @cond Doxygen_Suppress
  332     PROJ_DLL ~GeographicCRS() override;
  333     //! @endcond
  334 
  335     PROJ_DLL const cs::EllipsoidalCSNNPtr &coordinateSystem() PROJ_PURE_DECL;
  336 
  337     // Non-standard
  338     PROJ_DLL static GeographicCRSNNPtr
  339     create(const util::PropertyMap &properties,
  340            const datum::GeodeticReferenceFrameNNPtr &datum,
  341            const cs::EllipsoidalCSNNPtr &cs);
  342     PROJ_DLL static GeographicCRSNNPtr
  343     create(const util::PropertyMap &properties,
  344            const datum::GeodeticReferenceFramePtr &datum,
  345            const datum::DatumEnsemblePtr &datumEnsemble,
  346            const cs::EllipsoidalCSNNPtr &cs);
  347 
  348     PROJ_DLL static const GeographicCRSNNPtr EPSG_4267; // NAD27
  349     PROJ_DLL static const GeographicCRSNNPtr EPSG_4269; // NAD83
  350     PROJ_DLL static const GeographicCRSNNPtr EPSG_4326; // WGS 84 2D
  351     PROJ_DLL static const GeographicCRSNNPtr OGC_CRS84; // CRS84 (Long, Lat)
  352     PROJ_DLL static const GeographicCRSNNPtr EPSG_4807; // NTF Paris
  353     PROJ_DLL static const GeographicCRSNNPtr EPSG_4979; // WGS 84 3D
  354 
  355     PROJ_PRIVATE :
  356         //! @cond Doxygen_Suppress
  357         PROJ_INTERNAL void
  358         addAngularUnitConvertAndAxisSwap(
  359             io::PROJStringFormatter *formatter) const;
  360 
  361     PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
  362         const override; // throw(FormattingException)
  363 
  364     PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
  365         const override; // throw(FormattingException)
  366 
  367     PROJ_DLL bool
  368     is2DPartOf3D(util::nn<const GeographicCRS *> other) PROJ_PURE_DECL;
  369 
  370     PROJ_INTERNAL bool
  371     _isEquivalentTo(const util::IComparable *other,
  372                     util::IComparable::Criterion criterion =
  373                         util::IComparable::Criterion::STRICT) const override;
  374 
  375     //! @endcond
  376 
  377   protected:
  378     PROJ_INTERNAL GeographicCRS(const datum::GeodeticReferenceFramePtr &datumIn,
  379                                 const datum::DatumEnsemblePtr &datumEnsembleIn,
  380                                 const cs::EllipsoidalCSNNPtr &csIn);
  381     PROJ_INTERNAL GeographicCRS(const GeographicCRS &other);
  382 
  383     PROJ_INTERNAL static GeographicCRSNNPtr createEPSG_4267();
  384     PROJ_INTERNAL static GeographicCRSNNPtr createEPSG_4269();
  385     PROJ_INTERNAL static GeographicCRSNNPtr createEPSG_4326();
  386     PROJ_INTERNAL static GeographicCRSNNPtr createOGC_CRS84();
  387     PROJ_INTERNAL static GeographicCRSNNPtr createEPSG_4807();
  388     PROJ_INTERNAL static GeographicCRSNNPtr createEPSG_4979();
  389 
  390     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
  391 
  392     INLINED_MAKE_SHARED
  393 
  394   private:
  395     PROJ_OPAQUE_PRIVATE_DATA
  396 
  397     GeographicCRS &operator=(const GeographicCRS &other) = delete;
  398 };
  399 
  400 // ---------------------------------------------------------------------------
  401 
  402 /** \brief A coordinate reference system having a vertical reference frame and
  403  * a one-dimensional vertical coordinate system used for recording
  404  * gravity-related heights or depths.
  405  *
  406  * Vertical CRSs make use of the direction of gravity to define the concept of
  407  * height or depth, but the relationship with gravity may not be
  408  * straightforward. If the vertical reference frame is dynamic or if the
  409  * vertical CRS has an association to a velocity model then the CRS is dynamic,
  410  * else it is static.
  411  *
  412  * \note Ellipsoidal heights cannot be captured in a vertical coordinate
  413  * reference system. They exist only as an inseparable part of a 3D coordinate
  414  * tuple defined in a geographic 3D coordinate reference system.
  415  *
  416  * \remark Implements VerticalCRS from \ref ISO_19111_2019
  417  */
  418 class PROJ_GCC_DLL VerticalCRS : virtual public SingleCRS,
  419                                  public io::IPROJStringExportable {
  420   public:
  421     //! @cond Doxygen_Suppress
  422     PROJ_DLL ~VerticalCRS() override;
  423     //! @endcond
  424 
  425     PROJ_DLL const datum::VerticalReferenceFramePtr datum() const;
  426     PROJ_DLL const cs::VerticalCSNNPtr coordinateSystem() const;
  427     PROJ_DLL const std::vector<operation::TransformationNNPtr> &
  428     geoidModel() PROJ_PURE_DECL;
  429     PROJ_DLL const std::vector<operation::PointMotionOperationNNPtr> &
  430     velocityModel() PROJ_PURE_DECL;
  431 
  432     PROJ_DLL static VerticalCRSNNPtr
  433     create(const util::PropertyMap &properties,
  434            const datum::VerticalReferenceFrameNNPtr &datumIn,
  435            const cs::VerticalCSNNPtr &csIn);
  436 
  437     PROJ_DLL static VerticalCRSNNPtr
  438     create(const util::PropertyMap &properties,
  439            const datum::VerticalReferenceFramePtr &datumIn,
  440            const datum::DatumEnsemblePtr &datumEnsembleIn,
  441            const cs::VerticalCSNNPtr &csIn);
  442 
  443     PROJ_DLL std::list<std::pair<VerticalCRSNNPtr, int>>
  444     identify(const io::AuthorityFactoryPtr &authorityFactory) const;
  445 
  446     PROJ_PRIVATE :
  447         //! @cond Doxygen_Suppress
  448         PROJ_INTERNAL void
  449         addLinearUnitConvert(io::PROJStringFormatter *formatter) const;
  450 
  451     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
  452         const override; // throw(io::FormattingException)
  453 
  454     PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
  455         const override; // throw(FormattingException)
  456 
  457     PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
  458         const override; // throw(FormattingException)
  459 
  460     PROJ_INTERNAL bool
  461     _isEquivalentTo(const util::IComparable *other,
  462                     util::IComparable::Criterion criterion =
  463                         util::IComparable::Criterion::STRICT) const override;
  464 
  465     //! @endcond
  466 
  467   protected:
  468     PROJ_INTERNAL VerticalCRS(const datum::VerticalReferenceFramePtr &datumIn,
  469                               const datum::DatumEnsemblePtr &datumEnsembleIn,
  470                               const cs::VerticalCSNNPtr &csIn);
  471     PROJ_INTERNAL VerticalCRS(const VerticalCRS &other);
  472 
  473     PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
  474     _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
  475 
  476     INLINED_MAKE_SHARED
  477 
  478     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
  479 
  480   private:
  481     PROJ_OPAQUE_PRIVATE_DATA
  482     VerticalCRS &operator=(const VerticalCRS &other) = delete;
  483 };
  484 
  485 // ---------------------------------------------------------------------------
  486 
  487 /** \brief Abstract class modelling a single coordinate reference system that
  488  * is defined through the application of a specified coordinate conversion to
  489  * the definition of a previously established single coordinate reference
  490  * system referred to as the base CRS.
  491  *
  492  * A derived coordinate reference system inherits its datum (or datum ensemble)
  493  * from its base CRS. The coordinate conversion between the base and derived
  494  * coordinate reference system is implemented using the parameters and
  495  * formula(s) specified in the definition of the coordinate conversion.
  496  *
  497  * \remark Implements DerivedCRS from \ref ISO_19111_2019
  498  */
  499 class PROJ_GCC_DLL DerivedCRS : virtual public SingleCRS {
  500   public:
  501     //! @cond Doxygen_Suppress
  502     PROJ_DLL ~DerivedCRS() override;
  503     //! @endcond
  504 
  505     PROJ_DLL const SingleCRSNNPtr &baseCRS() PROJ_PURE_DECL;
  506     PROJ_DLL const operation::ConversionNNPtr derivingConversion() const;
  507 
  508     PROJ_PRIVATE :
  509         //! @cond Doxygen_Suppress
  510         PROJ_INTERNAL const operation::ConversionNNPtr &
  511         derivingConversionRef() PROJ_PURE_DECL;
  512 
  513     PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
  514         const override; // throw(FormattingException)
  515 
  516     //! @endcond
  517 
  518   protected:
  519     PROJ_INTERNAL
  520     DerivedCRS(const SingleCRSNNPtr &baseCRSIn,
  521                const operation::ConversionNNPtr &derivingConversionIn,
  522                const cs::CoordinateSystemNNPtr &cs);
  523     PROJ_INTERNAL DerivedCRS(const DerivedCRS &other);
  524 
  525     PROJ_INTERNAL void setDerivingConversionCRS();
  526 
  527     PROJ_INTERNAL void baseExportToWKT(
  528         io::WKTFormatter *formatter, const std::string &keyword,
  529         const std::string &baseKeyword) const; // throw(FormattingException)
  530 
  531     PROJ_INTERNAL bool
  532     _isEquivalentTo(const util::IComparable *other,
  533                     util::IComparable::Criterion criterion =
  534                         util::IComparable::Criterion::STRICT) const override;
  535 
  536     PROJ_INTERNAL virtual const char *className() const = 0;
  537 
  538   private:
  539     PROJ_OPAQUE_PRIVATE_DATA
  540     DerivedCRS &operator=(const DerivedCRS &other) = delete;
  541 };
  542 
  543 /** Shared pointer of DerivedCRS */
  544 using DerivedCRSPtr = std::shared_ptr<DerivedCRS>;
  545 /** Non-null shared pointer of DerivedCRS */
  546 using DerivedCRSNNPtr = util::nn<DerivedCRSPtr>;
  547 
  548 // ---------------------------------------------------------------------------
  549 
  550 class ProjectedCRS;
  551 /** Shared pointer of ProjectedCRS */
  552 using ProjectedCRSPtr = std::shared_ptr<ProjectedCRS>;
  553 /** Non-null shared pointer of ProjectedCRS */
  554 using ProjectedCRSNNPtr = util::nn<ProjectedCRSPtr>;
  555 
  556 /** \brief A derived coordinate reference system which has a geodetic
  557  * (usually geographic) coordinate reference system as its base CRS, thereby
  558  * inheriting a geodetic reference frame, and is converted using a map
  559  * projection.
  560  *
  561  * It has a Cartesian coordinate system, usually two-dimensional but may be
  562  * three-dimensional; in the 3D case the base geographic CRSs ellipsoidal
  563  * height is passed through unchanged and forms the vertical axis of the
  564  * projected CRS's Cartesian coordinate system.
  565  *
  566  * \remark Implements ProjectedCRS from \ref ISO_19111_2019
  567  */
  568 class PROJ_GCC_DLL ProjectedCRS final : public DerivedCRS,
  569                                         public io::IPROJStringExportable {
  570   public:
  571     //! @cond Doxygen_Suppress
  572     PROJ_DLL ~ProjectedCRS() override;
  573     //! @endcond
  574 
  575     PROJ_DLL const GeodeticCRSNNPtr &baseCRS() PROJ_PURE_DECL;
  576     PROJ_DLL const cs::CartesianCSNNPtr &coordinateSystem() PROJ_PURE_DECL;
  577 
  578     PROJ_DLL static ProjectedCRSNNPtr
  579     create(const util::PropertyMap &properties,
  580            const GeodeticCRSNNPtr &baseCRSIn,
  581            const operation::ConversionNNPtr &derivingConversionIn,
  582            const cs::CartesianCSNNPtr &csIn);
  583 
  584     PROJ_DLL std::list<std::pair<ProjectedCRSNNPtr, int>>
  585     identify(const io::AuthorityFactoryPtr &authorityFactory) const;
  586 
  587     PROJ_PRIVATE :
  588         //! @cond Doxygen_Suppress
  589         PROJ_INTERNAL void
  590         addUnitConvertAndAxisSwap(io::PROJStringFormatter *formatter,
  591                                   bool axisSpecFound) const;
  592 
  593     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
  594         const override; // throw(io::FormattingException)
  595 
  596     PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
  597         const override; // throw(FormattingException)
  598 
  599     PROJ_FOR_TEST ProjectedCRSNNPtr alterParametersLinearUnit(
  600         const common::UnitOfMeasure &unit, bool convertToNewUnit) const;
  601 
  602     //! @endcond
  603 
  604   protected:
  605     PROJ_INTERNAL
  606     ProjectedCRS(const GeodeticCRSNNPtr &baseCRSIn,
  607                  const operation::ConversionNNPtr &derivingConversionIn,
  608                  const cs::CartesianCSNNPtr &csIn);
  609     PROJ_INTERNAL ProjectedCRS(const ProjectedCRS &other);
  610 
  611     PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
  612         const override; // throw(FormattingException)
  613 
  614     PROJ_INTERNAL bool
  615     _isEquivalentTo(const util::IComparable *other,
  616                     util::IComparable::Criterion criterion =
  617                         util::IComparable::Criterion::STRICT) const override;
  618 
  619     PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
  620     _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
  621 
  622     PROJ_INTERNAL const char *className() const override {
  623         return "ProjectedCRS";
  624     }
  625 
  626     INLINED_MAKE_SHARED
  627 
  628     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
  629 
  630   private:
  631     PROJ_OPAQUE_PRIVATE_DATA
  632     ProjectedCRS &operator=(const ProjectedCRS &other) = delete;
  633 };
  634 
  635 // ---------------------------------------------------------------------------
  636 
  637 class TemporalCRS;
  638 /** Shared pointer of TemporalCRS */
  639 using TemporalCRSPtr = std::shared_ptr<TemporalCRS>;
  640 /** Non-null shared pointer of TemporalCRS */
  641 using TemporalCRSNNPtr = util::nn<TemporalCRSPtr>;
  642 
  643 /** \brief A coordinate reference system associated with a temporal datum and a
  644  * one-dimensional temporal coordinate system.
  645  *
  646  * \remark Implements TemporalCRS from \ref ISO_19111_2019
  647  */
  648 class PROJ_GCC_DLL TemporalCRS : virtual public SingleCRS {
  649   public:
  650     //! @cond Doxygen_Suppress
  651     PROJ_DLL ~TemporalCRS() override;
  652     //! @endcond
  653 
  654     PROJ_DLL const datum::TemporalDatumNNPtr datum() const;
  655 
  656     PROJ_DLL const cs::TemporalCSNNPtr coordinateSystem() const;
  657 
  658     PROJ_DLL static TemporalCRSNNPtr
  659     create(const util::PropertyMap &properties,
  660            const datum::TemporalDatumNNPtr &datumIn,
  661            const cs::TemporalCSNNPtr &csIn);
  662 
  663     //! @cond Doxygen_Suppress
  664     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
  665         const override; // throw(io::FormattingException)
  666 
  667     PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
  668         const override; // throw(FormattingException)
  669 
  670     //! @endcond
  671 
  672   protected:
  673     PROJ_INTERNAL TemporalCRS(const datum::TemporalDatumNNPtr &datumIn,
  674                               const cs::TemporalCSNNPtr &csIn);
  675     PROJ_INTERNAL TemporalCRS(const TemporalCRS &other);
  676 
  677     INLINED_MAKE_SHARED
  678 
  679     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
  680 
  681     PROJ_INTERNAL bool
  682     _isEquivalentTo(const util::IComparable *other,
  683                     util::IComparable::Criterion criterion =
  684                         util::IComparable::Criterion::STRICT) const override;
  685 
  686   private:
  687     PROJ_OPAQUE_PRIVATE_DATA
  688     TemporalCRS &operator=(const TemporalCRS &other) = delete;
  689 };
  690 
  691 // ---------------------------------------------------------------------------
  692 
  693 class EngineeringCRS;
  694 /** Shared pointer of EngineeringCRS */
  695 using EngineeringCRSPtr = std::shared_ptr<EngineeringCRS>;
  696 /** Non-null shared pointer of EngineeringCRS */
  697 using EngineeringCRSNNPtr = util::nn<EngineeringCRSPtr>;
  698 
  699 /** \brief Contextually local coordinate reference system associated with an
  700  * engineering datum.
  701  *
  702  * It is applied either to activities on or near the surface of the Earth
  703  * without geodetic corrections, or on moving platforms such as road vehicles,
  704  * vessels, aircraft or spacecraft, or as the internal CRS of an image.
  705  *
  706  * In \ref WKT2, it maps to a ENGINEERINGCRS / ENGCRS keyword. In \ref WKT1,
  707  * it maps to a LOCAL_CS keyword.
  708  *
  709  * \remark Implements EngineeringCRS from \ref ISO_19111_2019
  710  */
  711 class PROJ_GCC_DLL EngineeringCRS : virtual public SingleCRS {
  712   public:
  713     //! @cond Doxygen_Suppress
  714     PROJ_DLL ~EngineeringCRS() override;
  715     //! @endcond
  716 
  717     PROJ_DLL const datum::EngineeringDatumNNPtr datum() const;
  718 
  719     PROJ_DLL static EngineeringCRSNNPtr
  720     create(const util::PropertyMap &properties,
  721            const datum::EngineeringDatumNNPtr &datumIn,
  722            const cs::CoordinateSystemNNPtr &csIn);
  723 
  724     //! @cond Doxygen_Suppress
  725     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
  726         const override; // throw(io::FormattingException)
  727 
  728     PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
  729         const override; // throw(FormattingException)
  730 
  731     //! @endcond
  732 
  733   protected:
  734     PROJ_INTERNAL EngineeringCRS(const datum::EngineeringDatumNNPtr &datumIn,
  735                                  const cs::CoordinateSystemNNPtr &csIn);
  736     PROJ_INTERNAL EngineeringCRS(const EngineeringCRS &other);
  737 
  738     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
  739 
  740     PROJ_INTERNAL bool
  741     _isEquivalentTo(const util::IComparable *other,
  742                     util::IComparable::Criterion criterion =
  743                         util::IComparable::Criterion::STRICT) const override;
  744 
  745     INLINED_MAKE_SHARED
  746 
  747   private:
  748     PROJ_OPAQUE_PRIVATE_DATA
  749     EngineeringCRS &operator=(const EngineeringCRS &other) = delete;
  750 };
  751 
  752 // ---------------------------------------------------------------------------
  753 
  754 class ParametricCRS;
  755 /** Shared pointer of ParametricCRS */
  756 using ParametricCRSPtr = std::shared_ptr<ParametricCRS>;
  757 /** Non-null shared pointer of ParametricCRS */
  758 using ParametricCRSNNPtr = util::nn<ParametricCRSPtr>;
  759 
  760 /** \brief Contextually local coordinate reference system associated with an
  761  * engineering datum.
  762  *
  763  * This is applied either to activities on or near the surface of the Earth
  764  * without geodetic corrections, or on moving platforms such as road vehicles
  765  * vessels, aircraft or spacecraft, or as the internal CRS of an image.
  766  *
  767  * \remark Implements ParametricCRS from \ref ISO_19111_2019
  768  */
  769 class PROJ_GCC_DLL ParametricCRS : virtual public SingleCRS {
  770   public:
  771     //! @cond Doxygen_Suppress
  772     PROJ_DLL ~ParametricCRS() override;
  773     //! @endcond
  774 
  775     PROJ_DLL const datum::ParametricDatumNNPtr datum() const;
  776 
  777     PROJ_DLL const cs::ParametricCSNNPtr coordinateSystem() const;
  778 
  779     PROJ_DLL static ParametricCRSNNPtr
  780     create(const util::PropertyMap &properties,
  781            const datum::ParametricDatumNNPtr &datumIn,
  782            const cs::ParametricCSNNPtr &csIn);
  783 
  784     //! @cond Doxygen_Suppress
  785     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
  786         const override; // throw(io::FormattingException)
  787 
  788     PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
  789         const override; // throw(FormattingException)
  790 
  791     //! @endcond
  792 
  793   protected:
  794     PROJ_INTERNAL ParametricCRS(const datum::ParametricDatumNNPtr &datumIn,
  795                                 const cs::ParametricCSNNPtr &csIn);
  796     PROJ_INTERNAL ParametricCRS(const ParametricCRS &other);
  797 
  798     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
  799 
  800     PROJ_INTERNAL bool
  801     _isEquivalentTo(const util::IComparable *other,
  802                     util::IComparable::Criterion criterion =
  803                         util::IComparable::Criterion::STRICT) const override;
  804 
  805     INLINED_MAKE_SHARED
  806 
  807   private:
  808     PROJ_OPAQUE_PRIVATE_DATA
  809     ParametricCRS &operator=(const ParametricCRS &other) = delete;
  810 };
  811 
  812 // ---------------------------------------------------------------------------
  813 
  814 class CompoundCRS;
  815 /** Shared pointer of CompoundCRS */
  816 using CompoundCRSPtr = std::shared_ptr<CompoundCRS>;
  817 /** Non-null shared pointer of CompoundCRS */
  818 using CompoundCRSNNPtr = util::nn<CompoundCRSPtr>;
  819 
  820 /** \brief A coordinate reference system describing the position of points
  821  * through two or more independent single coordinate reference systems.
  822  *
  823  * \note Two coordinate reference systems are independent of each other
  824  * if coordinate values in one cannot be converted or transformed into
  825  * coordinate values in the other.
  826  *
  827  * \note As a departure to \ref ISO_19111_2019, we allow to build a CompoundCRS
  828  * from CRS objects, whereas ISO19111:2019 restricts the components to
  829  * SingleCRS.
  830  *
  831  * \remark Implements CompoundCRS from \ref ISO_19111_2019
  832  */
  833 class PROJ_GCC_DLL CompoundCRS final : public CRS,
  834                                        public io::IPROJStringExportable {
  835   public:
  836     //! @cond Doxygen_Suppress
  837     PROJ_DLL ~CompoundCRS() override;
  838     //! @endcond
  839 
  840     PROJ_DLL const std::vector<CRSNNPtr> &
  841     componentReferenceSystems() PROJ_PURE_DECL;
  842 
  843     PROJ_DLL std::list<std::pair<CompoundCRSNNPtr, int>>
  844     identify(const io::AuthorityFactoryPtr &authorityFactory) const;
  845 
  846     //! @cond Doxygen_Suppress
  847     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
  848         const override; // throw(io::FormattingException)
  849     //! @endcond
  850 
  851     PROJ_DLL static CompoundCRSNNPtr
  852     create(const util::PropertyMap &properties,
  853            const std::vector<CRSNNPtr> &components);
  854 
  855   protected:
  856     // relaxed: standard say SingleCRSNNPtr
  857     PROJ_INTERNAL explicit CompoundCRS(const std::vector<CRSNNPtr> &components);
  858     PROJ_INTERNAL CompoundCRS(const CompoundCRS &other);
  859 
  860     PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
  861         const override; // throw(FormattingException)
  862 
  863     PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
  864         const override; // throw(FormattingException)
  865 
  866     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
  867 
  868     PROJ_INTERNAL bool
  869     _isEquivalentTo(const util::IComparable *other,
  870                     util::IComparable::Criterion criterion =
  871                         util::IComparable::Criterion::STRICT) const override;
  872 
  873     PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
  874     _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
  875 
  876     INLINED_MAKE_SHARED
  877 
  878   private:
  879     PROJ_OPAQUE_PRIVATE_DATA
  880     CompoundCRS &operator=(const CompoundCRS &other) = delete;
  881 };
  882 
  883 // ---------------------------------------------------------------------------
  884 
  885 /** \brief A coordinate reference system with an associated transformation to
  886  * a target/hub CRS.
  887  *
  888  * The definition of a CRS is not dependent upon any relationship to an
  889  * independent CRS. However in an implementation that merges datasets
  890  * referenced to differing CRSs, it is sometimes useful to associate the
  891  * definition of the transformation that has been used with the CRS definition.
  892  * This facilitates the interrelationship of CRS by concatenating
  893  * transformations via a common or hub CRS. This is sometimes referred to as
  894  * "early-binding". \ref WKT2 permits the association of an abridged coordinate
  895  * transformation description with a coordinate reference system description in
  896  * a single text string. In a BoundCRS, the abridged coordinate transformation
  897  * is applied to the source CRS with the target CRS being the common or hub
  898  * system.
  899  *
  900  * Coordinates referring to a BoundCRS are expressed into its source/base CRS.
  901  *
  902  * This abstraction can for example model the concept of TOWGS84 datum shift
  903  * present in \ref WKT1.
  904  *
  905  * \note Contrary to other CRS classes of this package, there is no
  906  * \ref ISO_19111_2019 modelling of a BoundCRS.
  907  *
  908  * \remark Implements BoundCRS from \ref WKT2
  909  */
  910 class PROJ_GCC_DLL BoundCRS final : public CRS,
  911                                     public io::IPROJStringExportable {
  912   public:
  913     //! @cond Doxygen_Suppress
  914     PROJ_DLL ~BoundCRS() override;
  915     //! @endcond
  916 
  917     PROJ_DLL const CRSNNPtr &baseCRS() PROJ_PURE_DECL;
  918     PROJ_DLL CRSNNPtr baseCRSWithCanonicalBoundCRS() const;
  919 
  920     PROJ_DLL const CRSNNPtr &hubCRS() PROJ_PURE_DECL;
  921     PROJ_DLL const operation::TransformationNNPtr &
  922     transformation() PROJ_PURE_DECL;
  923 
  924     //! @cond Doxygen_Suppress
  925     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
  926         const override; // throw(io::FormattingException)
  927     //! @endcond
  928 
  929     PROJ_DLL static BoundCRSNNPtr
  930     create(const CRSNNPtr &baseCRSIn, const CRSNNPtr &hubCRSIn,
  931            const operation::TransformationNNPtr &transformationIn);
  932 
  933     PROJ_DLL static BoundCRSNNPtr
  934     createFromTOWGS84(const CRSNNPtr &baseCRSIn,
  935                       const std::vector<double> &TOWGS84Parameters);
  936 
  937     PROJ_DLL static BoundCRSNNPtr
  938     createFromNadgrids(const CRSNNPtr &baseCRSIn, const std::string &filename);
  939 
  940   protected:
  941     PROJ_INTERNAL
  942     BoundCRS(const CRSNNPtr &baseCRSIn, const CRSNNPtr &hubCRSIn,
  943              const operation::TransformationNNPtr &transformationIn);
  944     PROJ_INTERNAL BoundCRS(const BoundCRS &other);
  945 
  946     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
  947 
  948     PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
  949         const override; // throw(FormattingException)
  950 
  951     PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
  952         const override; // throw(FormattingException)
  953 
  954     PROJ_INTERNAL bool
  955     _isEquivalentTo(const util::IComparable *other,
  956                     util::IComparable::Criterion criterion =
  957                         util::IComparable::Criterion::STRICT) const override;
  958 
  959     PROJ_INTERNAL BoundCRSNNPtr shallowCloneAsBoundCRS() const;
  960     PROJ_INTERNAL bool isTOWGS84Compatible() const;
  961     PROJ_INTERNAL std::string getHDatumPROJ4GRIDS() const;
  962     PROJ_INTERNAL std::string getVDatumPROJ4GRIDS() const;
  963 
  964     PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
  965     _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
  966 
  967     INLINED_MAKE_SHARED
  968 
  969   private:
  970     PROJ_OPAQUE_PRIVATE_DATA
  971     BoundCRS &operator=(const BoundCRS &other) = delete;
  972 };
  973 
  974 // ---------------------------------------------------------------------------
  975 
  976 class DerivedGeodeticCRS;
  977 /** Shared pointer of DerivedGeodeticCRS */
  978 using DerivedGeodeticCRSPtr = std::shared_ptr<DerivedGeodeticCRS>;
  979 /** Non-null shared pointer of DerivedGeodeticCRS */
  980 using DerivedGeodeticCRSNNPtr = util::nn<DerivedGeodeticCRSPtr>;
  981 
  982 /** \brief A derived coordinate reference system which has either a geodetic
  983  * or a geographic coordinate reference system as its base CRS, thereby
  984  * inheriting a geodetic reference frame, and associated with a 3D Cartesian
  985  * or spherical coordinate system.
  986  *
  987  * \remark Implements DerivedGeodeticCRS from \ref ISO_19111_2019
  988  */
  989 class PROJ_GCC_DLL DerivedGeodeticCRS final : public GeodeticCRS,
  990                                               public DerivedCRS {
  991   public:
  992     //! @cond Doxygen_Suppress
  993     PROJ_DLL ~DerivedGeodeticCRS() override;
  994     //! @endcond
  995 
  996     PROJ_DLL const GeodeticCRSNNPtr baseCRS() const;
  997 
  998     PROJ_DLL static DerivedGeodeticCRSNNPtr
  999     create(const util::PropertyMap &properties,
 1000            const GeodeticCRSNNPtr &baseCRSIn,
 1001            const operation::ConversionNNPtr &derivingConversionIn,
 1002            const cs::CartesianCSNNPtr &csIn);
 1003 
 1004     PROJ_DLL static DerivedGeodeticCRSNNPtr
 1005     create(const util::PropertyMap &properties,
 1006            const GeodeticCRSNNPtr &baseCRSIn,
 1007            const operation::ConversionNNPtr &derivingConversionIn,
 1008            const cs::SphericalCSNNPtr &csIn);
 1009 
 1010     //! @cond Doxygen_Suppress
 1011     void _exportToWKT(io::WKTFormatter *formatter)
 1012         const override; // throw(io::FormattingException)
 1013 
 1014     PROJ_INTERNAL void
 1015     _exportToJSON(io::JSONFormatter *formatter) const override {
 1016         return DerivedCRS::_exportToJSON(formatter);
 1017     }
 1018 
 1019     //! @endcond
 1020 
 1021   protected:
 1022     PROJ_INTERNAL
 1023     DerivedGeodeticCRS(const GeodeticCRSNNPtr &baseCRSIn,
 1024                        const operation::ConversionNNPtr &derivingConversionIn,
 1025                        const cs::CartesianCSNNPtr &csIn);
 1026     PROJ_INTERNAL
 1027     DerivedGeodeticCRS(const GeodeticCRSNNPtr &baseCRSIn,
 1028                        const operation::ConversionNNPtr &derivingConversionIn,
 1029                        const cs::SphericalCSNNPtr &csIn);
 1030     PROJ_INTERNAL DerivedGeodeticCRS(const DerivedGeodeticCRS &other);
 1031 
 1032     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
 1033 
 1034     PROJ_INTERNAL bool
 1035     _isEquivalentTo(const util::IComparable *other,
 1036                     util::IComparable::Criterion criterion =
 1037                         util::IComparable::Criterion::STRICT) const override;
 1038 
 1039     PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
 1040     _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
 1041 
 1042     // cppcheck-suppress functionStatic
 1043     PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
 1044         const override; // throw(FormattingException)
 1045 
 1046     PROJ_INTERNAL const char *className() const override {
 1047         return "DerivedGeodeticCRS";
 1048     }
 1049 
 1050     INLINED_MAKE_SHARED
 1051 
 1052   private:
 1053     PROJ_OPAQUE_PRIVATE_DATA
 1054     DerivedGeodeticCRS &operator=(const DerivedGeodeticCRS &other) = delete;
 1055 };
 1056 
 1057 // ---------------------------------------------------------------------------
 1058 
 1059 class DerivedGeographicCRS;
 1060 /** Shared pointer of DerivedGeographicCRS */
 1061 using DerivedGeographicCRSPtr = std::shared_ptr<DerivedGeographicCRS>;
 1062 /** Non-null shared pointer of DerivedGeographicCRS */
 1063 using DerivedGeographicCRSNNPtr = util::nn<DerivedGeographicCRSPtr>;
 1064 
 1065 /** \brief A derived coordinate reference system which has either a geodetic or
 1066  * a geographic coordinate reference system as its base CRS, thereby inheriting
 1067  * a geodetic reference frame, and an ellipsoidal coordinate system.
 1068  *
 1069  * A derived geographic CRS can be based on a geodetic CRS only if that
 1070  * geodetic CRS definition includes an ellipsoid.
 1071  *
 1072  * \remark Implements DerivedGeographicCRS from \ref ISO_19111_2019
 1073  */
 1074 class PROJ_GCC_DLL DerivedGeographicCRS final : public GeographicCRS,
 1075                                                 public DerivedCRS {
 1076   public:
 1077     //! @cond Doxygen_Suppress
 1078     PROJ_DLL ~DerivedGeographicCRS() override;
 1079     //! @endcond
 1080 
 1081     PROJ_DLL const GeodeticCRSNNPtr baseCRS() const;
 1082 
 1083     PROJ_DLL static DerivedGeographicCRSNNPtr
 1084     create(const util::PropertyMap &properties,
 1085            const GeodeticCRSNNPtr &baseCRSIn,
 1086            const operation::ConversionNNPtr &derivingConversionIn,
 1087            const cs::EllipsoidalCSNNPtr &csIn);
 1088 
 1089     //! @cond Doxygen_Suppress
 1090     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
 1091         const override; // throw(io::FormattingException)
 1092 
 1093     PROJ_INTERNAL void
 1094     _exportToJSON(io::JSONFormatter *formatter) const override {
 1095         return DerivedCRS::_exportToJSON(formatter);
 1096     }
 1097 
 1098     //! @endcond
 1099 
 1100   protected:
 1101     PROJ_INTERNAL
 1102     DerivedGeographicCRS(const GeodeticCRSNNPtr &baseCRSIn,
 1103                          const operation::ConversionNNPtr &derivingConversionIn,
 1104                          const cs::EllipsoidalCSNNPtr &csIn);
 1105     PROJ_INTERNAL DerivedGeographicCRS(const DerivedGeographicCRS &other);
 1106 
 1107     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
 1108 
 1109     PROJ_INTERNAL bool
 1110     _isEquivalentTo(const util::IComparable *other,
 1111                     util::IComparable::Criterion criterion =
 1112                         util::IComparable::Criterion::STRICT) const override;
 1113 
 1114     PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
 1115     _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
 1116 
 1117     PROJ_INTERNAL const char *className() const override {
 1118         return "DerivedGeographicCRS";
 1119     }
 1120 
 1121     // cppcheck-suppress functionStatic
 1122     PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
 1123         const override; // throw(FormattingException)
 1124 
 1125     INLINED_MAKE_SHARED
 1126 
 1127   private:
 1128     PROJ_OPAQUE_PRIVATE_DATA
 1129     DerivedGeographicCRS &operator=(const DerivedGeographicCRS &other) = delete;
 1130 };
 1131 
 1132 // ---------------------------------------------------------------------------
 1133 
 1134 class DerivedProjectedCRS;
 1135 /** Shared pointer of DerivedProjectedCRS */
 1136 using DerivedProjectedCRSPtr = std::shared_ptr<DerivedProjectedCRS>;
 1137 /** Non-null shared pointer of DerivedProjectedCRS */
 1138 using DerivedProjectedCRSNNPtr = util::nn<DerivedProjectedCRSPtr>;
 1139 
 1140 /** \brief A derived coordinate reference system which has a projected
 1141  * coordinate reference system as its base CRS, thereby inheriting a geodetic
 1142  * reference frame, but also inheriting the distortion characteristics of the
 1143  * base projected CRS.
 1144  *
 1145  * A DerivedProjectedCRS is not a ProjectedCRS.
 1146  *
 1147  * \remark Implements DerivedProjectedCRS from \ref ISO_19111_2019
 1148  */
 1149 class PROJ_GCC_DLL DerivedProjectedCRS final : public DerivedCRS {
 1150   public:
 1151     //! @cond Doxygen_Suppress
 1152     PROJ_DLL ~DerivedProjectedCRS() override;
 1153     //! @endcond
 1154 
 1155     PROJ_DLL const ProjectedCRSNNPtr baseCRS() const;
 1156 
 1157     PROJ_DLL static DerivedProjectedCRSNNPtr
 1158     create(const util::PropertyMap &properties,
 1159            const ProjectedCRSNNPtr &baseCRSIn,
 1160            const operation::ConversionNNPtr &derivingConversionIn,
 1161            const cs::CoordinateSystemNNPtr &csIn);
 1162 
 1163     //! @cond Doxygen_Suppress
 1164     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
 1165         const override; // throw(io::FormattingException)
 1166                         //! @endcond
 1167 
 1168   protected:
 1169     PROJ_INTERNAL
 1170     DerivedProjectedCRS(const ProjectedCRSNNPtr &baseCRSIn,
 1171                         const operation::ConversionNNPtr &derivingConversionIn,
 1172                         const cs::CoordinateSystemNNPtr &csIn);
 1173     PROJ_INTERNAL DerivedProjectedCRS(const DerivedProjectedCRS &other);
 1174 
 1175     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
 1176 
 1177     PROJ_INTERNAL bool
 1178     _isEquivalentTo(const util::IComparable *other,
 1179                     util::IComparable::Criterion criterion =
 1180                         util::IComparable::Criterion::STRICT) const override;
 1181 
 1182     PROJ_INTERNAL const char *className() const override {
 1183         return "DerivedProjectedCRS";
 1184     }
 1185 
 1186     INLINED_MAKE_SHARED
 1187 
 1188   private:
 1189     PROJ_OPAQUE_PRIVATE_DATA
 1190     DerivedProjectedCRS &operator=(const DerivedProjectedCRS &other) = delete;
 1191 };
 1192 
 1193 // ---------------------------------------------------------------------------
 1194 
 1195 class DerivedVerticalCRS;
 1196 /** Shared pointer of DerivedVerticalCRS */
 1197 using DerivedVerticalCRSPtr = std::shared_ptr<DerivedVerticalCRS>;
 1198 /** Non-null shared pointer of DerivedVerticalCRS */
 1199 using DerivedVerticalCRSNNPtr = util::nn<DerivedVerticalCRSPtr>;
 1200 
 1201 /** \brief A derived coordinate reference system which has a vertical
 1202  * coordinate reference system as its base CRS, thereby inheriting a vertical
 1203  * reference frame, and a vertical coordinate system.
 1204  *
 1205  * \remark Implements DerivedVerticalCRS from \ref ISO_19111_2019
 1206  */
 1207 class PROJ_GCC_DLL DerivedVerticalCRS final : public VerticalCRS,
 1208                                               public DerivedCRS {
 1209   public:
 1210     //! @cond Doxygen_Suppress
 1211     PROJ_DLL ~DerivedVerticalCRS() override;
 1212     //! @endcond
 1213 
 1214     PROJ_DLL const VerticalCRSNNPtr baseCRS() const;
 1215 
 1216     PROJ_DLL static DerivedVerticalCRSNNPtr
 1217     create(const util::PropertyMap &properties,
 1218            const VerticalCRSNNPtr &baseCRSIn,
 1219            const operation::ConversionNNPtr &derivingConversionIn,
 1220            const cs::VerticalCSNNPtr &csIn);
 1221 
 1222     //! @cond Doxygen_Suppress
 1223     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
 1224         const override; // throw(io::FormattingException)
 1225 
 1226     PROJ_INTERNAL void
 1227     _exportToJSON(io::JSONFormatter *formatter) const override {
 1228         return DerivedCRS::_exportToJSON(formatter);
 1229     }
 1230 
 1231     //! @endcond
 1232 
 1233   protected:
 1234     PROJ_INTERNAL
 1235     DerivedVerticalCRS(const VerticalCRSNNPtr &baseCRSIn,
 1236                        const operation::ConversionNNPtr &derivingConversionIn,
 1237                        const cs::VerticalCSNNPtr &csIn);
 1238     PROJ_INTERNAL DerivedVerticalCRS(const DerivedVerticalCRS &other);
 1239 
 1240     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
 1241 
 1242     PROJ_INTERNAL bool
 1243     _isEquivalentTo(const util::IComparable *other,
 1244                     util::IComparable::Criterion criterion =
 1245                         util::IComparable::Criterion::STRICT) const override;
 1246 
 1247     PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
 1248     _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
 1249 
 1250     PROJ_INTERNAL const char *className() const override {
 1251         return "DerivedVerticalCRS";
 1252     }
 1253 
 1254     // cppcheck-suppress functionStatic
 1255     PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
 1256         const override; // throw(FormattingException)
 1257 
 1258     INLINED_MAKE_SHARED
 1259 
 1260   private:
 1261     PROJ_OPAQUE_PRIVATE_DATA
 1262     DerivedVerticalCRS &operator=(const DerivedVerticalCRS &other) = delete;
 1263 };
 1264 
 1265 // ---------------------------------------------------------------------------
 1266 
 1267 /** \brief Template representing a derived coordinate reference system.
 1268  */
 1269 template <class DerivedCRSTraits>
 1270 class PROJ_GCC_DLL DerivedCRSTemplate final : public DerivedCRSTraits::BaseType,
 1271                                               public DerivedCRS {
 1272   protected:
 1273     /** Base type */
 1274     typedef typename DerivedCRSTraits::BaseType BaseType;
 1275     /** CSType */
 1276     typedef typename DerivedCRSTraits::CSType CSType;
 1277 
 1278   public:
 1279     //! @cond Doxygen_Suppress
 1280     PROJ_DLL ~DerivedCRSTemplate() override;
 1281     //! @endcond
 1282 
 1283     /** Non-null shared pointer of DerivedCRSTemplate */
 1284     typedef typename util::nn<std::shared_ptr<DerivedCRSTemplate>> NNPtr;
 1285     /** Non-null shared pointer of BaseType */
 1286     typedef util::nn<std::shared_ptr<BaseType>> BaseNNPtr;
 1287     /** Non-null shared pointer of CSType */
 1288     typedef util::nn<std::shared_ptr<CSType>> CSNNPtr;
 1289 
 1290     /** \brief Return the base CRS of a DerivedCRSTemplate.
 1291      *
 1292      * @return the base CRS.
 1293      */
 1294     PROJ_DLL const BaseNNPtr baseCRS() const;
 1295 
 1296     /** \brief Instantiate a DerivedCRSTemplate from a base CRS, a deriving
 1297      * conversion and a cs::CoordinateSystem.
 1298      *
 1299      * @param properties See \ref general_properties.
 1300      * At minimum the name should be defined.
 1301      * @param baseCRSIn base CRS.
 1302      * @param derivingConversionIn the deriving conversion from the base CRS to
 1303      * this
 1304      * CRS.
 1305      * @param csIn the coordinate system.
 1306      * @return new DerivedCRSTemplate.
 1307      */
 1308     PROJ_DLL static NNPtr
 1309     create(const util::PropertyMap &properties, const BaseNNPtr &baseCRSIn,
 1310            const operation::ConversionNNPtr &derivingConversionIn,
 1311            const CSNNPtr &csIn);
 1312 
 1313     //! @cond Doxygen_Suppress
 1314     PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
 1315         const override; // throw(io::FormattingException)
 1316 
 1317     PROJ_INTERNAL void
 1318     _exportToJSON(io::JSONFormatter *formatter) const override {
 1319         return DerivedCRS::_exportToJSON(formatter);
 1320     }
 1321     //! @endcond
 1322 
 1323   protected:
 1324     PROJ_INTERNAL
 1325     DerivedCRSTemplate(const BaseNNPtr &baseCRSIn,
 1326                        const operation::ConversionNNPtr &derivingConversionIn,
 1327                        const CSNNPtr &csIn);
 1328     PROJ_INTERNAL DerivedCRSTemplate(const DerivedCRSTemplate &other);
 1329 
 1330     PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
 1331 
 1332     PROJ_INTERNAL bool
 1333     _isEquivalentTo(const util::IComparable *other,
 1334                     util::IComparable::Criterion criterion =
 1335                         util::IComparable::Criterion::STRICT) const override;
 1336 
 1337     PROJ_INTERNAL const char *className() const override;
 1338 
 1339     INLINED_MAKE_SHARED
 1340 
 1341   private:
 1342     struct PROJ_INTERNAL Private;
 1343     std::unique_ptr<Private> d;
 1344 
 1345     DerivedCRSTemplate &operator=(const DerivedCRSTemplate &other) = delete;
 1346 };
 1347 
 1348 // ---------------------------------------------------------------------------
 1349 
 1350 //! @cond Doxygen_Suppress
 1351 struct PROJ_GCC_DLL DerivedEngineeringCRSTraits {
 1352     typedef EngineeringCRS BaseType;
 1353     typedef cs::CoordinateSystem CSType;
 1354     // old x86_64-w64-mingw32-g++ has issues with static variables. use method
 1355     // instead
 1356     inline static const std::string &CRSName();
 1357     inline static const std::string &WKTKeyword();
 1358     inline static const std::string &WKTBaseKeyword();
 1359     static const bool wkt2_2018_only = true;
 1360 };
 1361 //! @endcond
 1362 
 1363 /** \brief A derived coordinate reference system which has an engineering
 1364  * coordinate reference system as its base CRS, thereby inheriting an
 1365  * engineering datum, and is associated with one of the coordinate system
 1366  * types for an EngineeringCRS
 1367  *
 1368  * \remark Implements DerivedEngineeringCRS from \ref ISO_19111_2019
 1369  */
 1370 #ifdef DOXYGEN_ENABLED
 1371 class DerivedEngineeringCRS
 1372     : public DerivedCRSTemplate<DerivedEngineeringCRSTraits> {};
 1373 #else
 1374 using DerivedEngineeringCRS = DerivedCRSTemplate<DerivedEngineeringCRSTraits>;
 1375 #endif
 1376 
 1377 #ifndef DO_NOT_DEFINE_EXTERN_DERIVED_CRS_TEMPLATE
 1378 extern template class DerivedCRSTemplate<DerivedEngineeringCRSTraits>;
 1379 #endif
 1380 
 1381 /** Shared pointer of DerivedEngineeringCRS */
 1382 using DerivedEngineeringCRSPtr = std::shared_ptr<DerivedEngineeringCRS>;
 1383 /** Non-null shared pointer of DerivedEngineeringCRS */
 1384 using DerivedEngineeringCRSNNPtr = util::nn<DerivedEngineeringCRSPtr>;
 1385 
 1386 // ---------------------------------------------------------------------------
 1387 
 1388 //! @cond Doxygen_Suppress
 1389 struct PROJ_GCC_DLL DerivedParametricCRSTraits {
 1390     typedef ParametricCRS BaseType;
 1391     typedef cs::ParametricCS CSType;
 1392     // old x86_64-w64-mingw32-g++ has issues with static variables. use method
 1393     // instead
 1394     inline static const std::string &CRSName();
 1395     inline static const std::string &WKTKeyword();
 1396     inline static const std::string &WKTBaseKeyword();
 1397     static const bool wkt2_2018_only = false;
 1398 };
 1399 //! @endcond
 1400 
 1401 /** \brief A derived coordinate reference system which has a parametric
 1402  * coordinate reference system as its base CRS, thereby inheriting a parametric
 1403  * datum, and a parametric coordinate system.
 1404  *
 1405  * \remark Implements DerivedParametricCRS from \ref ISO_19111_2019
 1406  */
 1407 #ifdef DOXYGEN_ENABLED
 1408 class DerivedParametricCRS
 1409     : public DerivedCRSTemplate<DerivedParametricCRSTraits> {};
 1410 #else
 1411 using DerivedParametricCRS = DerivedCRSTemplate<DerivedParametricCRSTraits>;
 1412 #endif
 1413 
 1414 #ifndef DO_NOT_DEFINE_EXTERN_DERIVED_CRS_TEMPLATE
 1415 extern template class DerivedCRSTemplate<DerivedParametricCRSTraits>;
 1416 #endif
 1417 
 1418 /** Shared pointer of DerivedParametricCRS */
 1419 using DerivedParametricCRSPtr = std::shared_ptr<DerivedParametricCRS>;
 1420 /** Non-null shared pointer of DerivedParametricCRS */
 1421 using DerivedParametricCRSNNPtr = util::nn<DerivedParametricCRSPtr>;
 1422 
 1423 // ---------------------------------------------------------------------------
 1424 
 1425 //! @cond Doxygen_Suppress
 1426 struct PROJ_GCC_DLL DerivedTemporalCRSTraits {
 1427     typedef TemporalCRS BaseType;
 1428     typedef cs::TemporalCS CSType;
 1429     // old x86_64-w64-mingw32-g++ has issues with static variables. use method
 1430     // instead
 1431     inline static const std::string &CRSName();
 1432     inline static const std::string &WKTKeyword();
 1433     inline static const std::string &WKTBaseKeyword();
 1434     static const bool wkt2_2018_only = false;
 1435 };
 1436 //! @endcond
 1437 
 1438 /** \brief A derived coordinate reference system which has a temporal
 1439  * coordinate reference system as its base CRS, thereby inheriting a temporal
 1440  * datum, and a temporal coordinate system.
 1441  *
 1442  * \remark Implements DerivedTemporalCRS from \ref ISO_19111_2019
 1443  */
 1444 #ifdef DOXYGEN_ENABLED
 1445 class DerivedTemporalCRS : public DerivedCRSTemplate<DerivedTemporalCRSTraits> {
 1446 };
 1447 #else
 1448 using DerivedTemporalCRS = DerivedCRSTemplate<DerivedTemporalCRSTraits>;
 1449 #endif
 1450 
 1451 #ifndef DO_NOT_DEFINE_EXTERN_DERIVED_CRS_TEMPLATE
 1452 extern template class DerivedCRSTemplate<DerivedTemporalCRSTraits>;
 1453 #endif
 1454 
 1455 /** Shared pointer of DerivedTemporalCRS */
 1456 using DerivedTemporalCRSPtr = std::shared_ptr<DerivedTemporalCRS>;
 1457 /** Non-null shared pointer of DerivedTemporalCRS */
 1458 using DerivedTemporalCRSNNPtr = util::nn<DerivedTemporalCRSPtr>;
 1459 
 1460 // ---------------------------------------------------------------------------
 1461 
 1462 } // namespace crs
 1463 
 1464 NS_PROJ_END
 1465 
 1466 #endif //  CRS_HH_INCLUDED