aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-11-14 17:40:42 +0100
committerEven Rouault <even.rouault@spatialys.com>2018-11-14 22:48:29 +0100
commitd928db15d53805d9b728b440079756081961c536 (patch)
treee862a961d26bedb34c58e4f28ef0bdeedb5f3225 /include
parent330e8bf686f9c4524075ca1ff50cbca6c9e091da (diff)
downloadPROJ-d928db15d53805d9b728b440079756081961c536.tar.gz
PROJ-d928db15d53805d9b728b440079756081961c536.zip
Implement RFC 2: Initial integration of "GDAL SRS barn" work
This work mostly consists of: - a C++ implementation of the ISO-19111:2018 / OGC Topic 2 "Referencing by coordinates" classes to represent Datums, Coordinate systems, CRSs (Coordinate Reference Systems) and Coordinate Operations. - methods to convert between this C++ modeling and WKT1, WKT2 and PROJ string representations of those objects - management and query of a SQLite3 database of CRS and Coordinate Operation definition - a C API binding part of those capabilities This is all-in-one squashed commit of the work of https://github.com/OSGeo/proj.4/pull/1040
Diffstat (limited to 'include')
-rw-r--r--include/CMakeLists.txt1
-rw-r--r--include/Makefile.am3
-rw-r--r--include/proj/CMakeLists.txt7
-rw-r--r--include/proj/Makefile.am8
-rw-r--r--include/proj/common.hpp445
-rw-r--r--include/proj/coordinateoperation.hpp1764
-rw-r--r--include/proj/coordinatesystem.hpp701
-rw-r--r--include/proj/crs.hpp1361
-rw-r--r--include/proj/datum.hpp779
-rw-r--r--include/proj/internal/Makefile.am8
-rw-r--r--include/proj/internal/coordinateoperation_constants.hpp898
-rw-r--r--include/proj/internal/coordinateoperation_internal.hpp274
-rw-r--r--include/proj/internal/coordinatesystem_internal.hpp104
-rw-r--r--include/proj/internal/esri_projection_mappings.hpp887
-rw-r--r--include/proj/internal/internal.hpp190
-rw-r--r--include/proj/internal/io_internal.hpp163
-rw-r--r--include/proj/internal/lru_cache.hpp223
-rw-r--r--include/proj/io.hpp970
-rw-r--r--include/proj/metadata.hpp458
-rw-r--r--include/proj/nn.hpp385
-rw-r--r--include/proj/util.hpp752
21 files changed, 10381 insertions, 0 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
new file mode 100644
index 00000000..648a0650
--- /dev/null
+++ b/include/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(proj)
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644
index 00000000..ba96cf80
--- /dev/null
+++ b/include/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = proj
+
+EXTRA_DIST = CMakeLists.txt
diff --git a/include/proj/CMakeLists.txt b/include/proj/CMakeLists.txt
new file mode 100644
index 00000000..d112cf74
--- /dev/null
+++ b/include/proj/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(installdest include/proj)
+
+install(
+ FILES util.hpp metadata.hpp common.hpp crs.hpp datum.hpp
+ coordinatesystem.hpp coordinateoperation.hpp io.hpp nn.hpp
+ DESTINATION ${installdest}
+)
diff --git a/include/proj/Makefile.am b/include/proj/Makefile.am
new file mode 100644
index 00000000..e5ae5aed
--- /dev/null
+++ b/include/proj/Makefile.am
@@ -0,0 +1,8 @@
+EXTRA_DIST = CMakeLists.txt
+
+SUBDIRS = internal
+
+projdir = $(includedir)/proj
+
+proj_HEADERS = util.hpp metadata.hpp common.hpp crs.hpp datum.hpp \
+ coordinatesystem.hpp coordinateoperation.hpp io.hpp nn.hpp
diff --git a/include/proj/common.hpp b/include/proj/common.hpp
new file mode 100644
index 00000000..f1e683e7
--- /dev/null
+++ b/include/proj/common.hpp
@@ -0,0 +1,445 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef COMMON_HH_INCLUDED
+#define COMMON_HH_INCLUDED
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "io.hpp"
+#include "metadata.hpp"
+#include "util.hpp"
+
+NS_PROJ_START
+
+/** osgeo.proj.common namespace
+ *
+ * \brief Common classes.
+ */
+namespace common {
+
+// ---------------------------------------------------------------------------
+
+class UnitOfMeasure;
+/** Shared pointer of UnitOfMeasure. */
+using UnitOfMeasurePtr = std::shared_ptr<UnitOfMeasure>;
+/** Non-null shared pointer of UnitOfMeasure. */
+using UnitOfMeasureNNPtr = util::nn<UnitOfMeasurePtr>;
+
+/** \brief Unit of measure.
+ *
+ * This is a mutable object.
+ */
+class PROJ_GCC_DLL UnitOfMeasure : public util::BaseObject {
+ public:
+ /** \brief Type of unit of measure. */
+ enum class PROJ_MSVC_DLL Type {
+ /** Unknown unit of measure */
+ UNKNOWN,
+ /** No unit of measure */
+ NONE,
+ /** Angular unit of measure */
+ ANGULAR,
+ /** Linear unit of measure */
+ LINEAR,
+ /** Scale unit of measure */
+ SCALE,
+ /** Time unit of measure */
+ TIME,
+ /** Parametric unit of measure */
+ PARAMETRIC,
+ };
+
+ PROJ_DLL UnitOfMeasure(const std::string &nameIn = std::string(),
+ double toSIIn = 1.0, Type typeIn = Type::UNKNOWN,
+ const std::string &codeSpaceIn = std::string(),
+ const std::string &codeIn = std::string());
+
+ //! @cond Doxygen_Suppress
+ PROJ_DLL UnitOfMeasure(const UnitOfMeasure &other);
+ PROJ_DLL ~UnitOfMeasure() override;
+ PROJ_DLL UnitOfMeasure &operator=(const UnitOfMeasure &other);
+ PROJ_INTERNAL static UnitOfMeasureNNPtr create(const UnitOfMeasure &other);
+ //! @endcond
+
+ PROJ_DLL const std::string &name() PROJ_PURE_DECL;
+ PROJ_DLL double conversionToSI() PROJ_PURE_DECL;
+ PROJ_DLL Type type() PROJ_PURE_DECL;
+
+ PROJ_DLL const std::string &codeSpace() PROJ_PURE_DECL;
+ PROJ_DLL const std::string &code() PROJ_PURE_DECL;
+
+ PROJ_DLL bool operator==(const UnitOfMeasure &other) PROJ_PURE_DECL;
+ PROJ_DLL bool operator!=(const UnitOfMeasure &other) PROJ_PURE_DECL;
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter,
+ const std::string &unitType = std::string())
+ const; // throw(io::FormattingException)
+
+ PROJ_INTERNAL std::string exportToPROJString() const;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const UnitOfMeasure &other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const;
+
+ //! @endcond
+
+ PROJ_DLL static const UnitOfMeasure NONE;
+
+ PROJ_DLL static const UnitOfMeasure SCALE_UNITY;
+ PROJ_DLL static const UnitOfMeasure PARTS_PER_MILLION;
+ PROJ_DLL static const UnitOfMeasure PPM_PER_YEAR;
+
+ PROJ_DLL static const UnitOfMeasure METRE;
+ PROJ_DLL static const UnitOfMeasure METRE_PER_YEAR;
+
+ PROJ_DLL static const UnitOfMeasure RADIAN;
+ PROJ_DLL static const UnitOfMeasure MICRORADIAN;
+ PROJ_DLL static const UnitOfMeasure DEGREE;
+ PROJ_DLL static const UnitOfMeasure ARC_SECOND;
+ PROJ_DLL static const UnitOfMeasure GRAD;
+ PROJ_DLL static const UnitOfMeasure ARC_SECOND_PER_YEAR;
+
+ PROJ_DLL static const UnitOfMeasure SECOND;
+ PROJ_DLL static const UnitOfMeasure YEAR;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Numeric value associated with a UnitOfMeasure. */
+class Measure : public util::BaseObject {
+ public:
+ PROJ_DLL Measure(double valueIn = 0.0,
+ const UnitOfMeasure &unitIn = UnitOfMeasure());
+
+ //! @cond Doxygen_Suppress
+ PROJ_DLL Measure(const Measure &other);
+ PROJ_DLL ~Measure();
+ //! @endcond
+
+ PROJ_DLL const UnitOfMeasure &unit() PROJ_CONST_DECL;
+ PROJ_DLL double getSIValue() PROJ_CONST_DECL;
+ PROJ_DLL double value() PROJ_CONST_DECL;
+
+ PROJ_DLL double
+ convertToUnit(const UnitOfMeasure &otherUnit) PROJ_CONST_DECL;
+
+ PROJ_DLL bool operator==(const Measure &other) PROJ_CONST_DECL;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const Measure &other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ Measure &operator=(const Measure &) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Numeric value, without a physical unit of measure. */
+class Scale : public Measure {
+ public:
+ PROJ_DLL explicit Scale(double valueIn = 0.0);
+ PROJ_DLL explicit Scale(double valueIn, const UnitOfMeasure &unitIn);
+
+ //! @cond Doxygen_Suppress
+ explicit Scale(const Measure &other) : Scale(other.value(), other.unit()) {}
+ PROJ_DLL Scale(const Scale &other);
+ PROJ_DLL ~Scale() override;
+ //! @endcond
+
+ protected:
+ PROJ_FRIEND_OPTIONAL(Scale);
+ Scale &operator=(const Scale &) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Numeric value, with a angular unit of measure. */
+class Angle : public Measure {
+ public:
+ PROJ_DLL explicit Angle(double valueIn = 0.0);
+ PROJ_DLL Angle(double valueIn, const UnitOfMeasure &unitIn);
+
+ //! @cond Doxygen_Suppress
+ explicit Angle(const Measure &other) : Angle(other.value(), other.unit()) {}
+ PROJ_DLL Angle(const Angle &other);
+ PROJ_DLL ~Angle() override;
+ //! @endcond
+
+ protected:
+ PROJ_FRIEND_OPTIONAL(Angle);
+ Angle &operator=(const Angle &) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Numeric value, with a linear unit of measure. */
+class Length : public Measure {
+ public:
+ PROJ_DLL explicit Length(double valueIn = 0.0);
+ PROJ_DLL Length(double valueIn, const UnitOfMeasure &unitIn);
+
+ //! @cond Doxygen_Suppress
+ explicit Length(const Measure &other)
+ : Length(other.value(), other.unit()) {}
+ PROJ_DLL Length(const Length &other);
+ PROJ_DLL ~Length() override;
+ //! @endcond
+
+ protected:
+ PROJ_FRIEND_OPTIONAL(Length);
+ Length &operator=(const Length &) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Date-time value, as a ISO:8601 encoded string, or other string
+ * encoding */
+class DateTime {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL DateTime(const DateTime &other);
+ PROJ_DLL ~DateTime();
+ //! @endcond
+
+ PROJ_DLL bool isISO_8601() const;
+ PROJ_DLL std::string toString() const;
+
+ PROJ_DLL static DateTime
+ create(const std::string &str); // may throw Exception
+
+ protected:
+ DateTime();
+ PROJ_FRIEND_OPTIONAL(DateTime);
+
+ private:
+ explicit DateTime(const std::string &str);
+ DateTime &operator=(const DateTime &other) = delete;
+
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Data epoch */
+class DataEpoch {
+ // FIXME
+ public:
+ /** FIXME */
+ Measure coordinateEpoch{};
+};
+
+// ---------------------------------------------------------------------------
+
+class IdentifiedObject;
+/** Shared pointer of IdentifiedObject. */
+using IdentifiedObjectPtr = std::shared_ptr<IdentifiedObject>;
+/** Non-null shared pointer of IdentifiedObject. */
+using IdentifiedObjectNNPtr = util::nn<IdentifiedObjectPtr>;
+
+/** \brief Abstract class representating a CRS-related object that has an
+ * identification.
+ *
+ * \remark Implements IdentifiedObject from \ref ISO_19111_2018
+ */
+class IdentifiedObject : public util::BaseObject,
+ public util::IComparable,
+ public io::IWKTExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~IdentifiedObject() override;
+ //! @endcond
+
+ PROJ_DLL static const std::string NAME_KEY;
+ PROJ_DLL static const std::string IDENTIFIERS_KEY;
+ PROJ_DLL static const std::string ALIAS_KEY;
+ PROJ_DLL static const std::string REMARKS_KEY;
+ PROJ_DLL static const std::string DEPRECATED_KEY;
+
+ // in practice only name().description() is used
+ PROJ_DLL const metadata::IdentifierNNPtr &name() PROJ_CONST_DECL;
+ PROJ_DLL const std::string &nameStr() PROJ_CONST_DECL;
+ PROJ_DLL const std::vector<metadata::IdentifierNNPtr> &
+ identifiers() PROJ_CONST_DECL;
+ PROJ_DLL const std::vector<util::GenericNameNNPtr> &
+ aliases() PROJ_CONST_DECL;
+ PROJ_DLL const std::string &remarks() PROJ_CONST_DECL;
+
+ // from Apache SIS AbstractIdentifiedObject
+ PROJ_DLL bool isDeprecated() PROJ_CONST_DECL;
+
+ // Non-standard
+ PROJ_DLL std::string alias() PROJ_CONST_DECL;
+ PROJ_DLL int getEPSGCode() PROJ_CONST_DECL;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ void
+ formatID(io::WKTFormatter *formatter) const;
+ void formatRemarks(io::WKTFormatter *formatter) const;
+
+ bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ bool
+ _isEquivalentTo(const IdentifiedObject *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) PROJ_CONST_DECL;
+ //! @endcond
+
+ protected:
+ PROJ_FRIEND_OPTIONAL(IdentifiedObject);
+ INLINED_MAKE_SHARED
+ IdentifiedObject();
+ IdentifiedObject(const IdentifiedObject &other);
+
+ void setProperties(const util::PropertyMap
+ &properties); // throw(InvalidValueTypeException)
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ IdentifiedObject &operator=(const IdentifiedObject &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class ObjectDomain;
+/** Shared pointer of ObjectDomain. */
+using ObjectDomainPtr = std::shared_ptr<ObjectDomain>;
+/** Non-null shared pointer of ObjectDomain. */
+using ObjectDomainNNPtr = util::nn<ObjectDomainPtr>;
+
+/** \brief The scope and validity of a CRS-related object.
+ *
+ * \remark Implements ObjectDomain from \ref ISO_19111_2018
+ */
+class ObjectDomain : public util::BaseObject, public util::IComparable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~ObjectDomain() override;
+ //! @endcond
+
+ // In ISO_19111:2018, scope and domain are compulsory, but in WKT2:2015,
+ // they
+ // are not necessarily both specified
+ PROJ_DLL const util::optional<std::string> &scope() PROJ_CONST_DECL;
+ PROJ_DLL const metadata::ExtentPtr &domainOfValidity() PROJ_CONST_DECL;
+
+ PROJ_DLL static ObjectDomainNNPtr
+ create(const util::optional<std::string> &scopeIn,
+ const metadata::ExtentPtr &extent);
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ void
+ _exportToWKT(io::WKTFormatter *formatter)
+ const; // throw(io::FormattingException)
+
+ bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+ //! @cond Doxygen_Suppress
+ ObjectDomain(const util::optional<std::string> &scopeIn,
+ const metadata::ExtentPtr &extent);
+ //! @endcond
+
+ ObjectDomain(const ObjectDomain &other);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ ObjectDomain &operator=(const ObjectDomain &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class ObjectUsage;
+/** Shared pointer of ObjectUsage. */
+using ObjectUsagePtr = std::shared_ptr<ObjectUsage>;
+/** Non-null shared pointer of ObjectUsage. */
+using ObjectUsageNNPtr = util::nn<ObjectUsagePtr>;
+
+/** \brief Abstract class of a CRS-related object that has usages.
+ *
+ * \remark Implements ObjectUsage from \ref ISO_19111_2018
+ */
+class ObjectUsage : public IdentifiedObject {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~ObjectUsage() override;
+ //! @endcond
+
+ PROJ_DLL const std::vector<ObjectDomainNNPtr> &domains() PROJ_CONST_DECL;
+
+ PROJ_DLL static const std::string SCOPE_KEY;
+ PROJ_DLL static const std::string DOMAIN_OF_VALIDITY_KEY;
+
+ PROJ_DLL static const std::string OBJECT_DOMAIN_KEY;
+
+ //! @cond Doxygen_Suppress
+ bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+ ObjectUsage();
+ ObjectUsage(const ObjectUsage &other);
+ void setProperties(const util::PropertyMap
+ &properties); // throw(InvalidValueTypeException)
+
+ void baseExportToWKT(
+ io::WKTFormatter *formatter) const; // throw(io::FormattingException)
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ ObjectUsage &operator=(const ObjectUsage &other) = delete;
+};
+
+} // namespace common
+
+NS_PROJ_END
+
+#endif // COMMON_HH_INCLUDED
diff --git a/include/proj/coordinateoperation.hpp b/include/proj/coordinateoperation.hpp
new file mode 100644
index 00000000..5e3ecf0b
--- /dev/null
+++ b/include/proj/coordinateoperation.hpp
@@ -0,0 +1,1764 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef COORDINATEOPERATION_HH_INCLUDED
+#define COORDINATEOPERATION_HH_INCLUDED
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "common.hpp"
+#include "io.hpp"
+#include "metadata.hpp"
+
+NS_PROJ_START
+
+namespace crs {
+class CRS;
+using CRSPtr = std::shared_ptr<CRS>;
+using CRSNNPtr = util::nn<CRSPtr>;
+
+class DerivedCRS;
+class ProjectedCRS;
+} // namespace crs
+
+/** osgeo.proj.operation namespace
+
+ \brief Coordinate operations (relationship between any two coordinate
+ reference systems).
+
+ This covers Conversion, Transformation,
+ PointMotionOperation or ConcatenatedOperation.
+*/
+namespace operation {
+
+// ---------------------------------------------------------------------------
+
+/** \brief Grid description */
+struct GridDescription {
+ std::string shortName{}; /**< Grid short filename */
+ std::string fullName{}; /**< Grid full path name (if found) */
+ std::string packageName{}; /**< Package name (or empty) */
+ std::string url{}; /**< Grid URL (if packageName is empty), or package
+ URL (or empty) */
+ bool directDownload = false; /**< Whether url can be fetched directly. */
+ bool openLicense =
+ false; /**< Whether the grid is released with an open license. */
+ bool available = false; /**< Whether GRID is available. */
+
+ //! @cond Doxygen_Suppress
+ bool operator<(const GridDescription &other) const {
+ return shortName < other.shortName;
+ }
+
+ PROJ_DLL GridDescription();
+ PROJ_DLL ~GridDescription();
+ PROJ_DLL GridDescription(const GridDescription &);
+ PROJ_DLL GridDescription(GridDescription &&) noexcept;
+ //! @endcond
+};
+
+// ---------------------------------------------------------------------------
+
+class CoordinateOperation;
+/** Shared pointer of CoordinateOperation */
+using CoordinateOperationPtr = std::shared_ptr<CoordinateOperation>;
+/** Non-null shared pointer of CoordinateOperation */
+using CoordinateOperationNNPtr = util::nn<CoordinateOperationPtr>;
+
+/** \brief Abstract class for a mathematical operation on coordinates.
+ *
+ * A mathematical operation:
+ * <ul>
+ * <li>on coordinates that transforms or converts them from one coordinate
+ * reference system to another coordinate reference system</li>
+ * <li>or that describes the change of coordinate values within one coordinate
+ * reference system due to the motion of the point between one coordinate epoch
+ * and another coordinate epoch.</li>
+ * </ul>
+ * Many but not all coordinate operations (from CRS A to CRS B) also uniquely
+ * define the inverse coordinate operation (from CRS B to CRS A). In some cases,
+ * the coordinate operation method algorithm for the inverse coordinate
+ * operation is the same as for the forward algorithm, but the signs of some
+ * coordinate operation parameter values have to be reversed. In other cases,
+ * different algorithms are required for the forward and inverse coordinate
+ * operations, but the same coordinate operation parameter values are used. If
+ * (some) entirely different parameter values are needed, a different coordinate
+ * operation shall be defined.
+ *
+ * \remark Implements CoordinateOperation from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL CoordinateOperation : public common::ObjectUsage,
+ public io::IPROJStringExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~CoordinateOperation() override;
+ //! @endcond
+
+ PROJ_DLL const util::optional<std::string> &operationVersion() const;
+ PROJ_DLL const std::vector<metadata::PositionalAccuracyNNPtr> &
+ coordinateOperationAccuracies() const;
+
+ PROJ_DLL const crs::CRSPtr sourceCRS() const;
+ PROJ_DLL const crs::CRSPtr targetCRS() const;
+ PROJ_DLL const crs::CRSPtr &interpolationCRS() const;
+ PROJ_DLL const util::optional<common::DataEpoch> &
+ sourceCoordinateEpoch() const;
+ PROJ_DLL const util::optional<common::DataEpoch> &
+ targetCoordinateEpoch() const;
+
+ // virtual void transform(...) = 0; TODO
+
+ /** \brief Return the inverse of the coordinate operation.
+ * @throw util::UnsupportedOperationException
+ */
+ PROJ_DLL virtual CoordinateOperationNNPtr inverse() const = 0;
+
+ /** \brief Return grids needed by an operation. */
+ PROJ_DLL virtual std::set<GridDescription>
+ gridsNeeded(const io::DatabaseContextPtr &databaseContext) const = 0;
+
+ PROJ_DLL bool
+ isPROJInstanciable(const io::DatabaseContextPtr &databaseContext) const;
+
+ protected:
+ PROJ_INTERNAL CoordinateOperation();
+ PROJ_INTERNAL CoordinateOperation(const CoordinateOperation &other);
+
+ PROJ_FRIEND(crs::DerivedCRS);
+ PROJ_FRIEND(io::AuthorityFactory);
+ PROJ_FRIEND(CoordinateOperationFactory);
+ PROJ_INTERNAL void
+ setWeakSourceTargetCRS(std::weak_ptr<crs::CRS> sourceCRSIn,
+ std::weak_ptr<crs::CRS> targetCRSIn);
+ PROJ_INTERNAL void setCRSs(const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn,
+ const crs::CRSPtr &interpolationCRSIn);
+ PROJ_INTERNAL void setCRSs(const CoordinateOperation *in,
+ bool inverseSourceTarget);
+ PROJ_INTERNAL
+ void setAccuracies(
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ CoordinateOperation &operator=(const CoordinateOperation &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Abstract class modelling a parameter value (OperationParameter)
+ * or group of parameters.
+ *
+ * \remark Implements GeneralOperationParameter from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL GeneralOperationParameter : public common::IdentifiedObject {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~GeneralOperationParameter() override;
+ //! @endcond
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool _isEquivalentTo(
+ const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override = 0;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL GeneralOperationParameter();
+ PROJ_INTERNAL
+ GeneralOperationParameter(const GeneralOperationParameter &other);
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ GeneralOperationParameter &
+ operator=(const GeneralOperationParameter &other) = delete;
+};
+
+/** Shared pointer of GeneralOperationParameter */
+using GeneralOperationParameterPtr = std::shared_ptr<GeneralOperationParameter>;
+/** Non-null shared pointer of GeneralOperationParameter */
+using GeneralOperationParameterNNPtr = util::nn<GeneralOperationParameterPtr>;
+
+// ---------------------------------------------------------------------------
+
+class OperationParameter;
+/** Shared pointer of OperationParameter */
+using OperationParameterPtr = std::shared_ptr<OperationParameter>;
+/** Non-null shared pointer of OperationParameter */
+using OperationParameterNNPtr = util::nn<OperationParameterPtr>;
+
+/** \brief The definition of a parameter used by a coordinate operation method.
+ *
+ * Most parameter values are numeric, but other types of parameter values are
+ * possible.
+ *
+ * \remark Implements OperationParameter from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL OperationParameter final : public GeneralOperationParameter {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~OperationParameter() override;
+ //! @endcond
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ // non-standard
+ PROJ_DLL static OperationParameterNNPtr
+ create(const util::PropertyMap &properties);
+
+ PROJ_DLL int getEPSGCode() PROJ_CONST_DECL;
+
+ PROJ_DLL static const char *getNameForEPSGCode(int epsg_code) noexcept;
+
+ protected:
+ PROJ_INTERNAL OperationParameter();
+ PROJ_INTERNAL OperationParameter(const OperationParameter &other);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ OperationParameter &operator=(const OperationParameter &other) = delete;
+
+ // cppcheck-suppress functionStatic
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+};
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+struct MethodMapping;
+//! @endcond
+
+/** \brief Abstract class modelling a parameter value (OperationParameterValue)
+ * or group of parameter values.
+ *
+ * \remark Implements GeneralParameterValue from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL GeneralParameterValue : public util::BaseObject,
+ public io::IWKTExportable,
+ public util::IComparable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~GeneralParameterValue() override;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override = 0; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool _isEquivalentTo(
+ const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override = 0;
+ //! @endcond
+
+ protected:
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL GeneralParameterValue();
+ PROJ_INTERNAL GeneralParameterValue(const GeneralParameterValue &other);
+
+ friend class Conversion;
+ friend class SingleOperation;
+ PROJ_INTERNAL virtual void _exportToWKT(io::WKTFormatter *formatter,
+ const MethodMapping *mapping)
+ const = 0; // throw(io::FormattingException)
+ //! @endcond
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ GeneralParameterValue &
+ operator=(const GeneralParameterValue &other) = delete;
+};
+
+/** Shared pointer of GeneralParameterValue */
+using GeneralParameterValuePtr = std::shared_ptr<GeneralParameterValue>;
+/** Non-null shared pointer of GeneralParameterValue */
+using GeneralParameterValueNNPtr = util::nn<GeneralParameterValuePtr>;
+
+// ---------------------------------------------------------------------------
+
+class ParameterValue;
+/** Shared pointer of ParameterValue */
+using ParameterValuePtr = std::shared_ptr<ParameterValue>;
+/** Non-null shared pointer of ParameterValue */
+using ParameterValueNNPtr = util::nn<ParameterValuePtr>;
+
+/** \brief The value of the coordinate operation parameter.
+ *
+ * Most parameter values are numeric, but other types of parameter values are
+ * possible.
+ *
+ * \remark Implements ParameterValue from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL ParameterValue final : public util::BaseObject,
+ public io::IWKTExportable,
+ public util::IComparable {
+ public:
+ /** Type of the value. */
+ enum class Type {
+ /** Measure (i.e. value with a unit) */
+ MEASURE,
+ /** String */
+ STRING,
+ /** Integer */
+ INTEGER,
+ /** Boolean */
+ BOOLEAN,
+ /** Filename */
+ FILENAME
+ };
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~ParameterValue() override;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ PROJ_DLL static ParameterValueNNPtr
+ create(const common::Measure &measureIn);
+ PROJ_DLL static ParameterValueNNPtr create(const char *stringValueIn);
+ PROJ_DLL static ParameterValueNNPtr
+ create(const std::string &stringValueIn);
+ PROJ_DLL static ParameterValueNNPtr create(int integerValueIn);
+ PROJ_DLL static ParameterValueNNPtr create(bool booleanValueIn);
+ PROJ_DLL static ParameterValueNNPtr
+ createFilename(const std::string &stringValueIn);
+
+ PROJ_DLL const Type &type() PROJ_CONST_DECL;
+ PROJ_DLL const common::Measure &value() PROJ_CONST_DECL;
+ PROJ_DLL const std::string &stringValue() PROJ_CONST_DECL;
+ PROJ_DLL const std::string &valueFile() PROJ_CONST_DECL;
+ PROJ_DLL int integerValue() PROJ_CONST_DECL;
+ PROJ_DLL bool booleanValue() PROJ_CONST_DECL;
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL explicit ParameterValue(const common::Measure &measureIn);
+ PROJ_INTERNAL explicit ParameterValue(const std::string &stringValueIn,
+ Type typeIn);
+ PROJ_INTERNAL explicit ParameterValue(int integerValueIn);
+ PROJ_INTERNAL explicit ParameterValue(bool booleanValueIn);
+ INLINED_MAKE_SHARED
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ ParameterValue &operator=(const ParameterValue &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class OperationParameterValue;
+/** Shared pointer of OperationParameterValue */
+using OperationParameterValuePtr = std::shared_ptr<OperationParameterValue>;
+/** Non-null shared pointer of OperationParameterValue */
+using OperationParameterValueNNPtr = util::nn<OperationParameterValuePtr>;
+
+/** \brief A parameter value, ordered sequence of values, or reference to a
+ * file of parameter values.
+ *
+ * This combines a OperationParameter with the corresponding ParameterValue.
+ *
+ * \remark Implements OperationParameterValue from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL OperationParameterValue final
+ : public GeneralParameterValue {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~OperationParameterValue() override;
+ //! @endcond
+
+ PROJ_DLL const OperationParameterNNPtr &parameter() PROJ_CONST_DECL;
+ PROJ_DLL const ParameterValueNNPtr &parameterValue() PROJ_CONST_DECL;
+
+ PROJ_DLL static OperationParameterValueNNPtr
+ create(const OperationParameterNNPtr &parameterIn,
+ const ParameterValueNNPtr &valueIn);
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL static bool
+ convertFromAbridged(const std::string &paramName, double &val,
+ const common::UnitOfMeasure *&unit,
+ int &paramEPSGCode);
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL
+ OperationParameterValue(const OperationParameterNNPtr &parameterIn,
+ const ParameterValueNNPtr &valueIn);
+ PROJ_INTERNAL OperationParameterValue(const OperationParameterValue &other);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter,
+ const MethodMapping *mapping)
+ const override; // throw(io::FormattingException)
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ OperationParameterValue &
+ operator=(const OperationParameterValue &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class OperationMethod;
+/** Shared pointer of OperationMethod */
+using OperationMethodPtr = std::shared_ptr<OperationMethod>;
+/** Non-null shared pointer of OperationMethod */
+using OperationMethodNNPtr = util::nn<OperationMethodPtr>;
+
+/** \brief The method (algorithm or procedure) used to perform the
+ * coordinate operation.
+ *
+ * For a projection method, this contains the name of the projection method
+ * and the name of the projection parameters.
+ *
+ * \remark Implements OperationMethod from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL OperationMethod : public common::IdentifiedObject {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~OperationMethod() override;
+ //! @endcond
+
+ PROJ_DLL const util::optional<std::string> &formula() PROJ_CONST_DECL;
+ PROJ_DLL const util::optional<metadata::Citation> &
+ formulaCitation() PROJ_CONST_DECL;
+ PROJ_DLL const std::vector<GeneralOperationParameterNNPtr> &
+ parameters() PROJ_CONST_DECL;
+
+ PROJ_DLL static OperationMethodNNPtr
+ create(const util::PropertyMap &properties,
+ const std::vector<GeneralOperationParameterNNPtr> &parameters);
+
+ PROJ_DLL static OperationMethodNNPtr
+ create(const util::PropertyMap &properties,
+ const std::vector<OperationParameterNNPtr> &parameters);
+
+ PROJ_DLL int getEPSGCode() PROJ_CONST_DECL;
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL OperationMethod();
+ PROJ_INTERNAL OperationMethod(const OperationMethod &other);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ OperationMethod &operator=(const OperationMethod &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Exception that can be thrown when an invalid operation is attempted
+ * to be constructed.
+ */
+class PROJ_GCC_DLL InvalidOperation : public util::Exception {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL explicit InvalidOperation(const char *message);
+ PROJ_INTERNAL explicit InvalidOperation(const std::string &message);
+ PROJ_DLL InvalidOperation(const InvalidOperation &other);
+ PROJ_DLL ~InvalidOperation() override;
+ //! @endcond
+};
+
+// ---------------------------------------------------------------------------
+
+class SingleOperation;
+/** Shared pointer of SingleOperation */
+using SingleOperationPtr = std::shared_ptr<SingleOperation>;
+/** Non-null shared pointer of SingleOperation */
+using SingleOperationNNPtr = util::nn<SingleOperationPtr>;
+
+/** \brief A single (not concatenated) coordinate operation
+ * (CoordinateOperation)
+ *
+ * \remark Implements SingleOperation from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL SingleOperation : virtual public CoordinateOperation {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~SingleOperation() override;
+ //! @endcond
+
+ PROJ_DLL const std::vector<GeneralParameterValueNNPtr> &
+ parameterValues() PROJ_CONST_DECL;
+ PROJ_DLL const OperationMethodNNPtr &method() PROJ_CONST_DECL;
+
+ PROJ_DLL const ParameterValuePtr &
+ parameterValue(const std::string &paramName, int epsg_code = 0) const
+ noexcept;
+
+ PROJ_DLL const ParameterValuePtr &parameterValue(int epsg_code) const
+ noexcept;
+
+ PROJ_DLL const common::Measure &
+ parameterValueMeasure(const std::string &paramName, int epsg_code = 0) const
+ noexcept;
+
+ PROJ_DLL const common::Measure &parameterValueMeasure(int epsg_code) const
+ noexcept;
+
+ PROJ_DLL static SingleOperationNNPtr createPROJBased(
+ const util::PropertyMap &properties, const std::string &PROJString,
+ const crs::CRSPtr &sourceCRS, const crs::CRSPtr &targetCRS,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies =
+ std::vector<metadata::PositionalAccuracyNNPtr>());
+
+ PROJ_DLL std::set<GridDescription>
+ gridsNeeded(const io::DatabaseContextPtr &databaseContext) const override;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+
+ PROJ_DLL double
+ parameterValueNumeric(int epsg_code,
+ const common::UnitOfMeasure &targetUnit) const
+ noexcept;
+
+ PROJ_INTERNAL double parameterValueNumericAsSI(int epsg_code) const
+ noexcept;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL explicit SingleOperation(
+ const OperationMethodNNPtr &methodIn);
+ PROJ_INTERNAL SingleOperation(const SingleOperation &other);
+
+ PROJ_INTERNAL void
+ setParameterValues(const std::vector<GeneralParameterValueNNPtr> &values);
+
+ PROJ_INTERNAL void
+ exportTransformationToWKT(io::WKTFormatter *formatter) const;
+
+ PROJ_INTERNAL bool
+ exportToPROJStringGeneric(io::PROJStringFormatter *formatter) const;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ SingleOperation &operator=(const SingleOperation &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class Conversion;
+/** Shared pointer of Conversion */
+using ConversionPtr = std::shared_ptr<Conversion>;
+/** Non-null shared pointer of Conversion */
+using ConversionNNPtr = util::nn<ConversionPtr>;
+
+/** \brief A mathematical operation on coordinates in which the parameter
+ * values are defined rather than empirically derived.
+ *
+ * Application of the coordinate conversion introduces no error into output
+ * coordinates. The best-known example of a coordinate conversion is a map
+ * projection. For coordinate conversions the output coordinates are referenced
+ * to the same datum as are the input coordinates.
+ *
+ * Coordinate conversions forming a component of a derived CRS have a source
+ * crs::CRS and a target crs::CRS that are NOT specified through the source and
+ * target
+ * associations, but through associations from crs::DerivedCRS to
+ * crs::SingleCRS.
+ *
+ * \remark Implements Conversion from \ref ISO_19111_2018
+ */
+
+/*!
+
+\section projection_parameters Projection parameters
+
+\subsection colatitude_cone_axis Co-latitude of cone axis
+
+The rotation applied to spherical coordinates for the oblique projection,
+measured on the conformal sphere in the plane of the meridian of origin.
+
+EPSG:1036
+
+\subsection center_latitude Latitude of natural origin/Center Latitude
+
+The latitude of the point from which the values of both the geographical
+coordinates on the ellipsoid and the grid coordinates on the projection are
+deemed to increment or decrement for computational purposes. Alternatively it
+may be considered as the latitude of the point which in the absence of
+application of false coordinates has grid coordinates of (0,0).
+
+EPSG:8801
+
+\subsection center_longitude Longitude of natural origin/Central Meridian
+
+The longitude of the point from which the values of both the geographical
+coordinates on the ellipsoid and the grid coordinates on the projection are
+deemed to increment or decrement for computational purposes. Alternatively it
+may be considered as the longitude of the point which in the absence of
+application of false coordinates has grid coordinates of (0,0). Sometimes known
+as "central meridian (CM)".
+
+EPSG:8802
+
+\subsection scale Scale Factor
+
+The factor by which the map grid is reduced or enlarged during the projection
+process, defined by its value at the natural origin.
+
+EPSG:8805
+
+\subsection false_easting False Easting
+
+Since the natural origin may be at or near the centre of the projection and
+under normal coordinate circumstances would thus give rise to negative
+coordinates over parts of the mapped area, this origin is usually given false
+coordinates which are large enough to avoid this inconvenience. The False
+Easting, FE, is the value assigned to the abscissa (east or west) axis of the
+projection grid at the natural origin.
+
+EPSG:8806
+
+\subsection false_northing False Northing
+
+Since the natural origin may be at or near the centre of the projection and
+under normal coordinate circumstances would thus give rise to negative
+coordinates over parts of the mapped area, this origin is usually given false
+coordinates which are large enough to avoid this inconvenience. The False
+Northing, FN, is the value assigned to the ordinate (north or south) axis of the
+projection grid at the natural origin.
+
+EPSG:8807
+
+\subsection latitude_projection_centre Latitute of projection centre
+
+For an oblique projection, this is the latitude of the point at which the
+azimuth of the central line is defined.
+
+EPSG:8811
+
+\subsection longitude_projection_centre Longitude of projection centre
+
+For an oblique projection, this is the longitude of the point at which the
+azimuth of the central line is defined.
+
+EPSG:8812
+
+\subsection azimuth_initial_line Azimuth of initial line
+
+The azimuthal direction (north zero, east of north being positive) of the great
+circle which is the centre line of an oblique projection. The azimuth is given
+at the projection centre.
+
+EPSG:8813
+
+\subsection angle_from_recitfied_to_skrew_grid Angle from Rectified to Skew Grid
+
+The angle at the natural origin of an oblique projection through which the
+natural coordinate reference system is rotated to make the projection north
+axis parallel with true north.
+
+EPSG:8814
+
+\subsection scale_factor_initial_line Scale factor on initial line
+
+The factor by which the map grid is reduced or enlarged during the projection
+process, defined by its value at the projection center.
+
+EPSG:8815
+
+\subsection easting_projection_centre Easting at projection centre
+
+The easting value assigned to the projection centre.
+
+EPSG:8816
+
+\subsection northing_projection_centre Northing at projection centre
+
+The northing value assigned to the projection centre.
+
+EPSG:8817
+
+\subsection latitude_pseudo_standard_parallel Latitude of pseudo standard
+parallel
+
+Latitude of the parallel on which the conic or cylindrical projection is based.
+This latitude is not geographic, but is defined on the conformal sphere AFTER
+its rotation to obtain the oblique aspect of the projection.
+
+EPSG:8818
+
+\subsection scale_factor_pseudo_standard_parallel Scale factor on pseudo
+standard parallel
+
+The factor by which the map grid is reduced or enlarged during the projection
+process, defined by its value at the pseudo-standard parallel.
+EPSG:8819
+
+\subsection latitude_false_origin Latitude of false origin
+
+The latitude of the point which is not the natural origin and at which grid
+coordinate values false easting and false northing are defined.
+
+EPSG:8821
+
+\subsection longitude_false_origin Longitude of false origin
+
+The longitude of the point which is not the natural origin and at which grid
+coordinate values false easting and false northing are defined.
+
+EPSG:8822
+
+\subsection latitude_first_std_parallel Latitude of 1st standard parallel
+
+For a conic projection with two standard parallels, this is the latitude of one
+of the parallels of intersection of the cone with the ellipsoid. It is normally
+but not necessarily that nearest to the pole. Scale is true along this parallel.
+
+EPSG:8823
+
+\subsection latitude_second_std_parallel Latitude of 2nd standard parallel
+
+For a conic projection with two standard parallels, this is the latitude of one
+of the parallels at which the cone intersects with the ellipsoid. It is normally
+but not necessarily that nearest to the equator. Scale is true along this
+parallel.
+
+EPSG:8824
+
+\subsection easting_false_origin Easting of false origin
+
+The easting value assigned to the false origin.
+
+EPSG:8826
+
+\subsection northing_false_origin Northing of false origin
+
+The northing value assigned to the false origin.
+
+EPSG:8827
+
+\subsection latitude_std_parallel Latitude of standard parallel
+
+For polar aspect azimuthal projections, the parallel on which the scale factor
+is defined to be unity.
+
+EPSG:8832
+
+\subsection longitude_of_origin Longitude of origin
+
+For polar aspect azimuthal projections, the meridian along which the
+northing axis increments and also across which parallels of latitude
+increment towards the north pole.
+
+EPSG:8833
+
+*/
+
+class PROJ_GCC_DLL Conversion : public SingleOperation {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~Conversion() override;
+ //! @endcond
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL ConversionNNPtr shallowClone() const;
+ //! @endcond
+
+ PROJ_DLL CoordinateOperationNNPtr inverse() const override;
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ PROJ_DLL bool isUTM(int &zone, bool &north) const;
+
+ PROJ_DLL ConversionNNPtr identify() const;
+
+ PROJ_DLL static ConversionNNPtr
+ create(const util::PropertyMap &properties,
+ const OperationMethodNNPtr &methodIn,
+ const std::vector<GeneralParameterValueNNPtr>
+ &values); // throw InvalidOperation
+
+ PROJ_DLL static ConversionNNPtr
+ create(const util::PropertyMap &propertiesConversion,
+ const util::PropertyMap &propertiesOperationMethod,
+ const std::vector<OperationParameterNNPtr> &parameters,
+ const std::vector<ParameterValueNNPtr>
+ &values); // throw InvalidOperation
+
+ PROJ_DLL static ConversionNNPtr
+ createUTM(const util::PropertyMap &properties, int zone, bool north);
+
+ PROJ_DLL static ConversionNNPtr createTransverseMercator(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Scale &scale,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createGaussSchreiberTransverseMercator(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Scale &scale,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createTransverseMercatorSouthOriented(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Scale &scale,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createTwoPointEquidistant(const util::PropertyMap &properties,
+ const common::Angle &latitudeFirstPoint,
+ const common::Angle &longitudeFirstPoint,
+ const common::Angle &latitudeSecondPoint,
+ const common::Angle &longitudeSeconPoint,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createTunisiaMappingGrid(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createAlbersEqualArea(const util::PropertyMap &properties,
+ const common::Angle &latitudeFalseOrigin,
+ const common::Angle &longitudeFalseOrigin,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &latitudeSecondParallel,
+ const common::Length &eastingFalseOrigin,
+ const common::Length &northingFalseOrigin);
+
+ PROJ_DLL static ConversionNNPtr createLambertConicConformal_1SP(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Scale &scale,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createLambertConicConformal_2SP(const util::PropertyMap &properties,
+ const common::Angle &latitudeFalseOrigin,
+ const common::Angle &longitudeFalseOrigin,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &latitudeSecondParallel,
+ const common::Length &eastingFalseOrigin,
+ const common::Length &northingFalseOrigin);
+
+ PROJ_DLL static ConversionNNPtr createLambertConicConformal_2SP_Michigan(
+ const util::PropertyMap &properties,
+ const common::Angle &latitudeFalseOrigin,
+ const common::Angle &longitudeFalseOrigin,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &latitudeSecondParallel,
+ const common::Length &eastingFalseOrigin,
+ const common::Length &northingFalseOrigin,
+ const common::Scale &ellipsoidScalingFactor);
+
+ PROJ_DLL static ConversionNNPtr createLambertConicConformal_2SP_Belgium(
+ const util::PropertyMap &properties,
+ const common::Angle &latitudeFalseOrigin,
+ const common::Angle &longitudeFalseOrigin,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &latitudeSecondParallel,
+ const common::Length &eastingFalseOrigin,
+ const common::Length &northingFalseOrigin);
+
+ PROJ_DLL static ConversionNNPtr
+ createAzimuthalEquidistant(const util::PropertyMap &properties,
+ const common::Angle &latitudeNatOrigin,
+ const common::Angle &longitudeNatOrigin,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createGuamProjection(const util::PropertyMap &properties,
+ const common::Angle &latitudeNatOrigin,
+ const common::Angle &longitudeNatOrigin,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createBonne(const util::PropertyMap &properties,
+ const common::Angle &latitudeNatOrigin,
+ const common::Angle &longitudeNatOrigin,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createLambertCylindricalEqualAreaSpherical(
+ const util::PropertyMap &properties,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &longitudeNatOrigin,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createLambertCylindricalEqualArea(
+ const util::PropertyMap &properties,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &longitudeNatOrigin,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createCassiniSoldner(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createEquidistantConic(const util::PropertyMap &properties,
+ const common::Angle &centerLat,
+ const common::Angle &centerLong,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &latitudeSecondParallel,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createEckertI(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createEckertII(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createEckertIII(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createEckertIV(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createEckertV(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createEckertVI(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createEquidistantCylindrical(const util::PropertyMap &properties,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &longitudeNatOrigin,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createEquidistantCylindricalSpherical(
+ const util::PropertyMap &properties,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &longitudeNatOrigin,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createGall(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createGoodeHomolosine(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createInterruptedGoodeHomolosine(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createGeostationarySatelliteSweepX(
+ const util::PropertyMap &properties, const common::Angle &centerLong,
+ const common::Length &height, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createGeostationarySatelliteSweepY(
+ const util::PropertyMap &properties, const common::Angle &centerLong,
+ const common::Length &height, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createGnomonic(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createHotineObliqueMercatorVariantA(
+ const util::PropertyMap &properties,
+ const common::Angle &latitudeProjectionCentre,
+ const common::Angle &longitudeProjectionCentre,
+ const common::Angle &azimuthInitialLine,
+ const common::Angle &angleFromRectifiedToSkrewGrid,
+ const common::Scale &scale, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createHotineObliqueMercatorVariantB(
+ const util::PropertyMap &properties,
+ const common::Angle &latitudeProjectionCentre,
+ const common::Angle &longitudeProjectionCentre,
+ const common::Angle &azimuthInitialLine,
+ const common::Angle &angleFromRectifiedToSkrewGrid,
+ const common::Scale &scale,
+ const common::Length &eastingProjectionCentre,
+ const common::Length &northingProjectionCentre);
+
+ PROJ_DLL static ConversionNNPtr
+ createHotineObliqueMercatorTwoPointNaturalOrigin(
+ const util::PropertyMap &properties,
+ const common::Angle &latitudeProjectionCentre,
+ const common::Angle &latitudePoint1,
+ const common::Angle &longitudePoint1,
+ const common::Angle &latitudePoint2,
+ const common::Angle &longitudePoint2, const common::Scale &scale,
+ const common::Length &eastingProjectionCentre,
+ const common::Length &northingProjectionCentre);
+
+ PROJ_DLL static ConversionNNPtr createInternationalMapWorldPolyconic(
+ const util::PropertyMap &properties, const common::Angle &centerLong,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &latitudeSecondParallel,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createKrovakNorthOriented(
+ const util::PropertyMap &properties,
+ const common::Angle &latitudeProjectionCentre,
+ const common::Angle &longitudeOfOrigin,
+ const common::Angle &colatitudeConeAxis,
+ const common::Angle &latitudePseudoStandardParallel,
+ const common::Scale &scaleFactorPseudoStandardParallel,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createKrovak(const util::PropertyMap &properties,
+ const common::Angle &latitudeProjectionCentre,
+ const common::Angle &longitudeOfOrigin,
+ const common::Angle &colatitudeConeAxis,
+ const common::Angle &latitudePseudoStandardParallel,
+ const common::Scale &scaleFactorPseudoStandardParallel,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createLambertAzimuthalEqualArea(const util::PropertyMap &properties,
+ const common::Angle &latitudeNatOrigin,
+ const common::Angle &longitudeNatOrigin,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createMillerCylindrical(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createMercatorVariantA(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Scale &scale,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createMercatorVariantB(const util::PropertyMap &properties,
+ const common::Angle &latitudeFirstParallel,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createPopularVisualisationPseudoMercator(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createMollweide(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createNewZealandMappingGrid(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createObliqueStereographic(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Scale &scale,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createOrthographic(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createAmericanPolyconic(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createPolarStereographicVariantA(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Scale &scale,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createPolarStereographicVariantB(
+ const util::PropertyMap &properties,
+ const common::Angle &latitudeStandardParallel,
+ const common::Angle &longitudeOfOrigin,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createRobinson(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createSinusoidal(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createStereographic(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Scale &scale,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createVanDerGrinten(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createWagnerI(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createWagnerII(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createWagnerIII(const util::PropertyMap &properties,
+ const common::Angle &latitudeTrueScale,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createWagnerIV(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createWagnerV(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createWagnerVI(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createWagnerVII(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createQuadrilateralizedSphericalCube(
+ const util::PropertyMap &properties, const common::Angle &centerLat,
+ const common::Angle &centerLong, const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr createSphericalCrossTrackHeight(
+ const util::PropertyMap &properties, const common::Angle &pegPointLat,
+ const common::Angle &pegPointLong, const common::Angle &pegPointHeading,
+ const common::Length &pegPointHeight);
+
+ PROJ_DLL static ConversionNNPtr
+ createEqualEarth(const util::PropertyMap &properties,
+ const common::Angle &centerLong,
+ const common::Length &falseEasting,
+ const common::Length &falseNorthing);
+
+ PROJ_DLL static ConversionNNPtr
+ createChangeVerticalUnit(const util::PropertyMap &properties,
+ const common::Scale &factor);
+
+ PROJ_DLL static ConversionNNPtr createAxisOrderReversal(bool is3D);
+
+ PROJ_DLL static ConversionNNPtr
+ createGeographicGeocentric(const util::PropertyMap &properties);
+
+ PROJ_DLL ConversionPtr convertToOtherMethod(int targetEPSGCode) const;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void
+ _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL const char *getESRIMethodName() const;
+
+ PROJ_INTERNAL const char *getWKT1GDALMethodName() const;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL
+ Conversion(const OperationMethodNNPtr &methodIn,
+ const std::vector<GeneralParameterValueNNPtr> &values);
+ PROJ_INTERNAL Conversion(const Conversion &other);
+ INLINED_MAKE_SHARED
+
+ PROJ_FRIEND(crs::ProjectedCRS);
+ PROJ_INTERNAL void addWKTExtensionNode(io::WKTFormatter *formatter) const;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ Conversion &operator=(const Conversion &other) = delete;
+
+ PROJ_INTERNAL static ConversionNNPtr
+ create(const util::PropertyMap &properties, int method_epsg_code,
+ const std::vector<ParameterValueNNPtr> &values);
+
+ PROJ_INTERNAL static ConversionNNPtr
+ create(const util::PropertyMap &properties, const char *method_wkt2_name,
+ const std::vector<ParameterValueNNPtr> &values);
+};
+
+// ---------------------------------------------------------------------------
+
+class Transformation;
+/** Shared pointer of Transformation */
+using TransformationPtr = std::shared_ptr<Transformation>;
+/** Non-null shared pointer of Transformation */
+using TransformationNNPtr = util::nn<TransformationPtr>;
+
+/** \brief A mathematical operation on coordinates in which parameters are
+ * empirically derived from data containing the coordinates of a series of
+ * points in both coordinate reference systems.
+ *
+ * This computational process is usually "over-determined", allowing derivation
+ * of error (or accuracy) estimates for the coordinate transformation. Also,
+ * the stochastic nature of the parameters may result in multiple (different)
+ * versions of the same coordinate transformations between the same source and
+ * target CRSs. Any single coordinate operation in which the input and output
+ * coordinates are referenced to different datums (reference frames) will be a
+ * coordinate transformation.
+ *
+ * \remark Implements Transformation from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL Transformation : public SingleOperation {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~Transformation() override;
+ //! @endcond
+
+ PROJ_DLL const crs::CRSNNPtr &sourceCRS() PROJ_CONST_DECL;
+ PROJ_DLL const crs::CRSNNPtr &targetCRS() PROJ_CONST_DECL;
+
+ PROJ_DLL CoordinateOperationNNPtr inverse() const override;
+
+ PROJ_DLL static TransformationNNPtr
+ create(const util::PropertyMap &properties,
+ const crs::CRSNNPtr &sourceCRSIn, const crs::CRSNNPtr &targetCRSIn,
+ const crs::CRSPtr &interpolationCRSIn,
+ const OperationMethodNNPtr &methodIn,
+ const std::vector<GeneralParameterValueNNPtr> &values,
+ const std::vector<metadata::PositionalAccuracyNNPtr>
+ &accuracies); // throw InvalidOperation
+
+ PROJ_DLL static TransformationNNPtr
+ create(const util::PropertyMap &propertiesTransformation,
+ const crs::CRSNNPtr &sourceCRSIn, const crs::CRSNNPtr &targetCRSIn,
+ const crs::CRSPtr &interpolationCRSIn,
+ const util::PropertyMap &propertiesOperationMethod,
+ const std::vector<OperationParameterNNPtr> &parameters,
+ const std::vector<ParameterValueNNPtr> &values,
+ const std::vector<metadata::PositionalAccuracyNNPtr>
+ &accuracies); // throw InvalidOperation
+
+ PROJ_DLL static TransformationNNPtr createGeocentricTranslations(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, double translationXMetre,
+ double translationYMetre, double translationZMetre,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createPositionVector(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, double translationXMetre,
+ double translationYMetre, double translationZMetre,
+ double rotationXArcSecond, double rotationYArcSecond,
+ double rotationZArcSecond, double scaleDifferencePPM,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createCoordinateFrameRotation(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, double translationXMetre,
+ double translationYMetre, double translationZMetre,
+ double rotationXArcSecond, double rotationYArcSecond,
+ double rotationZArcSecond, double scaleDifferencePPM,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createTimeDependentPositionVector(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, double translationXMetre,
+ double translationYMetre, double translationZMetre,
+ double rotationXArcSecond, double rotationYArcSecond,
+ double rotationZArcSecond, double scaleDifferencePPM,
+ double rateTranslationX, double rateTranslationY,
+ double rateTranslationZ, double rateRotationX, double rateRotationY,
+ double rateRotationZ, double rateScaleDifference,
+ double referenceEpochYear,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr
+ createTimeDependentCoordinateFrameRotation(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, double translationXMetre,
+ double translationYMetre, double translationZMetre,
+ double rotationXArcSecond, double rotationYArcSecond,
+ double rotationZArcSecond, double scaleDifferencePPM,
+ double rateTranslationX, double rateTranslationY,
+ double rateTranslationZ, double rateRotationX, double rateRotationY,
+ double rateRotationZ, double rateScaleDifference,
+ double referenceEpochYear,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createTOWGS84(
+ const crs::CRSNNPtr &sourceCRSIn,
+ const std::vector<double> &TOWGS84Parameters); // throw InvalidOperation
+
+ PROJ_DLL static TransformationNNPtr createNTv2(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, const std::string &filename,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createMolodensky(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, double translationXMetre,
+ double translationYMetre, double translationZMetre,
+ double semiMajorAxisDifferenceMetre, double flattingDifference,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createAbridgedMolodensky(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, double translationXMetre,
+ double translationYMetre, double translationZMetre,
+ double semiMajorAxisDifferenceMetre, double flattingDifference,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr
+ createGravityRelatedHeightToGeographic3D(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, const std::string &filename,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createVERTCON(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, const std::string &filename,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createLongitudeRotation(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, const common::Angle &offset);
+
+ PROJ_DLL static TransformationNNPtr createGeographic2DOffsets(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, const common::Angle &offsetLat,
+ const common::Angle &offsetLon,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createGeographic3DOffsets(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, const common::Angle &offsetLat,
+ const common::Angle &offsetLon, const common::Length &offsetHeight,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createGeographic2DWithHeightOffsets(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, const common::Angle &offsetLat,
+ const common::Angle &offsetLon, const common::Length &offsetHeight,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL static TransformationNNPtr createVerticalOffset(
+ const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn,
+ const crs::CRSNNPtr &targetCRSIn, const common::Length &offsetHeight,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ PROJ_DLL TransformationNNPtr substitutePROJAlternativeGridNames(
+ io::DatabaseContextNNPtr databaseContext) const;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL const std::string &
+ getNTv2Filename() const;
+
+ PROJ_FOR_TEST std::vector<double>
+ getTOWGS84Parameters() const; // throw(io::FormattingException)
+
+ PROJ_INTERNAL const std::string &getHeightToGeographic3DFilename() const;
+
+ PROJ_INTERNAL bool isLongitudeRotation() const;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL Transformation(
+ const crs::CRSNNPtr &sourceCRSIn, const crs::CRSNNPtr &targetCRSIn,
+ const crs::CRSPtr &interpolationCRSIn,
+ const OperationMethodNNPtr &methodIn,
+ const std::vector<GeneralParameterValueNNPtr> &values,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL TransformationNNPtr inverseAsTransformation() const;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ Transformation(const Transformation &) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class PointMotionOperation;
+/** Shared pointer of PointMotionOperation */
+using PointMotionOperationPtr = std::shared_ptr<PointMotionOperation>;
+/** Non-null shared pointer of PointMotionOperation */
+using PointMotionOperationNNPtr = util::nn<PointMotionOperationPtr>;
+
+/** \brief A mathematical operation that describes the change of coordinate
+ * values within one coordinate reference system due to the motion of the
+ * point between one coordinate epoch and another coordinate epoch.
+ *
+ * The motion is due to tectonic plate movement or deformation.
+ *
+ * \remark Implements PointMotionOperation from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL PointMotionOperation : public SingleOperation {
+ public:
+ // TODO
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~PointMotionOperation() override;
+ //! @endcond
+
+ private:
+ PointMotionOperation(const PointMotionOperation &) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class ConcatenatedOperation;
+/** Shared pointer of ConcatenatedOperation */
+using ConcatenatedOperationPtr = std::shared_ptr<ConcatenatedOperation>;
+/** Non-null shared pointer of ConcatenatedOperation */
+using ConcatenatedOperationNNPtr = util::nn<ConcatenatedOperationPtr>;
+
+/** \brief An ordered sequence of two or more single coordinate operations
+ * (SingleOperation).
+ *
+ * The sequence of coordinate operations is constrained by the requirement
+ * that
+ * the source coordinate reference system of step n+1 shall be the same as
+ * the target coordinate reference system of step n.
+ *
+ * \remark Implements ConcatenatedOperation from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL ConcatenatedOperation final : public CoordinateOperation {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~ConcatenatedOperation() override;
+ //! @endcond
+
+ PROJ_DLL const std::vector<CoordinateOperationNNPtr> &operations() const;
+
+ PROJ_DLL CoordinateOperationNNPtr inverse() const override;
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ PROJ_DLL static ConcatenatedOperationNNPtr
+ create(const util::PropertyMap &properties,
+ const std::vector<CoordinateOperationNNPtr> &operationsIn,
+ const std::vector<metadata::PositionalAccuracyNNPtr>
+ &accuracies); // throw InvalidOperation
+
+ PROJ_DLL static CoordinateOperationNNPtr createComputeMetadata(
+ const std::vector<CoordinateOperationNNPtr> &operationsIn,
+ bool checkExtent); // throw InvalidOperation
+
+ PROJ_DLL std::set<GridDescription>
+ gridsNeeded(const io::DatabaseContextPtr &databaseContext) const override;
+
+ protected:
+ PROJ_INTERNAL explicit ConcatenatedOperation(
+ const std::vector<CoordinateOperationNNPtr> &operationsIn);
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ ConcatenatedOperation &
+ operator=(const ConcatenatedOperation &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class CoordinateOperationContext;
+/** Unique pointer of CoordinateOperationContext */
+using CoordinateOperationContextPtr =
+ std::unique_ptr<CoordinateOperationContext>;
+/** Non-null unique pointer of CoordinateOperationContext */
+using CoordinateOperationContextNNPtr = util::nn<CoordinateOperationContextPtr>;
+
+/** \brief Context in which a coordinate operation is to be used.
+ *
+ * \remark Implements [CoordinateOperationFactory
+ * https://sis.apache.org/apidocs/org/apache/sis/referencing/operation/CoordinateOperationContext.html]
+ * from
+ * Apache SIS
+ */
+
+class PROJ_GCC_DLL CoordinateOperationContext {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL virtual ~CoordinateOperationContext();
+ //! @endcond
+
+ PROJ_DLL const io::AuthorityFactoryPtr &getAuthorityFactory() const;
+
+ PROJ_DLL const metadata::ExtentPtr &getAreaOfInterest() const;
+
+ PROJ_DLL void setAreaOfInterest(const metadata::ExtentPtr &extent);
+
+ PROJ_DLL double getDesiredAccuracy() const;
+
+ PROJ_DLL void setDesiredAccuracy(double accuracy);
+
+ /** Specify how source and target CRS extent should be used to restrict
+ * candidate operations (only taken into account if no explicit area of
+ * interest is specified. */
+ enum class SourceTargetCRSExtentUse {
+ /** Ignore CRS extent */
+ NONE,
+ /** Test coordinate operation extent against both CRS extent. */
+ BOTH,
+ /** Test coordinate operation extent against the intersection of both
+ CRS extent. */
+ INTERSECTION,
+ /** Test coordinate operation against the smallest of both CRS extent.
+ */
+ SMALLEST,
+ };
+
+ PROJ_DLL void setSourceAndTargetCRSExtentUse(SourceTargetCRSExtentUse use);
+
+ PROJ_DLL SourceTargetCRSExtentUse getSourceAndTargetCRSExtentUse() const;
+
+ /** Spatial criterion to restrict candiate operations. */
+ enum class SpatialCriterion {
+ /** The area of validity of transforms should strictly contain the
+ * are of interest. */
+ STRICT_CONTAINMENT,
+
+ /** The area of validity of transforms should at least intersect the
+ * area of interest. */
+ PARTIAL_INTERSECTION
+ };
+
+ PROJ_DLL void setSpatialCriterion(SpatialCriterion criterion);
+
+ PROJ_DLL SpatialCriterion getSpatialCriterion() const;
+
+ PROJ_DLL void setUsePROJAlternativeGridNames(bool usePROJNames);
+
+ PROJ_DLL bool getUsePROJAlternativeGridNames() const;
+
+ /** Describe how grid availability is used. */
+ enum class GridAvailabilityUse {
+ /** Grid availability is only used for sorting results. Operations
+ * where some grids are missing will be sorted last. */
+ USE_FOR_SORTING,
+
+ /** Completely discard an operation if a required grid is missing. */
+ DISCARD_OPERATION_IF_MISSING_GRID,
+
+ /** Ignore grid availability at all. Results will be presented as if
+ * all grids were available. */
+ IGNORE_GRID_AVAILABILITY,
+ };
+
+ PROJ_DLL void setGridAvailabilityUse(GridAvailabilityUse use);
+
+ PROJ_DLL GridAvailabilityUse getGridAvailabilityUse() const;
+
+ PROJ_DLL void setAllowUseIntermediateCRS(bool use);
+
+ PROJ_DLL bool getAllowUseIntermediateCRS() const;
+
+ PROJ_DLL void
+ setIntermediateCRS(const std::vector<std::pair<std::string, std::string>>
+ &intermediateCRSAuthCodes);
+
+ PROJ_DLL const std::vector<std::pair<std::string, std::string>> &
+ getIntermediateCRS() const;
+
+ PROJ_DLL static CoordinateOperationContextNNPtr
+ create(const io::AuthorityFactoryPtr &authorityFactory,
+ const metadata::ExtentPtr &extent, double accuracy);
+
+ protected:
+ PROJ_INTERNAL CoordinateOperationContext();
+ INLINED_MAKE_UNIQUE
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class CoordinateOperationFactory;
+/** Unique pointer of CoordinateOperationFactory */
+using CoordinateOperationFactoryPtr =
+ std::unique_ptr<CoordinateOperationFactory>;
+/** Non-null unique pointer of CoordinateOperationFactory */
+using CoordinateOperationFactoryNNPtr = util::nn<CoordinateOperationFactoryPtr>;
+
+/** \brief Creates coordinate operations. This factory is capable to find
+ * coordinate transformations or conversions between two coordinate
+ * reference
+ * systems.
+ *
+ * \remark Implements (partially) CoordinateOperationFactory from \ref
+ * GeoAPI
+ */
+class PROJ_GCC_DLL CoordinateOperationFactory {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL virtual ~CoordinateOperationFactory();
+ //! @endcond
+
+ PROJ_DLL CoordinateOperationPtr createOperation(
+ const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS) const;
+
+ PROJ_DLL std::vector<CoordinateOperationNNPtr>
+ createOperations(const crs::CRSNNPtr &sourceCRS,
+ const crs::CRSNNPtr &targetCRS,
+ const CoordinateOperationContextNNPtr &context) const;
+
+ PROJ_DLL static CoordinateOperationFactoryNNPtr create();
+
+ protected:
+ PROJ_INTERNAL CoordinateOperationFactory();
+ INLINED_MAKE_UNIQUE
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+} // namespace operation
+
+NS_PROJ_END
+
+#endif // COORDINATEOPERATION_HH_INCLUDED
diff --git a/include/proj/coordinatesystem.hpp b/include/proj/coordinatesystem.hpp
new file mode 100644
index 00000000..89c2f99c
--- /dev/null
+++ b/include/proj/coordinatesystem.hpp
@@ -0,0 +1,701 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef CS_HH_INCLUDED
+#define CS_HH_INCLUDED
+
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "common.hpp"
+#include "io.hpp"
+#include "util.hpp"
+
+NS_PROJ_START
+
+/** osgeo.proj.cs namespace
+
+ \brief Coordinate systems and their axis.
+*/
+namespace cs {
+
+// ---------------------------------------------------------------------------
+
+/** \brief The direction of positive increase in the coordinate value for a
+ * coordinate system axis.
+ *
+ * \remark Implements AxisDirection from \ref ISO_19111_2018
+ */
+class AxisDirection : public util::CodeList {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL static const AxisDirection *
+ valueOf(const std::string &nameIn) noexcept;
+ //! @endcond
+
+ PROJ_DLL static const AxisDirection NORTH;
+ PROJ_DLL static const AxisDirection NORTH_NORTH_EAST;
+ PROJ_DLL static const AxisDirection NORTH_EAST;
+ PROJ_DLL static const AxisDirection EAST_NORTH_EAST;
+ PROJ_DLL static const AxisDirection EAST;
+ PROJ_DLL static const AxisDirection EAST_SOUTH_EAST;
+ PROJ_DLL static const AxisDirection SOUTH_EAST;
+ PROJ_DLL static const AxisDirection SOUTH_SOUTH_EAST;
+ PROJ_DLL static const AxisDirection SOUTH;
+ PROJ_DLL static const AxisDirection SOUTH_SOUTH_WEST;
+ PROJ_DLL static const AxisDirection SOUTH_WEST;
+ PROJ_DLL static const AxisDirection
+ WEST_SOUTH_WEST; // note: was forgotten in WKT2-2015
+ PROJ_DLL static const AxisDirection WEST;
+ PROJ_DLL static const AxisDirection WEST_NORTH_WEST;
+ PROJ_DLL static const AxisDirection NORTH_WEST;
+ PROJ_DLL static const AxisDirection NORTH_NORTH_WEST;
+ PROJ_DLL static const AxisDirection UP;
+ PROJ_DLL static const AxisDirection DOWN;
+ PROJ_DLL static const AxisDirection GEOCENTRIC_X;
+ PROJ_DLL static const AxisDirection GEOCENTRIC_Y;
+ PROJ_DLL static const AxisDirection GEOCENTRIC_Z;
+ PROJ_DLL static const AxisDirection COLUMN_POSITIVE;
+ PROJ_DLL static const AxisDirection COLUMN_NEGATIVE;
+ PROJ_DLL static const AxisDirection ROW_POSITIVE;
+ PROJ_DLL static const AxisDirection ROW_NEGATIVE;
+ PROJ_DLL static const AxisDirection DISPLAY_RIGHT;
+ PROJ_DLL static const AxisDirection DISPLAY_LEFT;
+ PROJ_DLL static const AxisDirection DISPLAY_UP;
+ PROJ_DLL static const AxisDirection DISPLAY_DOWN;
+ PROJ_DLL static const AxisDirection FORWARD;
+ PROJ_DLL static const AxisDirection AFT;
+ PROJ_DLL static const AxisDirection PORT;
+ PROJ_DLL static const AxisDirection STARBOARD;
+ PROJ_DLL static const AxisDirection CLOCKWISE;
+ PROJ_DLL static const AxisDirection COUNTER_CLOCKWISE;
+ PROJ_DLL static const AxisDirection TOWARDS;
+ PROJ_DLL static const AxisDirection AWAY_FROM;
+ PROJ_DLL static const AxisDirection FUTURE;
+ PROJ_DLL static const AxisDirection PAST;
+ PROJ_DLL static const AxisDirection UNSPECIFIED;
+
+ private:
+ explicit AxisDirection(const std::string &nameIn);
+
+ static std::map<std::string, const AxisDirection *> registry;
+};
+
+// ---------------------------------------------------------------------------
+
+class Meridian;
+/** Shared pointer of Meridian. */
+using MeridianPtr = std::shared_ptr<Meridian>;
+/** Non-null shared pointer of Meridian. */
+using MeridianNNPtr = util::nn<MeridianPtr>;
+
+/** \brief The meridian that the axis follows from the pole, for a coordinate
+ * reference system centered on a pole.
+ *
+ * \note There is no modelling for this concept in \ref ISO_19111_2018
+ *
+ * \remark Implements MERIDIAN from \ref WKT2
+ */
+class PROJ_GCC_DLL Meridian : public common::IdentifiedObject {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~Meridian() override;
+ //! @endcond
+
+ PROJ_DLL const common::Angle &longitude() PROJ_CONST_DECL;
+
+ // non-standard
+ PROJ_DLL static MeridianNNPtr create(const common::Angle &longitudeIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+#ifdef DOXYGEN_ENABLED
+ Angle angle_;
+#endif
+
+ PROJ_INTERNAL explicit Meridian(const common::Angle &longitudeIn);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ Meridian(const Meridian &other) = delete;
+ Meridian &operator=(const Meridian &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class CoordinateSystemAxis;
+/** Shared pointer of CoordinateSystemAxis. */
+using CoordinateSystemAxisPtr = std::shared_ptr<CoordinateSystemAxis>;
+/** Non-null shared pointer of CoordinateSystemAxis. */
+using CoordinateSystemAxisNNPtr = util::nn<CoordinateSystemAxisPtr>;
+
+/** \brief The definition of a coordinate system axis.
+ *
+ * \remark Implements CoordinateSystemAxis from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL CoordinateSystemAxis final
+ : public common::IdentifiedObject {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~CoordinateSystemAxis() override;
+ //! @endcond
+
+ PROJ_DLL const std::string &abbreviation() PROJ_CONST_DECL;
+ PROJ_DLL const AxisDirection &direction() PROJ_CONST_DECL;
+ PROJ_DLL const common::UnitOfMeasure &unit() PROJ_CONST_DECL;
+ PROJ_DLL const util::optional<double> &minimumValue() PROJ_CONST_DECL;
+ PROJ_DLL const util::optional<double> &maximumValue() PROJ_CONST_DECL;
+ PROJ_DLL const MeridianPtr &meridian() PROJ_CONST_DECL;
+
+ // Non-standard
+ PROJ_DLL static CoordinateSystemAxisNNPtr
+ create(const util::PropertyMap &properties,
+ const std::string &abbreviationIn, const AxisDirection &directionIn,
+ const common::UnitOfMeasure &unitIn,
+ const MeridianPtr &meridianIn = nullptr);
+
+ PROJ_PRIVATE :
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool
+ _isEquivalentTo(
+ const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter, int order,
+ bool disableAbbrev) const;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL static std::string normalizeAxisName(const std::string &str);
+
+ PROJ_INTERNAL static CoordinateSystemAxisNNPtr
+ createLAT_NORTH(const common::UnitOfMeasure &unit);
+ PROJ_INTERNAL static CoordinateSystemAxisNNPtr
+ createLONG_EAST(const common::UnitOfMeasure &unit);
+
+ //! @endcond
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ CoordinateSystemAxis(const CoordinateSystemAxis &other) = delete;
+ CoordinateSystemAxis &operator=(const CoordinateSystemAxis &other) = delete;
+
+ PROJ_INTERNAL CoordinateSystemAxis();
+ /* cppcheck-suppress unusedPrivateFunction */
+ INLINED_MAKE_SHARED
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Abstract class modelling a coordinate system (CS)
+ *
+ * A CS is the non-repeating sequence of coordinate system axes that spans a
+ * given coordinate space. A CS is derived from a set of mathematical rules for
+ * specifying how coordinates in a given space are to be assigned to points.
+ * The coordinate values in a coordinate tuple shall be recorded in the order
+ * in which the coordinate system axes associations are recorded.
+ *
+ * \remark Implements CoordinateSystem from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL CoordinateSystem : public common::IdentifiedObject {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~CoordinateSystem() override;
+ //! @endcond
+
+ PROJ_DLL const std::vector<CoordinateSystemAxisNNPtr> &
+ axisList() PROJ_CONST_DECL;
+
+ PROJ_PRIVATE :
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void
+ _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL virtual std::string getWKT2Type(bool) const = 0;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL explicit CoordinateSystem(
+ const std::vector<CoordinateSystemAxisNNPtr> &axisIn);
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ CoordinateSystem(const CoordinateSystem &other) = delete;
+ CoordinateSystem &operator=(const CoordinateSystem &other) = delete;
+};
+
+/** Shared pointer of CoordinateSystem. */
+using CoordinateSystemPtr = std::shared_ptr<CoordinateSystem>;
+/** Non-null shared pointer of CoordinateSystem. */
+using CoordinateSystemNNPtr = util::nn<CoordinateSystemPtr>;
+
+// ---------------------------------------------------------------------------
+
+class SphericalCS;
+/** Shared pointer of SphericalCS. */
+using SphericalCSPtr = std::shared_ptr<SphericalCS>;
+/** Non-null shared pointer of SphericalCS. */
+using SphericalCSNNPtr = util::nn<SphericalCSPtr>;
+
+/** \brief A three-dimensional coordinate system in Euclidean space with one
+ * distance measured from the origin and two angular coordinates.
+ *
+ * Not to be confused with an ellipsoidal coordinate system based on an
+ * ellipsoid "degenerated" into a sphere. A SphericalCS shall have three
+ * axis associations.
+ *
+ * \remark Implements SphericalCS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL SphericalCS final : public CoordinateSystem {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~SphericalCS() override;
+ //! @endcond
+
+ // non-standard
+
+ PROJ_DLL static SphericalCSNNPtr
+ create(const util::PropertyMap &properties,
+ const CoordinateSystemAxisNNPtr &axis1,
+ const CoordinateSystemAxisNNPtr &axis2,
+ const CoordinateSystemAxisNNPtr &axis3);
+
+ protected:
+ PROJ_INTERNAL explicit SphericalCS(
+ const std::vector<CoordinateSystemAxisNNPtr> &axisIn);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL std::string getWKT2Type(bool) const override {
+ return "spherical";
+ }
+
+ private:
+ SphericalCS(const SphericalCS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class EllipsoidalCS;
+/** Shared pointer of EllipsoidalCS. */
+using EllipsoidalCSPtr = std::shared_ptr<EllipsoidalCS>;
+/** Non-null shared pointer of EllipsoidalCS. */
+using EllipsoidalCSNNPtr = util::nn<EllipsoidalCSPtr>;
+
+/** \brief A two- or three-dimensional coordinate system in which position is
+ * specified by geodetic latitude, geodetic longitude, and (in the
+ * three-dimensional case) ellipsoidal height.
+ *
+ * An EllipsoidalCS shall have two or three associations.
+ *
+ * \remark Implements EllipsoidalCS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL EllipsoidalCS final : public CoordinateSystem {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~EllipsoidalCS() override;
+ //! @endcond
+
+ // non-standard
+ PROJ_DLL static EllipsoidalCSNNPtr
+ create(const util::PropertyMap &properties,
+ const CoordinateSystemAxisNNPtr &axis1,
+ const CoordinateSystemAxisNNPtr &axis2);
+ PROJ_DLL static EllipsoidalCSNNPtr
+ create(const util::PropertyMap &properties,
+ const CoordinateSystemAxisNNPtr &axis1,
+ const CoordinateSystemAxisNNPtr &axis2,
+ const CoordinateSystemAxisNNPtr &axis3);
+ PROJ_DLL static EllipsoidalCSNNPtr
+ createLatitudeLongitude(const common::UnitOfMeasure &unit);
+ PROJ_DLL static EllipsoidalCSNNPtr createLatitudeLongitudeEllipsoidalHeight(
+ const common::UnitOfMeasure &angularUnit,
+ const common::UnitOfMeasure &linearUnit);
+ PROJ_DLL static EllipsoidalCSNNPtr
+ createLongitudeLatitude(const common::UnitOfMeasure &unit);
+
+ //! @cond Doxygen_Suppress
+
+ /** \brief Typical axis order. */
+ enum class AxisOrder {
+ /** Latitude(North), Longitude(East) */
+ LAT_NORTH_LONG_EAST,
+ /** Latitude(North), Longitude(East), Height(up) */
+ LAT_NORTH_LONG_EAST_HEIGHT_UP,
+ /** Longitude(East), Latitude(North) */
+ LONG_EAST_LAT_NORTH,
+ /** Longitude(East), Latitude(North), Height(up) */
+ LONG_EAST_LAT_NORTH_HEIGHT_UP,
+ /** Other axis order. */
+ OTHER
+ };
+
+ PROJ_INTERNAL AxisOrder axisOrder() const;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL explicit EllipsoidalCS(
+ const std::vector<CoordinateSystemAxisNNPtr> &axisIn);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL std::string getWKT2Type(bool) const override {
+ return "ellipsoidal";
+ }
+
+ protected:
+ EllipsoidalCS(const EllipsoidalCS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class VerticalCS;
+/** Shared pointer of VerticalCS. */
+using VerticalCSPtr = std::shared_ptr<VerticalCS>;
+/** Non-null shared pointer of VerticalCS. */
+using VerticalCSNNPtr = util::nn<VerticalCSPtr>;
+
+/** \brief A one-dimensional coordinate system used to record the heights or
+ * depths of points.
+ *
+ * Such a coordinate system is usually dependent on the Earth's gravity field.
+ * A VerticalCS shall have one axis association.
+ *
+ * \remark Implements VerticalCS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL VerticalCS final : public CoordinateSystem {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~VerticalCS() override;
+ //! @endcond
+
+ PROJ_DLL static VerticalCSNNPtr
+ create(const util::PropertyMap &properties,
+ const CoordinateSystemAxisNNPtr &axis);
+
+ PROJ_DLL static VerticalCSNNPtr
+ createGravityRelatedHeight(const common::UnitOfMeasure &unit);
+
+ protected:
+ PROJ_INTERNAL explicit VerticalCS(const CoordinateSystemAxisNNPtr &axisIn);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL std::string getWKT2Type(bool) const override {
+ return "vertical";
+ }
+
+ private:
+ VerticalCS(const VerticalCS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class CartesianCS;
+/** Shared pointer of CartesianCS. */
+using CartesianCSPtr = std::shared_ptr<CartesianCS>;
+/** Non-null shared pointer of CartesianCS. */
+using CartesianCSNNPtr = util::nn<CartesianCSPtr>;
+
+/** \brief A two- or three-dimensional coordinate system in Euclidean space
+ * with orthogonal straight axes.
+ *
+ * All axes shall have the same length unit. A CartesianCS shall have two or
+ * three axis associations; the number of associations shall equal the
+ * dimension of the CS.
+ *
+ * \remark Implements CartesianCS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL CartesianCS final : public CoordinateSystem {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~CartesianCS() override;
+ //! @endcond
+
+ PROJ_DLL static CartesianCSNNPtr
+ create(const util::PropertyMap &properties,
+ const CoordinateSystemAxisNNPtr &axis1,
+ const CoordinateSystemAxisNNPtr &axis2);
+ PROJ_DLL static CartesianCSNNPtr
+ create(const util::PropertyMap &properties,
+ const CoordinateSystemAxisNNPtr &axis1,
+ const CoordinateSystemAxisNNPtr &axis2,
+ const CoordinateSystemAxisNNPtr &axis3);
+ PROJ_DLL static CartesianCSNNPtr
+ createEastingNorthing(const common::UnitOfMeasure &unit);
+ PROJ_DLL static CartesianCSNNPtr
+ createGeocentric(const common::UnitOfMeasure &unit);
+
+ protected:
+ PROJ_INTERNAL explicit CartesianCS(
+ const std::vector<CoordinateSystemAxisNNPtr> &axisIn);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL std::string getWKT2Type(bool) const override {
+ return "Cartesian"; // uppercase is intended
+ }
+
+ private:
+ CartesianCS(const CartesianCS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class OrdinalCS;
+/** Shared pointer of OrdinalCS. */
+using OrdinalCSPtr = std::shared_ptr<OrdinalCS>;
+/** Non-null shared pointer of OrdinalCS. */
+using OrdinalCSNNPtr = util::nn<OrdinalCSPtr>;
+
+/** \brief n-dimensional coordinate system in which every axis uses integers.
+ *
+ * The number of associations shall equal the
+ * dimension of the CS.
+ *
+ * \remark Implements OrdinalCS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL OrdinalCS final : public CoordinateSystem {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~OrdinalCS() override;
+ //! @endcond
+
+ PROJ_DLL static OrdinalCSNNPtr
+ create(const util::PropertyMap &properties,
+ const std::vector<CoordinateSystemAxisNNPtr> &axisIn);
+
+ protected:
+ PROJ_INTERNAL explicit OrdinalCS(
+ const std::vector<CoordinateSystemAxisNNPtr> &axisIn);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL std::string getWKT2Type(bool) const override {
+ return "ordinal";
+ }
+
+ private:
+ OrdinalCS(const OrdinalCS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class ParametricCS;
+/** Shared pointer of ParametricCS. */
+using ParametricCSPtr = std::shared_ptr<ParametricCS>;
+/** Non-null shared pointer of ParametricCS. */
+using ParametricCSNNPtr = util::nn<ParametricCSPtr>;
+
+/** \brief one-dimensional coordinate reference system which uses parameter
+ * values or functions that may vary monotonically with height.
+ *
+ * \remark Implements ParametricCS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL ParametricCS final : public CoordinateSystem {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~ParametricCS() override;
+ //! @endcond
+
+ PROJ_DLL static ParametricCSNNPtr
+ create(const util::PropertyMap &properties,
+ const CoordinateSystemAxisNNPtr &axisIn);
+
+ protected:
+ PROJ_INTERNAL explicit ParametricCS(
+ const std::vector<CoordinateSystemAxisNNPtr> &axisIn);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL std::string getWKT2Type(bool) const override {
+ return "parametric";
+ }
+
+ private:
+ ParametricCS(const ParametricCS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class TemporalCS;
+/** Shared pointer of TemporalCS. */
+using TemporalCSPtr = std::shared_ptr<TemporalCS>;
+/** Non-null shared pointer of TemporalCS. */
+using TemporalCSNNPtr = util::nn<TemporalCSPtr>;
+
+/** \brief (Abstract class) A one-dimensional coordinate system used to record
+ * time.
+ *
+ * A TemporalCS shall have one axis association.
+ *
+ * \remark Implements TemporalCS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL TemporalCS : public CoordinateSystem {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~TemporalCS() override;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL explicit TemporalCS(const CoordinateSystemAxisNNPtr &axis);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL std::string
+ getWKT2Type(bool use2018Keywords) const override = 0;
+
+ private:
+ TemporalCS(const TemporalCS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class DateTimeTemporalCS;
+/** Shared pointer of DateTimeTemporalCS. */
+using DateTimeTemporalCSPtr = std::shared_ptr<DateTimeTemporalCS>;
+/** Non-null shared pointer of DateTimeTemporalCS. */
+using DateTimeTemporalCSNNPtr = util::nn<DateTimeTemporalCSPtr>;
+
+/** \brief A one-dimensional coordinate system used to record time in dateTime
+ * representation as defined in ISO 8601.
+ *
+ * A DateTimeTemporalCS shall have one axis association. It does not use
+ * axisUnitID; the temporal quantities are defined through the ISO 8601
+ * representation.
+ *
+ * \remark Implements DateTimeTemporalCS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL DateTimeTemporalCS final : public TemporalCS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DateTimeTemporalCS() override;
+ //! @endcond
+
+ PROJ_DLL static DateTimeTemporalCSNNPtr
+ create(const util::PropertyMap &properties,
+ const CoordinateSystemAxisNNPtr &axis);
+
+ protected:
+ PROJ_INTERNAL explicit DateTimeTemporalCS(
+ const CoordinateSystemAxisNNPtr &axis);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL std::string getWKT2Type(bool use2018Keywords) const override;
+
+ private:
+ DateTimeTemporalCS(const DateTimeTemporalCS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class TemporalCountCS;
+/** Shared pointer of TemporalCountCS. */
+using TemporalCountCSPtr = std::shared_ptr<TemporalCountCS>;
+/** Non-null shared pointer of TemporalCountCS. */
+using TemporalCountCSNNPtr = util::nn<TemporalCountCSPtr>;
+
+/** \brief A one-dimensional coordinate system used to record time as an
+ * integer count.
+ *
+ * A TemporalCountCS shall have one axis association.
+ *
+ * \remark Implements TemporalCountCS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL TemporalCountCS final : public TemporalCS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~TemporalCountCS() override;
+ //! @endcond
+
+ PROJ_DLL static TemporalCountCSNNPtr
+ create(const util::PropertyMap &properties,
+ const CoordinateSystemAxisNNPtr &axis);
+
+ protected:
+ PROJ_INTERNAL explicit TemporalCountCS(
+ const CoordinateSystemAxisNNPtr &axis);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL std::string getWKT2Type(bool use2018Keywords) const override;
+
+ private:
+ TemporalCountCS(const TemporalCountCS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class TemporalMeasureCS;
+/** Shared pointer of TemporalMeasureCS. */
+using TemporalMeasureCSPtr = std::shared_ptr<TemporalMeasureCS>;
+/** Non-null shared pointer of TemporalMeasureCS. */
+using TemporalMeasureCSNNPtr = util::nn<TemporalMeasureCSPtr>;
+
+/** \brief A one-dimensional coordinate system used to record a time as a
+ * real number.
+ *
+ * A TemporalMeasureCS shall have one axis association.
+ *
+ * \remark Implements TemporalMeasureCS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL TemporalMeasureCS final : public TemporalCS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~TemporalMeasureCS() override;
+ //! @endcond
+
+ PROJ_DLL static TemporalMeasureCSNNPtr
+ create(const util::PropertyMap &properties,
+ const CoordinateSystemAxisNNPtr &axis);
+
+ protected:
+ PROJ_INTERNAL explicit TemporalMeasureCS(
+ const CoordinateSystemAxisNNPtr &axis);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL std::string getWKT2Type(bool use2018Keywords) const override;
+
+ private:
+ TemporalMeasureCS(const TemporalMeasureCS &other) = delete;
+};
+
+} // namespace cs
+
+NS_PROJ_END
+
+#endif // CS_HH_INCLUDED
diff --git a/include/proj/crs.hpp b/include/proj/crs.hpp
new file mode 100644
index 00000000..252c90e3
--- /dev/null
+++ b/include/proj/crs.hpp
@@ -0,0 +1,1361 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef CRS_HH_INCLUDED
+#define CRS_HH_INCLUDED
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "common.hpp"
+#include "coordinateoperation.hpp"
+#include "coordinatesystem.hpp"
+#include "datum.hpp"
+#include "io.hpp"
+#include "util.hpp"
+
+NS_PROJ_START
+
+/** osgeo.proj.crs namespace
+
+ \brief CRS (coordinate reference system = coordinate system with a datum).
+*/
+namespace crs {
+
+// ---------------------------------------------------------------------------
+
+class GeographicCRS;
+/** Shared pointer of GeographicCRS */
+using GeographicCRSPtr = std::shared_ptr<GeographicCRS>;
+/** Non-null shared pointer of GeographicCRS */
+using GeographicCRSNNPtr = util::nn<GeographicCRSPtr>;
+
+class VerticalCRS;
+/** Shared pointer of VerticalCRS */
+using VerticalCRSPtr = std::shared_ptr<VerticalCRS>;
+/** Non-null shared pointer of VerticalCRS */
+using VerticalCRSNNPtr = util::nn<VerticalCRSPtr>;
+
+class BoundCRS;
+/** Shared pointer of BoundCRS */
+using BoundCRSPtr = std::shared_ptr<BoundCRS>;
+/** Non-null shared pointer of BoundCRS */
+using BoundCRSNNPtr = util::nn<BoundCRSPtr>;
+
+// ---------------------------------------------------------------------------
+
+class CRS;
+/** Shared pointer of CRS */
+using CRSPtr = std::shared_ptr<CRS>;
+/** Non-null shared pointer of CRS */
+using CRSNNPtr = util::nn<CRSPtr>;
+
+/** \brief Abstract class modelling a coordinate reference system which is
+ * usually single but may be compound.
+ *
+ * \remark Implements CRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL CRS : public common::ObjectUsage {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~CRS() override;
+ //! @endcond
+
+ // Non-standard
+
+ PROJ_DLL GeodeticCRSPtr extractGeodeticCRS() const;
+ PROJ_DLL GeographicCRSPtr extractGeographicCRS() const;
+ PROJ_DLL VerticalCRSPtr extractVerticalCRS() const;
+ PROJ_DLL CRSNNPtr createBoundCRSToWGS84IfPossible(
+ const io::DatabaseContextPtr &dbContext) const;
+ PROJ_DLL CRSNNPtr stripVerticalComponent() const;
+
+ PROJ_DLL const BoundCRSPtr &canonicalBoundCRS() PROJ_CONST_DECL;
+
+ PROJ_DLL std::list<std::pair<CRSNNPtr, int>>
+ identify(const io::AuthorityFactoryPtr &authorityFactory) const;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL const GeodeticCRS *
+ extractGeodeticCRSRaw() const;
+
+ PROJ_FOR_TEST CRSNNPtr shallowClone() const;
+
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL CRS();
+ PROJ_INTERNAL CRS(const CRS &other);
+ friend class BoundCRS;
+ PROJ_INTERNAL void setCanonicalBoundCRS(const BoundCRSNNPtr &boundCRS);
+
+ PROJ_INTERNAL virtual CRSNNPtr _shallowClone() const = 0;
+
+ PROJ_INTERNAL virtual std::list<std::pair<CRSNNPtr, int>>
+ _identify(const io::AuthorityFactoryPtr &authorityFactory) const;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Abstract class modelling a coordinate reference system consisting of
+ * one Coordinate System and either one datum::Datum or one
+ * datum::DatumEnsemble.
+ *
+ * \remark Implements SingleCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL SingleCRS : public CRS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~SingleCRS() override;
+ //! @endcond
+
+ PROJ_DLL const datum::DatumPtr &datum() PROJ_CONST_DECL;
+ PROJ_DLL const datum::DatumEnsemblePtr &datumEnsemble() PROJ_CONST_DECL;
+ PROJ_DLL const cs::CoordinateSystemNNPtr &
+ coordinateSystem() PROJ_CONST_DECL;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void
+ exportDatumOrDatumEnsembleToWkt(io::WKTFormatter *formatter)
+ const; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL SingleCRS(const datum::DatumPtr &datumIn,
+ const datum::DatumEnsemblePtr &datumEnsembleIn,
+ const cs::CoordinateSystemNNPtr &csIn);
+ PROJ_INTERNAL SingleCRS(const SingleCRS &other);
+
+ PROJ_INTERNAL bool
+ baseIsEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ SingleCRS &operator=(const SingleCRS &other) = delete;
+};
+
+/** Shared pointer of SingleCRS */
+using SingleCRSPtr = std::shared_ptr<SingleCRS>;
+/** Non-null shared pointer of SingleCRS */
+using SingleCRSNNPtr = util::nn<SingleCRSPtr>;
+
+// ---------------------------------------------------------------------------
+
+class GeodeticCRS;
+/** Shared pointer of GeodeticCRS */
+using GeodeticCRSPtr = std::shared_ptr<GeodeticCRS>;
+/** Non-null shared pointer of GeodeticCRS */
+using GeodeticCRSNNPtr = util::nn<GeodeticCRSPtr>;
+
+/** \brief A coordinate reference system associated with a geodetic reference
+ * frame and a three-dimensional Cartesian or spherical coordinate system.
+ *
+ * If the geodetic reference frame is dynamic or if the geodetic CRS has an
+ * association to a velocity model then the geodetic CRS is dynamic, else it
+ * is static.
+ *
+ * \remark Implements GeodeticCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL GeodeticCRS : virtual public SingleCRS,
+ public io::IPROJStringExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~GeodeticCRS() override;
+ //! @endcond
+
+ PROJ_DLL const datum::GeodeticReferenceFramePtr &datum() PROJ_CONST_DECL;
+
+ PROJ_DLL const datum::PrimeMeridianNNPtr &primeMeridian() PROJ_CONST_DECL;
+ PROJ_DLL const datum::EllipsoidNNPtr &ellipsoid() PROJ_CONST_DECL;
+
+ // coordinateSystem() returns either a EllipsoidalCS, SphericalCS or
+ // CartesianCS
+
+ PROJ_DLL const std::vector<operation::PointMotionOperationNNPtr> &
+ velocityModel() PROJ_CONST_DECL;
+
+ // Non-standard
+
+ PROJ_DLL bool isGeocentric() PROJ_CONST_DECL;
+
+ PROJ_DLL static GeodeticCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::GeodeticReferenceFrameNNPtr &datum,
+ const cs::SphericalCSNNPtr &cs);
+
+ PROJ_DLL static GeodeticCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::GeodeticReferenceFrameNNPtr &datum,
+ const cs::CartesianCSNNPtr &cs);
+
+ PROJ_DLL static GeodeticCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::GeodeticReferenceFramePtr &datum,
+ const datum::DatumEnsemblePtr &datumEnsemble,
+ const cs::SphericalCSNNPtr &cs);
+
+ PROJ_DLL static GeodeticCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::GeodeticReferenceFramePtr &datum,
+ const datum::DatumEnsemblePtr &datumEnsemble,
+ const cs::CartesianCSNNPtr &cs);
+
+ PROJ_DLL static const GeodeticCRSNNPtr EPSG_4978; // WGS 84 Geocentric
+
+ PROJ_DLL std::list<std::pair<GeodeticCRSNNPtr, int>>
+ identify(const io::AuthorityFactoryPtr &authorityFactory) const;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void
+ addDatumInfoToPROJString(io::PROJStringFormatter *formatter) const;
+
+ PROJ_INTERNAL void addGeocentricUnitConversionIntoPROJString(
+ io::PROJStringFormatter *formatter) const;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL GeodeticCRS(const datum::GeodeticReferenceFramePtr &datumIn,
+ const datum::DatumEnsemblePtr &datumEnsembleIn,
+ const cs::EllipsoidalCSNNPtr &csIn);
+ PROJ_INTERNAL GeodeticCRS(const datum::GeodeticReferenceFramePtr &datumIn,
+ const datum::DatumEnsemblePtr &datumEnsembleIn,
+ const cs::SphericalCSNNPtr &csIn);
+ PROJ_INTERNAL GeodeticCRS(const datum::GeodeticReferenceFramePtr &datumIn,
+ const datum::DatumEnsemblePtr &datumEnsembleIn,
+ const cs::CartesianCSNNPtr &csIn);
+ PROJ_INTERNAL GeodeticCRS(const GeodeticCRS &other);
+
+ PROJ_INTERNAL static GeodeticCRSNNPtr createEPSG_4978();
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
+ _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+
+ GeodeticCRS &operator=(const GeodeticCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief A coordinate reference system associated with a geodetic reference
+ * frame and a two- or three-dimensional ellipsoidal coordinate system.
+ *
+ * If the geodetic reference frame is dynamic or if the geographic CRS has an
+ * association to a velocity model then the geodetic CRS is dynamic, else it is
+ * static.
+ *
+ * \remark Implements GeographicCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL GeographicCRS : public GeodeticCRS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~GeographicCRS() override;
+ //! @endcond
+
+ PROJ_DLL const cs::EllipsoidalCSNNPtr &coordinateSystem() PROJ_CONST_DECL;
+
+ // Non-standard
+ PROJ_DLL static GeographicCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::GeodeticReferenceFrameNNPtr &datum,
+ const cs::EllipsoidalCSNNPtr &cs);
+ PROJ_DLL static GeographicCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::GeodeticReferenceFramePtr &datum,
+ const datum::DatumEnsemblePtr &datumEnsemble,
+ const cs::EllipsoidalCSNNPtr &cs);
+
+ PROJ_DLL static const GeographicCRSNNPtr EPSG_4267; // NAD27
+ PROJ_DLL static const GeographicCRSNNPtr EPSG_4269; // NAD83
+ PROJ_DLL static const GeographicCRSNNPtr EPSG_4326; // WGS 84 2D
+ PROJ_DLL static const GeographicCRSNNPtr OGC_CRS84; // CRS84 (Long, Lat)
+ PROJ_DLL static const GeographicCRSNNPtr EPSG_4807; // NTF Paris
+ PROJ_DLL static const GeographicCRSNNPtr EPSG_4979; // WGS 84 3D
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void
+ addAngularUnitConvertAndAxisSwap(
+ io::PROJStringFormatter *formatter) const;
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_DLL bool
+ is2DPartOf3D(util::nn<const GeographicCRS *> other) PROJ_CONST_DECL;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL GeographicCRS(const datum::GeodeticReferenceFramePtr &datumIn,
+ const datum::DatumEnsemblePtr &datumEnsembleIn,
+ const cs::EllipsoidalCSNNPtr &csIn);
+ PROJ_INTERNAL GeographicCRS(const GeographicCRS &other);
+
+ PROJ_INTERNAL static GeographicCRSNNPtr createEPSG_4267();
+ PROJ_INTERNAL static GeographicCRSNNPtr createEPSG_4269();
+ PROJ_INTERNAL static GeographicCRSNNPtr createEPSG_4326();
+ PROJ_INTERNAL static GeographicCRSNNPtr createOGC_CRS84();
+ PROJ_INTERNAL static GeographicCRSNNPtr createEPSG_4807();
+ PROJ_INTERNAL static GeographicCRSNNPtr createEPSG_4979();
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+
+ GeographicCRS &operator=(const GeographicCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief A coordinate reference system having a vertical reference frame and
+ * a one-dimensional vertical coordinate system used for recording
+ * gravity-related heights or depths.
+ *
+ * Vertical CRSs make use of the direction of gravity to define the concept of
+ * height or depth, but the relationship with gravity may not be
+ * straightforward. If the vertical reference frame is dynamic or if the
+ * vertical CRS has an association to a velocity model then the CRS is dynamic,
+ * else it is static.
+ *
+ * \note Ellipsoidal heights cannot be captured in a vertical coordinate
+ * reference system. They exist only as an inseparable part of a 3D coordinate
+ * tuple defined in a geographic 3D coordinate reference system.
+ *
+ * \remark Implements VerticalCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL VerticalCRS : virtual public SingleCRS,
+ public io::IPROJStringExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~VerticalCRS() override;
+ //! @endcond
+
+ PROJ_DLL const datum::VerticalReferenceFramePtr datum() const;
+ PROJ_DLL const cs::VerticalCSNNPtr coordinateSystem() const;
+ PROJ_DLL const std::vector<operation::TransformationNNPtr> &
+ geoidModel() PROJ_CONST_DECL;
+ PROJ_DLL const std::vector<operation::PointMotionOperationNNPtr> &
+ velocityModel() PROJ_CONST_DECL;
+
+ PROJ_DLL static VerticalCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::VerticalReferenceFrameNNPtr &datumIn,
+ const cs::VerticalCSNNPtr &csIn);
+
+ PROJ_DLL static VerticalCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::VerticalReferenceFramePtr &datumIn,
+ const datum::DatumEnsemblePtr &datumEnsembleIn,
+ const cs::VerticalCSNNPtr &csIn);
+
+ PROJ_DLL std::list<std::pair<VerticalCRSNNPtr, int>>
+ identify(const io::AuthorityFactoryPtr &authorityFactory) const;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void
+ addLinearUnitConvert(io::PROJStringFormatter *formatter) const;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL VerticalCRS(const datum::VerticalReferenceFramePtr &datumIn,
+ const datum::DatumEnsemblePtr &datumEnsembleIn,
+ const cs::VerticalCSNNPtr &csIn);
+ PROJ_INTERNAL VerticalCRS(const VerticalCRS &other);
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
+ _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
+
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ VerticalCRS &operator=(const VerticalCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Abstract class modelling a single coordinate reference system that
+ * is defined through the application of a specified coordinate conversion to
+ * the definition of a previously established single coordinate reference
+ * system referred to as the base CRS.
+ *
+ * A derived coordinate reference system inherits its datum (or datum ensemble)
+ * from its base CRS. The coordinate conversion between the base and derived
+ * coordinate reference system is implemented using the parameters and
+ * formula(s) specified in the definition of the coordinate conversion.
+ *
+ * \remark Implements DerivedCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL DerivedCRS : virtual public SingleCRS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DerivedCRS() override;
+ //! @endcond
+
+ PROJ_DLL const SingleCRSNNPtr &baseCRS() PROJ_CONST_DECL;
+ PROJ_DLL const operation::ConversionNNPtr derivingConversion() const;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ const operation::ConversionNNPtr &
+ derivingConversionRef() PROJ_CONST_DECL;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL
+ DerivedCRS(const SingleCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::CoordinateSystemNNPtr &cs);
+ PROJ_INTERNAL DerivedCRS(const DerivedCRS &other);
+
+ PROJ_INTERNAL void setDerivingConversionCRS();
+
+ PROJ_INTERNAL void baseExportToPROJString(
+ io::PROJStringFormatter *formatter) const; // throw(FormattingException)
+
+ PROJ_INTERNAL void baseExportToWKT(
+ io::WKTFormatter *&formatter, const std::string &keyword,
+ const std::string &baseKeyword) const; // throw(FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ DerivedCRS &operator=(const DerivedCRS &other) = delete;
+};
+
+/** Shared pointer of DerivedCRS */
+using DerivedCRSPtr = std::shared_ptr<DerivedCRS>;
+/** Non-null shared pointer of DerivedCRS */
+using DerivedCRSNNPtr = util::nn<DerivedCRSPtr>;
+
+// ---------------------------------------------------------------------------
+
+class ProjectedCRS;
+/** Shared pointer of ProjectedCRS */
+using ProjectedCRSPtr = std::shared_ptr<ProjectedCRS>;
+/** Non-null shared pointer of ProjectedCRS */
+using ProjectedCRSNNPtr = util::nn<ProjectedCRSPtr>;
+
+/** \brief A derived coordinate reference system which has a geodetic
+ * (usually geographic) coordinate reference system as its base CRS, thereby
+ * inheriting a geodetic reference frame, and is converted using a map
+ * projection.
+ *
+ * It has a Cartesian coordinate system, usually two-dimensional but may be
+ * three-dimensional; in the 3D case the base geographic CRSs ellipsoidal
+ * height is passed through unchanged and forms the vertical axis of the
+ * projected CRS's Cartesian coordinate system.
+ *
+ * \remark Implements ProjectedCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL ProjectedCRS final : public DerivedCRS,
+ public io::IPROJStringExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~ProjectedCRS() override;
+ //! @endcond
+
+ PROJ_DLL const GeodeticCRSNNPtr &baseCRS() PROJ_CONST_DECL;
+ PROJ_DLL const cs::CartesianCSNNPtr &coordinateSystem() PROJ_CONST_DECL;
+
+ PROJ_DLL static ProjectedCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const GeodeticCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::CartesianCSNNPtr &csIn);
+
+ PROJ_DLL std::list<std::pair<ProjectedCRSNNPtr, int>>
+ identify(const io::AuthorityFactoryPtr &authorityFactory) const;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void
+ addUnitConvertAndAxisSwap(io::PROJStringFormatter *formatter,
+ bool axisSpecFound) const;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL
+ ProjectedCRS(const GeodeticCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::CartesianCSNNPtr &csIn);
+ PROJ_INTERNAL ProjectedCRS(const ProjectedCRS &other);
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
+ _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
+
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ ProjectedCRS &operator=(const ProjectedCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class TemporalCRS;
+/** Shared pointer of TemporalCRS */
+using TemporalCRSPtr = std::shared_ptr<TemporalCRS>;
+/** Non-null shared pointer of TemporalCRS */
+using TemporalCRSNNPtr = util::nn<TemporalCRSPtr>;
+
+/** \brief A coordinate reference system associated with a temporal datum and a
+ * one-dimensional temporal coordinate system.
+ *
+ * \remark Implements TemporalCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL TemporalCRS : virtual public SingleCRS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~TemporalCRS() override;
+ //! @endcond
+
+ PROJ_DLL const datum::TemporalDatumNNPtr datum() const;
+
+ PROJ_DLL const cs::TemporalCSNNPtr coordinateSystem() const;
+
+ PROJ_DLL static TemporalCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::TemporalDatumNNPtr &datumIn,
+ const cs::TemporalCSNNPtr &csIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL TemporalCRS(const datum::TemporalDatumNNPtr &datumIn,
+ const cs::TemporalCSNNPtr &csIn);
+ PROJ_INTERNAL TemporalCRS(const TemporalCRS &other);
+
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ TemporalCRS &operator=(const TemporalCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class EngineeringCRS;
+/** Shared pointer of EngineeringCRS */
+using EngineeringCRSPtr = std::shared_ptr<EngineeringCRS>;
+/** Non-null shared pointer of EngineeringCRS */
+using EngineeringCRSNNPtr = util::nn<EngineeringCRSPtr>;
+
+/** \brief Contextually local coordinate reference system associated with an
+ * engineering datum.
+ *
+ * It is applied either to activities on or near the surface of the Earth
+ * without geodetic corrections, or on moving platforms such as road vehicles,
+ * vessels, aircraft or spacecraft, or as the internal CRS of an image.
+ *
+ * In \ref WKT2, it maps to a ENGINEERINGCRS / ENGCRS keyword. In \ref WKT1,
+ * it maps to a LOCAL_CS keyword.
+ *
+ * \remark Implements EngineeringCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL EngineeringCRS : virtual public SingleCRS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~EngineeringCRS() override;
+ //! @endcond
+
+ PROJ_DLL const datum::EngineeringDatumNNPtr datum() const;
+
+ PROJ_DLL static EngineeringCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::EngineeringDatumNNPtr &datumIn,
+ const cs::CoordinateSystemNNPtr &csIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL EngineeringCRS(const datum::EngineeringDatumNNPtr &datumIn,
+ const cs::CoordinateSystemNNPtr &csIn);
+ PROJ_INTERNAL EngineeringCRS(const EngineeringCRS &other);
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ EngineeringCRS &operator=(const EngineeringCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class ParametricCRS;
+/** Shared pointer of ParametricCRS */
+using ParametricCRSPtr = std::shared_ptr<ParametricCRS>;
+/** Non-null shared pointer of ParametricCRS */
+using ParametricCRSNNPtr = util::nn<ParametricCRSPtr>;
+
+/** \brief Contextually local coordinate reference system associated with an
+ * engineering datum.
+ *
+ * This is applied either to activities on or near the surface of the Earth
+ * without geodetic corrections, or on moving platforms such as road vehicles
+ * vessels, aircraft or spacecraft, or as the internal CRS of an image.
+ *
+ * \remark Implements ParametricCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL ParametricCRS : virtual public SingleCRS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~ParametricCRS() override;
+ //! @endcond
+
+ PROJ_DLL const datum::ParametricDatumNNPtr datum() const;
+
+ PROJ_DLL const cs::ParametricCSNNPtr coordinateSystem() const;
+
+ PROJ_DLL static ParametricCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const datum::ParametricDatumNNPtr &datumIn,
+ const cs::ParametricCSNNPtr &csIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL ParametricCRS(const datum::ParametricDatumNNPtr &datumIn,
+ const cs::ParametricCSNNPtr &csIn);
+ PROJ_INTERNAL ParametricCRS(const ParametricCRS &other);
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ ParametricCRS &operator=(const ParametricCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class CompoundCRS;
+/** Shared pointer of CompoundCRS */
+using CompoundCRSPtr = std::shared_ptr<CompoundCRS>;
+/** Non-null shared pointer of CompoundCRS */
+using CompoundCRSNNPtr = util::nn<CompoundCRSPtr>;
+
+/** \brief A coordinate reference system describing the position of points
+ * through two or more independent single coordinate reference systems.
+ *
+ * \note Two coordinate reference systems are independent of each other
+ * if coordinate values in one cannot be converted or transformed into
+ * coordinate values in the other.
+ *
+ * \note As a departure to \ref ISO_19111_2018, we allow to build a CompoundCRS
+ * from CRS objects, whereas ISO19111:2018 restricts the components to
+ * SingleCRS.
+ *
+ * \remark Implements CompoundCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL CompoundCRS final : public CRS,
+ public io::IPROJStringExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~CompoundCRS() override;
+ //! @endcond
+
+ PROJ_DLL const std::vector<CRSNNPtr> &
+ componentReferenceSystems() PROJ_CONST_DECL;
+
+ PROJ_DLL std::list<std::pair<CompoundCRSNNPtr, int>>
+ identify(const io::AuthorityFactoryPtr &authorityFactory) const;
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ PROJ_DLL static CompoundCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const std::vector<CRSNNPtr> &components);
+
+ protected:
+ // relaxed: standard say SingleCRSNNPtr
+ PROJ_INTERNAL explicit CompoundCRS(const std::vector<CRSNNPtr> &components);
+ PROJ_INTERNAL CompoundCRS(const CompoundCRS &other);
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
+ _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ CompoundCRS &operator=(const CompoundCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief A coordinate reference system with an associated transformation to
+ * a target/hub CRS.
+ *
+ * The definition of a CRS is not dependent upon any relationship to an
+ * independent CRS. However in an implementation that merges datasets
+ * referenced to differing CRSs, it is sometimes useful to associate the
+ * definition of the transformation that has been used with the CRS definition.
+ * This facilitates the interrelationship of CRS by concatenating
+ * transformations via a common or hub CRS. This is sometimes referred to as
+ * "early-binding". \ref WKT2 permits the association of an abridged coordinate
+ * transformation description with a coordinate reference system description in
+ * a single text string. In a BoundCRS, the abridged coordinate transformation
+ * is applied to the source CRS with the target CRS being the common or hub
+ * system.
+ *
+ * Coordinates referring to a BoundCRS are expressed into its source/base CRS.
+ *
+ * This abstraction can for example model the concept of TOWGS84 datum shift
+ * present in \ref WKT1.
+ *
+ * \note Contrary to other CRS classes of this package, there is no
+ * \ref ISO_19111_2018 modelling of a BoundCRS.
+ *
+ * \remark Implements BoundCRS from \ref WKT2
+ */
+class PROJ_GCC_DLL BoundCRS final : public CRS,
+ public io::IPROJStringExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~BoundCRS() override;
+ //! @endcond
+
+ PROJ_DLL const CRSNNPtr &baseCRS() PROJ_CONST_DECL;
+ PROJ_DLL CRSNNPtr baseCRSWithCanonicalBoundCRS() const;
+
+ PROJ_DLL const CRSNNPtr &hubCRS() PROJ_CONST_DECL;
+ PROJ_DLL const operation::TransformationNNPtr &
+ transformation() PROJ_CONST_DECL;
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ PROJ_DLL static BoundCRSNNPtr
+ create(const CRSNNPtr &baseCRSIn, const CRSNNPtr &hubCRSIn,
+ const operation::TransformationNNPtr &transformationIn);
+
+ PROJ_DLL static BoundCRSNNPtr
+ createFromTOWGS84(const CRSNNPtr &baseCRSIn,
+ const std::vector<double> &TOWGS84Parameters);
+
+ PROJ_DLL static BoundCRSNNPtr
+ createFromNadgrids(const CRSNNPtr &baseCRSIn, const std::string &filename);
+
+ protected:
+ PROJ_INTERNAL
+ BoundCRS(const CRSNNPtr &baseCRSIn, const CRSNNPtr &hubCRSIn,
+ const operation::TransformationNNPtr &transformationIn);
+ PROJ_INTERNAL BoundCRS(const BoundCRS &other);
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL BoundCRSNNPtr shallowCloneAsBoundCRS() const;
+ PROJ_INTERNAL bool isTOWGS84Compatible() const;
+ PROJ_INTERNAL std::string getHDatumPROJ4GRIDS() const;
+ PROJ_INTERNAL std::string getVDatumPROJ4GRIDS() const;
+
+ PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
+ _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ BoundCRS &operator=(const BoundCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class DerivedGeodeticCRS;
+/** Shared pointer of DerivedGeodeticCRS */
+using DerivedGeodeticCRSPtr = std::shared_ptr<DerivedGeodeticCRS>;
+/** Non-null shared pointer of DerivedGeodeticCRS */
+using DerivedGeodeticCRSNNPtr = util::nn<DerivedGeodeticCRSPtr>;
+
+/** \brief A derived coordinate reference system which has either a geodetic
+ * or a geographic coordinate reference system as its base CRS, thereby
+ * inheriting a geodetic reference frame, and associated with a 3D Cartesian
+ * or spherical coordinate system.
+ *
+ * \remark Implements DerivedGeodeticCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL DerivedGeodeticCRS final : public GeodeticCRS,
+ public DerivedCRS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DerivedGeodeticCRS() override;
+ //! @endcond
+
+ PROJ_DLL const GeodeticCRSNNPtr baseCRS() const;
+
+ PROJ_DLL static DerivedGeodeticCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const GeodeticCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::CartesianCSNNPtr &csIn);
+
+ PROJ_DLL static DerivedGeodeticCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const GeodeticCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::SphericalCSNNPtr &csIn);
+
+ //! @cond Doxygen_Suppress
+ void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL
+ DerivedGeodeticCRS(const GeodeticCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::CartesianCSNNPtr &csIn);
+ PROJ_INTERNAL
+ DerivedGeodeticCRS(const GeodeticCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::SphericalCSNNPtr &csIn);
+ PROJ_INTERNAL DerivedGeodeticCRS(const DerivedGeodeticCRS &other);
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
+ _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ DerivedGeodeticCRS &operator=(const DerivedGeodeticCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class DerivedGeographicCRS;
+/** Shared pointer of DerivedGeographicCRS */
+using DerivedGeographicCRSPtr = std::shared_ptr<DerivedGeographicCRS>;
+/** Non-null shared pointer of DerivedGeographicCRS */
+using DerivedGeographicCRSNNPtr = util::nn<DerivedGeographicCRSPtr>;
+
+/** \brief A derived coordinate reference system which has either a geodetic or
+ * a geographic coordinate reference system as its base CRS, thereby inheriting
+ * a geodetic reference frame, and an ellipsoidal coordinate system.
+ *
+ * A derived geographic CRS can be based on a geodetic CRS only if that
+ * geodetic CRS definition includes an ellipsoid.
+ *
+ * \remark Implements DerivedGeographicCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL DerivedGeographicCRS final : public GeographicCRS,
+ public DerivedCRS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DerivedGeographicCRS() override;
+ //! @endcond
+
+ PROJ_DLL const GeodeticCRSNNPtr baseCRS() const;
+
+ PROJ_DLL static DerivedGeographicCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const GeodeticCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::EllipsoidalCSNNPtr &csIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL
+ DerivedGeographicCRS(const GeodeticCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::EllipsoidalCSNNPtr &csIn);
+ PROJ_INTERNAL DerivedGeographicCRS(const DerivedGeographicCRS &other);
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
+ _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ DerivedGeographicCRS &operator=(const DerivedGeographicCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class DerivedProjectedCRS;
+/** Shared pointer of DerivedProjectedCRS */
+using DerivedProjectedCRSPtr = std::shared_ptr<DerivedProjectedCRS>;
+/** Non-null shared pointer of DerivedProjectedCRS */
+using DerivedProjectedCRSNNPtr = util::nn<DerivedProjectedCRSPtr>;
+
+/** \brief A derived coordinate reference system which has a projected
+ * coordinate reference system as its base CRS, thereby inheriting a geodetic
+ * reference frame, but also inheriting the distortion characteristics of the
+ * base projected CRS.
+ *
+ * A DerivedProjectedCRS is not a ProjectedCRS.
+ *
+ * \remark Implements DerivedProjectedCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL DerivedProjectedCRS final
+ : public DerivedCRS,
+ public io::IPROJStringExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DerivedProjectedCRS() override;
+ //! @endcond
+
+ PROJ_DLL const ProjectedCRSNNPtr baseCRS() const;
+
+ PROJ_DLL static DerivedProjectedCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const ProjectedCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::CoordinateSystemNNPtr &csIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL
+ DerivedProjectedCRS(const ProjectedCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::CoordinateSystemNNPtr &csIn);
+ PROJ_INTERNAL DerivedProjectedCRS(const DerivedProjectedCRS &other);
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ DerivedProjectedCRS &operator=(const DerivedProjectedCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class DerivedVerticalCRS;
+/** Shared pointer of DerivedVerticalCRS */
+using DerivedVerticalCRSPtr = std::shared_ptr<DerivedVerticalCRS>;
+/** Non-null shared pointer of DerivedVerticalCRS */
+using DerivedVerticalCRSNNPtr = util::nn<DerivedVerticalCRSPtr>;
+
+/** \brief A derived coordinate reference system which has a vertical
+ * coordinate reference system as its base CRS, thereby inheriting a vertical
+ * reference frame, and a vertical coordinate system.
+ *
+ * \remark Implements DerivedVerticalCRS from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL DerivedVerticalCRS final : public VerticalCRS,
+ public DerivedCRS {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DerivedVerticalCRS() override;
+ //! @endcond
+
+ PROJ_DLL const VerticalCRSNNPtr baseCRS() const;
+
+ PROJ_DLL static DerivedVerticalCRSNNPtr
+ create(const util::PropertyMap &properties,
+ const VerticalCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::VerticalCSNNPtr &csIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL
+ DerivedVerticalCRS(const VerticalCRSNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const cs::VerticalCSNNPtr &csIn);
+ PROJ_INTERNAL DerivedVerticalCRS(const DerivedVerticalCRS &other);
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>>
+ _identify(const io::AuthorityFactoryPtr &authorityFactory) const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ DerivedVerticalCRS &operator=(const DerivedVerticalCRS &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Template representing a derived coordinate reference system.
+ */
+template <class DerivedCRSTraits>
+class PROJ_GCC_DLL DerivedCRSTemplate final : public DerivedCRSTraits::BaseType,
+ public DerivedCRS {
+ protected:
+ /** Base type */
+ typedef typename DerivedCRSTraits::BaseType BaseType;
+ /** CSType */
+ typedef typename DerivedCRSTraits::CSType CSType;
+
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DerivedCRSTemplate() override;
+ //! @endcond
+
+ /** Non-null shared pointer of DerivedCRSTemplate */
+ typedef typename util::nn<std::shared_ptr<DerivedCRSTemplate>> NNPtr;
+ /** Non-null shared pointer of BaseType */
+ typedef util::nn<std::shared_ptr<BaseType>> BaseNNPtr;
+ /** Non-null shared pointer of CSType */
+ typedef util::nn<std::shared_ptr<CSType>> CSNNPtr;
+
+ /** \brief Return the base CRS of a DerivedCRSTemplate.
+ *
+ * @return the base CRS.
+ */
+ PROJ_DLL const BaseNNPtr baseCRS() const;
+
+ /** \brief Instanciate a DerivedCRSTemplate from a base CRS, a deriving
+ * conversion and a cs::CoordinateSystem.
+ *
+ * @param properties See \ref general_properties.
+ * At minimum the name should be defined.
+ * @param baseCRSIn base CRS.
+ * @param derivingConversionIn the deriving conversion from the base CRS to
+ * this
+ * CRS.
+ * @param csIn the coordinate system.
+ * @return new DerivedCRSTemplate.
+ */
+ PROJ_DLL static NNPtr
+ create(const util::PropertyMap &properties, const BaseNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const CSNNPtr &csIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL
+ DerivedCRSTemplate(const BaseNNPtr &baseCRSIn,
+ const operation::ConversionNNPtr &derivingConversionIn,
+ const CSNNPtr &csIn);
+ PROJ_INTERNAL DerivedCRSTemplate(const DerivedCRSTemplate &other);
+
+ PROJ_INTERNAL CRSNNPtr _shallowClone() const override;
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ struct PROJ_INTERNAL Private;
+ std::unique_ptr<Private> d;
+
+ DerivedCRSTemplate &operator=(const DerivedCRSTemplate &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+struct PROJ_GCC_DLL DerivedEngineeringCRSTraits {
+ typedef EngineeringCRS BaseType;
+ typedef cs::CoordinateSystem CSType;
+ // old x86_64-w64-mingw32-g++ has issues with static variables. use method
+ // instead
+ inline static const std::string &CRSName();
+ inline static const std::string &WKTKeyword();
+ inline static const std::string &WKTBaseKeyword();
+ static const bool wkt2_2018_only = true;
+};
+//! @endcond
+
+/** \brief A derived coordinate reference system which has an engineering
+ * coordinate reference system as its base CRS, thereby inheriting an
+ * engineering datum, and is associated with one of the coordinate system
+ * types for an EngineeringCRS
+ *
+ * \remark Implements DerivedEngineeringCRS from \ref ISO_19111_2018
+ */
+#ifdef DOXYGEN_ENABLED
+class DerivedEngineeringCRS
+ : public DerivedCRSTemplate<DerivedEngineeringCRSTraits> {};
+#else
+using DerivedEngineeringCRS = DerivedCRSTemplate<DerivedEngineeringCRSTraits>;
+#endif
+
+#ifndef DO_NOT_DEFINE_EXTERN_DERIVED_CRS_TEMPLATE
+extern template class DerivedCRSTemplate<DerivedEngineeringCRSTraits>;
+#endif
+
+/** Shared pointer of DerivedEngineeringCRS */
+using DerivedEngineeringCRSPtr = std::shared_ptr<DerivedEngineeringCRS>;
+/** Non-null shared pointer of DerivedEngineeringCRS */
+using DerivedEngineeringCRSNNPtr = util::nn<DerivedEngineeringCRSPtr>;
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+struct PROJ_GCC_DLL DerivedParametricCRSTraits {
+ typedef ParametricCRS BaseType;
+ typedef cs::ParametricCS CSType;
+ // old x86_64-w64-mingw32-g++ has issues with static variables. use method
+ // instead
+ inline static const std::string &CRSName();
+ inline static const std::string &WKTKeyword();
+ inline static const std::string &WKTBaseKeyword();
+ static const bool wkt2_2018_only = false;
+};
+//! @endcond
+
+/** \brief A derived coordinate reference system which has a parametric
+ * coordinate reference system as its base CRS, thereby inheriting a parametric
+ * datum, and a parametric coordinate system.
+ *
+ * \remark Implements DerivedParametricCRS from \ref ISO_19111_2018
+ */
+#ifdef DOXYGEN_ENABLED
+class DerivedParametricCRS
+ : public DerivedCRSTemplate<DerivedParametricCRSTraits> {};
+#else
+using DerivedParametricCRS = DerivedCRSTemplate<DerivedParametricCRSTraits>;
+#endif
+
+#ifndef DO_NOT_DEFINE_EXTERN_DERIVED_CRS_TEMPLATE
+extern template class DerivedCRSTemplate<DerivedParametricCRSTraits>;
+#endif
+
+/** Shared pointer of DerivedParametricCRS */
+using DerivedParametricCRSPtr = std::shared_ptr<DerivedParametricCRS>;
+/** Non-null shared pointer of DerivedParametricCRS */
+using DerivedParametricCRSNNPtr = util::nn<DerivedParametricCRSPtr>;
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+struct PROJ_GCC_DLL DerivedTemporalCRSTraits {
+ typedef TemporalCRS BaseType;
+ typedef cs::TemporalCS CSType;
+ // old x86_64-w64-mingw32-g++ has issues with static variables. use method
+ // instead
+ inline static const std::string &CRSName();
+ inline static const std::string &WKTKeyword();
+ inline static const std::string &WKTBaseKeyword();
+ static const bool wkt2_2018_only = false;
+};
+//! @endcond
+
+/** \brief A derived coordinate reference system which has a temporal
+ * coordinate reference system as its base CRS, thereby inheriting a temporal
+ * datum, and a temporal coordinate system.
+ *
+ * \remark Implements DerivedTemporalCRS from \ref ISO_19111_2018
+ */
+#ifdef DOXYGEN_ENABLED
+class DerivedTemporalCRS : public DerivedCRSTemplate<DerivedTemporalCRSTraits> {
+};
+#else
+using DerivedTemporalCRS = DerivedCRSTemplate<DerivedTemporalCRSTraits>;
+#endif
+
+#ifndef DO_NOT_DEFINE_EXTERN_DERIVED_CRS_TEMPLATE
+extern template class DerivedCRSTemplate<DerivedTemporalCRSTraits>;
+#endif
+
+/** Shared pointer of DerivedTemporalCRS */
+using DerivedTemporalCRSPtr = std::shared_ptr<DerivedTemporalCRS>;
+/** Non-null shared pointer of DerivedTemporalCRS */
+using DerivedTemporalCRSNNPtr = util::nn<DerivedTemporalCRSPtr>;
+
+// ---------------------------------------------------------------------------
+
+} // namespace crs
+
+NS_PROJ_END
+
+#endif // CRS_HH_INCLUDED
diff --git a/include/proj/datum.hpp b/include/proj/datum.hpp
new file mode 100644
index 00000000..12b93a04
--- /dev/null
+++ b/include/proj/datum.hpp
@@ -0,0 +1,779 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef DATUM_HH_INCLUDED
+#define DATUM_HH_INCLUDED
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "common.hpp"
+#include "io.hpp"
+#include "util.hpp"
+
+NS_PROJ_START
+
+/** osgeo.proj.datum namespace
+
+ \brief Datum (the relationship of a coordinate system to the body).
+ */
+namespace datum {
+
+// ---------------------------------------------------------------------------
+
+/** \brief Abstract class of the relationship of a coordinate system to an
+ * object, thus creating a coordinate reference system.
+ *
+ * For geodetic and vertical coordinate reference systems, it relates a
+ * coordinate system to the Earth (or the celestial body considered). With
+ * other types of coordinate reference systems, the datum may relate the
+ * coordinate system to another physical or
+ * virtual object. A datum uses a parameter or set of parameters that determine
+ * the location of the origin of the coordinate reference system. Each datum
+ * subtype can be associated with only specific types of coordinate reference
+ * systems.
+ *
+ * \remark Implements Datum from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL Datum : public common::ObjectUsage {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~Datum() override;
+ //! @endcond
+
+ PROJ_DLL const util::optional<std::string> &anchorDefinition() const;
+ PROJ_DLL const util::optional<common::DateTime> &publicationDate() const;
+ PROJ_DLL const common::IdentifiedObjectPtr &conventionalRS() const;
+
+ protected:
+ PROJ_INTERNAL Datum();
+
+ PROJ_INTERNAL bool
+ __isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const;
+
+#ifdef DOXYGEN_ENABLED
+ std::string *anchorDefinition_;
+ Date *publicationDate_;
+ common::IdentifiedObject *conventionalRS_;
+#endif
+
+ protected:
+ PROJ_INTERNAL void setAnchor(const util::optional<std::string> &anchor);
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ Datum &operator=(const Datum &other) = delete;
+ Datum(const Datum &other) = delete;
+};
+
+/** Shared pointer of Datum */
+using DatumPtr = std::shared_ptr<Datum>;
+/** Non-null shared pointer of Datum */
+using DatumNNPtr = util::nn<DatumPtr>;
+
+// ---------------------------------------------------------------------------
+
+class DatumEnsemble;
+/** Shared pointer of DatumEnsemble */
+using DatumEnsemblePtr = std::shared_ptr<DatumEnsemble>;
+/** Non-null shared pointer of DatumEnsemble */
+using DatumEnsembleNNPtr = util::nn<DatumEnsemblePtr>;
+
+/** \brief A collection of two or more geodetic or vertical reference frames
+ * (or if not geodetic or vertical reference frame, a collection of two or more
+ * datums) which for all but the highest accuracy requirements may be
+ * considered to be insignificantly different from each other.
+ *
+ * Every frame within the datum ensemble must be a realizations of the same
+ * Terrestrial Reference System or Vertical Reference System.
+ *
+ * \remark Implements DatumEnsemble from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL DatumEnsemble final : public common::IdentifiedObject {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DatumEnsemble() override;
+ //! @endcond
+
+ PROJ_DLL const std::vector<DatumNNPtr> &datums() const;
+ PROJ_DLL const metadata::PositionalAccuracyNNPtr &
+ positionalAccuracy() const;
+
+ PROJ_DLL static DatumEnsembleNNPtr create(
+ const util::PropertyMap &properties,
+ const std::vector<DatumNNPtr> &datumsIn,
+ const metadata::PositionalAccuracyNNPtr &accuracy); // throw(Exception)
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+#ifdef DOXYGEN_ENABLED
+ Datum datums_[];
+ PositionalAccuracy positionalAccuracy_;
+#endif
+
+ PROJ_INTERNAL
+ DatumEnsemble(const std::vector<DatumNNPtr> &datumsIn,
+ const metadata::PositionalAccuracyNNPtr &accuracy);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+
+ DatumEnsemble(const DatumEnsemble &other) = delete;
+ DatumEnsemble &operator=(const DatumEnsemble &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class PrimeMeridian;
+/** Shared pointer of PrimeMeridian */
+using PrimeMeridianPtr = std::shared_ptr<PrimeMeridian>;
+/** Non-null shared pointer of PrimeMeridian */
+using PrimeMeridianNNPtr = util::nn<PrimeMeridianPtr>;
+
+/** \brief The origin meridian from which longitude values are determined.
+ *
+ * \note The default value for prime meridian name is "Greenwich". When the
+ * default applies, the value for the longitude shall be 0 (degrees).
+ *
+ * \remark Implements PrimeMeridian from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL PrimeMeridian final : public common::IdentifiedObject,
+ public io::IPROJStringExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~PrimeMeridian() override;
+ //! @endcond
+
+ PROJ_DLL const common::Angle &longitude() PROJ_CONST_DECL;
+
+ // non-standard
+ PROJ_DLL static PrimeMeridianNNPtr
+ create(const util::PropertyMap &properties,
+ const common::Angle &longitudeIn);
+
+ PROJ_DLL static const PrimeMeridianNNPtr GREENWICH;
+ PROJ_DLL static const PrimeMeridianNNPtr PARIS;
+
+ PROJ_PRIVATE :
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void
+ _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL static std::string
+ getPROJStringWellKnownName(const common::Angle &angle);
+ //! @endcond
+
+ protected:
+#ifdef DOXYGEN_ENABLED
+ Angle greenwichLongitude_;
+#endif
+
+ PROJ_INTERNAL explicit PrimeMeridian(
+ const common::Angle &angle = common::Angle());
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ PrimeMeridian(const PrimeMeridian &other) = delete;
+ PrimeMeridian &operator=(const PrimeMeridian &other) = delete;
+
+ PROJ_INTERNAL static const PrimeMeridianNNPtr createGREENWICH();
+ PROJ_INTERNAL static const PrimeMeridianNNPtr createPARIS();
+};
+
+// ---------------------------------------------------------------------------
+
+class Ellipsoid;
+/** Shared pointer of Ellipsoid */
+using EllipsoidPtr = std::shared_ptr<Ellipsoid>;
+/** Non-null shared pointer of Ellipsoid */
+using EllipsoidNNPtr = util::nn<EllipsoidPtr>;
+
+/** \brief A geometric figure that can be used to describe the approximate
+ * shape of an object.
+ *
+ * For the Earth an oblate biaxial ellipsoid is used: in mathematical terms,
+ * it is a surface formed by the rotation of an ellipse about its minor axis.
+ *
+ * \remark Implements Ellipsoid from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL Ellipsoid final : public common::IdentifiedObject,
+ public io::IPROJStringExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~Ellipsoid() override;
+ //! @endcond
+
+ PROJ_DLL const common::Length &semiMajorAxis() PROJ_CONST_DECL;
+
+ // Inlined from SecondDefiningParameter union
+ PROJ_DLL const util::optional<common::Scale> &
+ inverseFlattening() PROJ_CONST_DECL;
+ PROJ_DLL const util::optional<common::Length> &
+ semiMinorAxis() PROJ_CONST_DECL;
+ PROJ_DLL bool isSphere() PROJ_CONST_DECL;
+
+ PROJ_DLL const util::optional<common::Length> &
+ semiMedianAxis() PROJ_CONST_DECL;
+
+ // non-standard
+
+ PROJ_DLL double computedInverseFlattening() PROJ_CONST_DECL;
+ PROJ_DLL double squaredEccentricity() PROJ_CONST_DECL;
+ PROJ_DLL common::Length computeSemiMinorAxis() const;
+
+ PROJ_DLL const std::string &celestialBody() PROJ_CONST_DECL;
+
+ PROJ_DLL static const std::string EARTH;
+
+ PROJ_DLL static EllipsoidNNPtr
+ createSphere(const util::PropertyMap &properties,
+ const common::Length &radius,
+ const std::string &celestialBody = EARTH);
+
+ PROJ_DLL static EllipsoidNNPtr
+ createFlattenedSphere(const util::PropertyMap &properties,
+ const common::Length &semiMajorAxisIn,
+ const common::Scale &invFlattening,
+ const std::string &celestialBody = EARTH);
+
+ PROJ_DLL static EllipsoidNNPtr
+ createTwoAxis(const util::PropertyMap &properties,
+ const common::Length &semiMajorAxisIn,
+ const common::Length &semiMinorAxisIn,
+ const std::string &celestialBody = EARTH);
+
+ PROJ_DLL EllipsoidNNPtr identify() const;
+
+ PROJ_DLL static const EllipsoidNNPtr CLARKE_1866;
+ PROJ_DLL static const EllipsoidNNPtr WGS84;
+ PROJ_DLL static const EllipsoidNNPtr GRS1980;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void
+ _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+ //! @endcond
+
+ PROJ_INTERNAL static std::string
+ guessBodyName(const io::DatabaseContextPtr &dbContext, double a);
+
+ PROJ_INTERNAL bool lookForProjWellKnownEllps(std::string &projEllpsName,
+ std::string &ellpsName) const;
+
+ protected:
+#ifdef DOXYGEN_ENABLED
+ common::Length semiMajorAxis_;
+ common::Scale *inverseFlattening_;
+ common::Length *semiMinorAxis_;
+ bool isSphere_;
+ common::Length *semiMedianAxis_;
+#endif
+
+ PROJ_INTERNAL explicit Ellipsoid(const common::Length &radius,
+ const std::string &celestialBody);
+
+ PROJ_INTERNAL Ellipsoid(const common::Length &semiMajorAxisIn,
+ const common::Scale &invFlattening,
+ const std::string &celestialBody);
+
+ PROJ_INTERNAL Ellipsoid(const common::Length &semiMajorAxisIn,
+ const common::Length &semiMinorAxisIn,
+ const std::string &celestialBody);
+
+ PROJ_INTERNAL Ellipsoid(const Ellipsoid &other);
+
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL static const EllipsoidNNPtr createCLARKE_1866();
+ PROJ_INTERNAL static const EllipsoidNNPtr createWGS84();
+ PROJ_INTERNAL static const EllipsoidNNPtr createGRS1980();
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ Ellipsoid &operator=(const Ellipsoid &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class GeodeticReferenceFrame;
+/** Shared pointer of GeodeticReferenceFrame */
+using GeodeticReferenceFramePtr = std::shared_ptr<GeodeticReferenceFrame>;
+/** Non-null shared pointer of GeodeticReferenceFrame */
+using GeodeticReferenceFrameNNPtr = util::nn<GeodeticReferenceFramePtr>;
+
+/** \brief The definition of the position, scale and orientation of a geocentric
+ * Cartesian 3D coordinate system relative to the Earth.
+ *
+ * It may also identify a defined ellipsoid (or sphere) that approximates
+ * the shape of the Earth and which is centred on and aligned to this
+ * geocentric coordinate system. Older geodetic datums define the location and
+ * orientation of a defined ellipsoid (or sphere) that approximates the shape
+ * of the earth.
+ *
+ * \note The terminology "Datum" is often used to mean a GeodeticReferenceFrame.
+ *
+ * \note In \ref ISO_19111_2007, this class was called GeodeticDatum.
+ *
+ * \remark Implements GeodeticReferenceFrame from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL GeodeticReferenceFrame : public Datum {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~GeodeticReferenceFrame() override;
+ //! @endcond
+
+ PROJ_DLL const PrimeMeridianNNPtr &primeMeridian() PROJ_CONST_DECL;
+
+ // We constraint more than the standard into which the ellipsoid might
+ // be omitted for a CRS with a non-ellipsoidal CS
+ PROJ_DLL const EllipsoidNNPtr &ellipsoid() PROJ_CONST_DECL;
+
+ // non-standard
+ PROJ_DLL static GeodeticReferenceFrameNNPtr
+ create(const util::PropertyMap &properties, const EllipsoidNNPtr &ellipsoid,
+ const util::optional<std::string> &anchor,
+ const PrimeMeridianNNPtr &primeMeridian);
+
+ PROJ_DLL static const GeodeticReferenceFrameNNPtr
+ EPSG_6267; // North American Datum 1927
+ PROJ_DLL static const GeodeticReferenceFrameNNPtr
+ EPSG_6269; // North American Datum 1983
+ PROJ_DLL static const GeodeticReferenceFrameNNPtr EPSG_6326; // WGS 84
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+#ifdef DOXYGEN_ENABLED
+ PrimeMeridian primeMeridian_;
+ Ellipsoid *ellipsoid_;
+#endif
+
+ PROJ_INTERNAL
+ GeodeticReferenceFrame(const EllipsoidNNPtr &ellipsoidIn,
+ const PrimeMeridianNNPtr &primeMeridianIn);
+ INLINED_MAKE_SHARED
+
+ PROJ_INTERNAL static const GeodeticReferenceFrameNNPtr createEPSG_6267();
+ PROJ_INTERNAL static const GeodeticReferenceFrameNNPtr createEPSG_6269();
+ PROJ_INTERNAL static const GeodeticReferenceFrameNNPtr createEPSG_6326();
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ GeodeticReferenceFrame(const GeodeticReferenceFrame &other) = delete;
+ GeodeticReferenceFrame &
+ operator=(const GeodeticReferenceFrame &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class DynamicGeodeticReferenceFrame;
+/** Shared pointer of DynamicGeodeticReferenceFrame */
+using DynamicGeodeticReferenceFramePtr =
+ std::shared_ptr<DynamicGeodeticReferenceFrame>;
+/** Non-null shared pointer of DynamicGeodeticReferenceFrame */
+using DynamicGeodeticReferenceFrameNNPtr =
+ util::nn<DynamicGeodeticReferenceFramePtr>;
+
+/** \brief A geodetic reference frame in which some of the parameters describe
+ * time evolution of defining station coordinates.
+ *
+ * For example defining station coordinates having linear velocities to account
+ * for crustal motion.
+ *
+ * \remark Implements DynamicGeodeticReferenceFrame from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL DynamicGeodeticReferenceFrame final
+ : public GeodeticReferenceFrame {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DynamicGeodeticReferenceFrame() override;
+ //! @endcond
+
+ PROJ_DLL const common::Measure &frameReferenceEpoch() const;
+ PROJ_DLL const util::optional<std::string> &deformationModelName() const;
+
+ // non-standard
+ PROJ_DLL static DynamicGeodeticReferenceFrameNNPtr
+ create(const util::PropertyMap &properties, const EllipsoidNNPtr &ellipsoid,
+ const util::optional<std::string> &anchor,
+ const PrimeMeridianNNPtr &primeMeridian,
+ const common::Measure &frameReferenceEpochIn,
+ const util::optional<std::string> &deformationModelNameIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+#ifdef DOXYGEN_ENABLED
+ Measure frameReferenceEpoch_;
+#endif
+
+ PROJ_INTERNAL DynamicGeodeticReferenceFrame(
+ const EllipsoidNNPtr &ellipsoidIn,
+ const PrimeMeridianNNPtr &primeMeridianIn,
+ const common::Measure &frameReferenceEpochIn,
+ const util::optional<std::string> &deformationModelNameIn);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ DynamicGeodeticReferenceFrame(const DynamicGeodeticReferenceFrame &other) =
+ delete;
+ DynamicGeodeticReferenceFrame &
+ operator=(const DynamicGeodeticReferenceFrame &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief The specification of the method by which the vertical reference frame
+ * is realized.
+ *
+ * \remark Implements RealizationMethod from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL RealizationMethod : public util::CodeList {
+ public:
+ PROJ_DLL static const RealizationMethod LEVELLING;
+ PROJ_DLL static const RealizationMethod GEOID;
+ PROJ_DLL static const RealizationMethod TIDAL;
+
+ private:
+ PROJ_FRIEND_OPTIONAL(RealizationMethod);
+ PROJ_DLL explicit RealizationMethod(
+ const std::string &nameIn = std::string());
+ PROJ_DLL RealizationMethod(const RealizationMethod &other);
+ PROJ_DLL RealizationMethod &operator=(const RealizationMethod &other);
+};
+
+// ---------------------------------------------------------------------------
+
+class VerticalReferenceFrame;
+/** Shared pointer of VerticalReferenceFrame */
+using VerticalReferenceFramePtr = std::shared_ptr<VerticalReferenceFrame>;
+/** Non-null shared pointer of VerticalReferenceFrame */
+using VerticalReferenceFrameNNPtr = util::nn<VerticalReferenceFramePtr>;
+
+/** \brief A textual description and/or a set of parameters identifying a
+ * particular reference level surface used as a zero-height or zero-depth
+ * surface, including its position with respect to the Earth.
+ *
+ * \note In \ref ISO_19111_2007, this class was called VerticalDatum.
+
+ * \remark Implements VerticalReferenceFrame from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL VerticalReferenceFrame : public Datum {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~VerticalReferenceFrame() override;
+ //! @endcond
+
+ PROJ_DLL const util::optional<RealizationMethod> &realizationMethod() const;
+
+ // non-standard
+ PROJ_DLL static VerticalReferenceFrameNNPtr
+ create(const util::PropertyMap &properties,
+ const util::optional<std::string> &anchor =
+ util::optional<std::string>(),
+ const util::optional<RealizationMethod> &realizationMethodIn =
+ util::optional<RealizationMethod>());
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+#ifdef DOXYGEN_ENABLED
+ RealizationMethod realizationMethod_;
+#endif
+
+ PROJ_INTERNAL explicit VerticalReferenceFrame(
+ const util::optional<RealizationMethod> &realizationMethodIn);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class DynamicVerticalReferenceFrame;
+/** Shared pointer of DynamicVerticalReferenceFrame */
+using DynamicVerticalReferenceFramePtr =
+ std::shared_ptr<DynamicVerticalReferenceFrame>;
+/** Non-null shared pointer of DynamicVerticalReferenceFrame */
+using DynamicVerticalReferenceFrameNNPtr =
+ util::nn<DynamicVerticalReferenceFramePtr>;
+
+/** \brief A vertical reference frame in which some of the defining parameters
+ * have time dependency.
+ *
+ * For example defining station heights have velocity to account for
+ * post-glacial isostatic rebound motion.
+ *
+ * \remark Implements DynamicVerticalReferenceFrame from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL DynamicVerticalReferenceFrame final
+ : public VerticalReferenceFrame {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DynamicVerticalReferenceFrame() override;
+ //! @endcond
+
+ PROJ_DLL const common::Measure &frameReferenceEpoch() const;
+ PROJ_DLL const util::optional<std::string> &deformationModelName() const;
+
+ // non-standard
+ PROJ_DLL static DynamicVerticalReferenceFrameNNPtr
+ create(const util::PropertyMap &properties,
+ const util::optional<std::string> &anchor,
+ const util::optional<RealizationMethod> &realizationMethodIn,
+ const common::Measure &frameReferenceEpochIn,
+ const util::optional<std::string> &deformationModelNameIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+ //! @endcond
+
+ protected:
+#ifdef DOXYGEN_ENABLED
+ Measure frameReferenceEpoch_;
+#endif
+
+ PROJ_INTERNAL DynamicVerticalReferenceFrame(
+ const util::optional<RealizationMethod> &realizationMethodIn,
+ const common::Measure &frameReferenceEpochIn,
+ const util::optional<std::string> &deformationModelNameIn);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ DynamicVerticalReferenceFrame(const DynamicVerticalReferenceFrame &other) =
+ delete;
+ DynamicVerticalReferenceFrame &
+ operator=(const DynamicVerticalReferenceFrame &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class TemporalDatum;
+/** Shared pointer of TemporalDatum */
+using TemporalDatumPtr = std::shared_ptr<TemporalDatum>;
+/** Non-null shared pointer of TemporalDatum */
+using TemporalDatumNNPtr = util::nn<TemporalDatumPtr>;
+
+/** \brief The definition of the relationship of a temporal coordinate system
+ * to an object. The object is normally time on the Earth.
+ *
+ * \remark Implements TemporalDatum from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL TemporalDatum final : public Datum {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~TemporalDatum() override;
+ //! @endcond
+
+ PROJ_DLL const common::DateTime &temporalOrigin() const;
+ PROJ_DLL const std::string &calendar() const;
+
+ PROJ_DLL static const std::string CALENDAR_PROLEPTIC_GREGORIAN;
+
+ // non-standard
+ PROJ_DLL static TemporalDatumNNPtr
+ create(const util::PropertyMap &properties,
+ const common::DateTime &temporalOriginIn,
+ const std::string &calendarIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL TemporalDatum(const common::DateTime &temporalOriginIn,
+ const std::string &calendarIn);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class EngineeringDatum;
+/** Shared pointer of EngineeringDatum */
+using EngineeringDatumPtr = std::shared_ptr<EngineeringDatum>;
+/** Non-null shared pointer of EngineeringDatum */
+using EngineeringDatumNNPtr = util::nn<EngineeringDatumPtr>;
+
+/** \brief The definition of the origin and orientation of an engineering
+ * coordinate reference system.
+ *
+ * \note The origin can be fixed with respect to the Earth (such as a defined
+ * point at a construction site), or be a defined point on a moving vehicle
+ * (such as on a ship or satellite), or a defined point of an image.
+ *
+ * \remark Implements EngineeringDatum from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL EngineeringDatum final : public Datum {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~EngineeringDatum() override;
+ //! @endcond
+
+ // non-standard
+ PROJ_DLL static EngineeringDatumNNPtr
+ create(const util::PropertyMap &properties,
+ const util::optional<std::string> &anchor =
+ util::optional<std::string>());
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL EngineeringDatum();
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class ParametricDatum;
+/** Shared pointer of ParametricDatum */
+using ParametricDatumPtr = std::shared_ptr<ParametricDatum>;
+/** Non-null shared pointer of ParametricDatum */
+using ParametricDatumNNPtr = util::nn<ParametricDatumPtr>;
+
+/** \brief Textual description and/or a set of parameters identifying a
+ * particular reference surface used as the origin of a parametric coordinate
+ * system, including its position with respect to the Earth.
+ *
+ * \remark Implements ParametricDatum from \ref ISO_19111_2018
+ */
+class PROJ_GCC_DLL ParametricDatum final : public Datum {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~ParametricDatum() override;
+ //! @endcond
+
+ // non-standard
+ PROJ_DLL static ParametricDatumNNPtr
+ create(const util::PropertyMap &properties,
+ const util::optional<std::string> &anchor =
+ util::optional<std::string>());
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL ParametricDatum();
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+} // namespace datum
+
+NS_PROJ_END
+
+#endif // DATUM_HH_INCLUDED
diff --git a/include/proj/internal/Makefile.am b/include/proj/internal/Makefile.am
new file mode 100644
index 00000000..ddd2686c
--- /dev/null
+++ b/include/proj/internal/Makefile.am
@@ -0,0 +1,8 @@
+noinst_HEADERS = \
+ coordinateoperation_constants.hpp \
+ coordinateoperation_internal.hpp \
+ esri_projection_mappings.hpp \
+ coordinatesystem_internal.hpp \
+ internal.hpp \
+ io_internal.hpp \
+ lru_cache.hpp
diff --git a/include/proj/internal/coordinateoperation_constants.hpp b/include/proj/internal/coordinateoperation_constants.hpp
new file mode 100644
index 00000000..e999b3a6
--- /dev/null
+++ b/include/proj/internal/coordinateoperation_constants.hpp
@@ -0,0 +1,898 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef FROM_COORDINATE_OPERATION_CPP
+#error This file should only be included from coordinateoperation.cpp
+#endif
+
+#ifndef COORDINATEOPERATION_CONSTANTS_HH_INCLUDED
+#define COORDINATEOPERATION_CONSTANTS_HH_INCLUDED
+
+#include "coordinateoperation_internal.hpp"
+#include "proj_constants.h"
+
+//! @cond Doxygen_Suppress
+// ---------------------------------------------------------------------------
+
+// anonymous namespace
+namespace {
+
+using namespace ::NS_PROJ;
+using namespace ::NS_PROJ::operation;
+
+static const char *WKT1_LATITUDE_OF_ORIGIN = "latitude_of_origin";
+static const char *WKT1_CENTRAL_MERIDIAN = "central_meridian";
+static const char *WKT1_SCALE_FACTOR = "scale_factor";
+static const char *WKT1_FALSE_EASTING = "false_easting";
+static const char *WKT1_FALSE_NORTHING = "false_northing";
+static const char *WKT1_STANDARD_PARALLEL_1 = "standard_parallel_1";
+static const char *WKT1_STANDARD_PARALLEL_2 = "standard_parallel_2";
+static const char *WKT1_LATITUDE_OF_CENTER = "latitude_of_center";
+static const char *WKT1_LONGITUDE_OF_CENTER = "longitude_of_center";
+static const char *WKT1_AZIMUTH = "azimuth";
+static const char *WKT1_RECTIFIED_GRID_ANGLE = "rectified_grid_angle";
+
+static const char *lat_0 = "lat_0";
+static const char *lat_1 = "lat_1";
+static const char *lat_2 = "lat_2";
+static const char *lat_ts = "lat_ts";
+static const char *lon_0 = "lon_0";
+static const char *lon_1 = "lon_1";
+static const char *lon_2 = "lon_2";
+static const char *lonc = "lonc";
+static const char *alpha = "alpha";
+static const char *gamma = "gamma";
+static const char *k_0 = "k_0";
+static const char *k = "k";
+static const char *x_0 = "x_0";
+static const char *y_0 = "y_0";
+static const char *h = "h";
+
+static const ParamMapping paramLatitudeNatOrigin = {
+ EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_LATITUDE_OF_ORIGIN,
+ common::UnitOfMeasure::Type::ANGULAR, lat_0};
+
+static const ParamMapping paramLongitudeNatOrigin = {
+ EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, WKT1_CENTRAL_MERIDIAN,
+ common::UnitOfMeasure::Type::ANGULAR, lon_0};
+
+static const ParamMapping paramScaleFactor = {
+ EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, WKT1_SCALE_FACTOR,
+ common::UnitOfMeasure::Type::SCALE, k_0};
+
+static const ParamMapping paramFalseEasting = {
+ EPSG_NAME_PARAMETER_FALSE_EASTING, EPSG_CODE_PARAMETER_FALSE_EASTING,
+ WKT1_FALSE_EASTING, common::UnitOfMeasure::Type::LINEAR, x_0};
+
+static const ParamMapping paramFalseNorthing = {
+ EPSG_NAME_PARAMETER_FALSE_NORTHING, EPSG_CODE_PARAMETER_FALSE_NORTHING,
+ WKT1_FALSE_NORTHING, common::UnitOfMeasure::Type::LINEAR, y_0};
+
+static const ParamMapping paramLatitudeFalseOrigin = {
+ EPSG_NAME_PARAMETER_LATITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_FALSE_ORIGIN, WKT1_LATITUDE_OF_ORIGIN,
+ common::UnitOfMeasure::Type::ANGULAR, lat_0};
+
+static const ParamMapping paramLongitudeFalseOrigin = {
+ EPSG_NAME_PARAMETER_LONGITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_FALSE_ORIGIN, WKT1_CENTRAL_MERIDIAN,
+ common::UnitOfMeasure::Type::ANGULAR, lon_0};
+
+static const ParamMapping paramFalseEastingOrigin = {
+ EPSG_NAME_PARAMETER_EASTING_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_EASTING_FALSE_ORIGIN, WKT1_FALSE_EASTING,
+ common::UnitOfMeasure::Type::LINEAR, x_0};
+
+static const ParamMapping paramFalseNorthingOrigin = {
+ EPSG_NAME_PARAMETER_NORTHING_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_NORTHING_FALSE_ORIGIN, WKT1_FALSE_NORTHING,
+ common::UnitOfMeasure::Type::LINEAR, y_0};
+
+static const ParamMapping paramLatitude1stStdParallel = {
+ EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, WKT1_STANDARD_PARALLEL_1,
+ common::UnitOfMeasure::Type::ANGULAR, lat_1};
+
+static const ParamMapping paramLatitude2ndStdParallel = {
+ EPSG_NAME_PARAMETER_LATITUDE_2ND_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_2ND_STD_PARALLEL, WKT1_STANDARD_PARALLEL_2,
+ common::UnitOfMeasure::Type::ANGULAR, lat_2};
+
+static const ParamMapping *const paramsNatOriginScale[] = {
+ &paramLatitudeNatOrigin, &paramLongitudeNatOrigin, &paramScaleFactor,
+ &paramFalseEasting, &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramLatFirstPoint = {
+ "Latitude of 1st point", 0, "Latitude_Of_1st_Point",
+ common::UnitOfMeasure::Type::ANGULAR, lat_1};
+static const ParamMapping paramLongFirstPoint = {
+ "Longitude of 1st point", 0, "Longitude_Of_1st_Point",
+ common::UnitOfMeasure::Type::ANGULAR, lon_1};
+static const ParamMapping paramLatSecondPoint = {
+ "Latitude of 2nd point", 0, "Latitude_Of_2nd_Point",
+ common::UnitOfMeasure::Type::ANGULAR, lat_2};
+static const ParamMapping paramLongSecondPoint = {
+ "Longitude of 2nd point", 0, "Longitude_Of_2nd_Point",
+ common::UnitOfMeasure::Type::ANGULAR, lon_2};
+
+static const ParamMapping *const paramsTPEQD[] = {&paramLatFirstPoint,
+ &paramLongFirstPoint,
+ &paramLatSecondPoint,
+ &paramLongSecondPoint,
+ &paramFalseEasting,
+ &paramFalseNorthing,
+ nullptr};
+
+static const ParamMapping *const paramsTMG[] = {
+ &paramLatitudeFalseOrigin, &paramLongitudeFalseOrigin,
+ &paramFalseEastingOrigin, &paramFalseNorthingOrigin, nullptr};
+
+static const ParamMapping paramLatFalseOriginLatOfCenter = {
+ EPSG_NAME_PARAMETER_LATITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_FALSE_ORIGIN, WKT1_LATITUDE_OF_CENTER,
+ common::UnitOfMeasure::Type::ANGULAR, lat_0};
+
+static const ParamMapping paramLongFalseOriginLongOfCenter = {
+ EPSG_NAME_PARAMETER_LONGITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_FALSE_ORIGIN, WKT1_LONGITUDE_OF_CENTER,
+ common::UnitOfMeasure::Type::ANGULAR, lon_0};
+
+static const ParamMapping *const paramsAEA[] = {
+ &paramLatFalseOriginLatOfCenter,
+ &paramLongFalseOriginLongOfCenter,
+ &paramLatitude1stStdParallel,
+ &paramLatitude2ndStdParallel,
+ &paramFalseEastingOrigin,
+ &paramFalseNorthingOrigin,
+ nullptr};
+
+static const ParamMapping *const paramsLCC2SP[] = {
+ &paramLatitudeFalseOrigin,
+ &paramLongitudeFalseOrigin,
+ &paramLatitude1stStdParallel,
+ &paramLatitude2ndStdParallel,
+ &paramFalseEastingOrigin,
+ &paramFalseNorthingOrigin,
+ nullptr,
+};
+
+static const ParamMapping paramEllipsoidScaleFactor = {
+ EPSG_NAME_PARAMETER_ELLIPSOID_SCALE_FACTOR,
+ EPSG_CODE_PARAMETER_ELLIPSOID_SCALE_FACTOR, nullptr,
+ common::UnitOfMeasure::Type::SCALE, k_0};
+
+static const ParamMapping *const paramsLCC2SPMichigan[] = {
+ &paramLatitudeFalseOrigin, &paramLongitudeFalseOrigin,
+ &paramLatitude1stStdParallel, &paramLatitude2ndStdParallel,
+ &paramFalseEastingOrigin, &paramFalseNorthingOrigin,
+ &paramEllipsoidScaleFactor, nullptr,
+};
+
+static const ParamMapping paramLatNatLatCenter = {
+ EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_LATITUDE_OF_CENTER,
+ common::UnitOfMeasure::Type::ANGULAR, lat_0};
+
+static const ParamMapping paramLonNatLonCenter = {
+ EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, WKT1_LONGITUDE_OF_CENTER,
+ common::UnitOfMeasure::Type::ANGULAR, lon_0};
+
+static const ParamMapping *const paramsAEQD[]{
+ &paramLatNatLatCenter, &paramLonNatLonCenter, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping *const paramsNatOrigin[] = {
+ &paramLatitudeNatOrigin, &paramLongitudeNatOrigin, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramLatNatOriginLat1 = {
+ EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_STANDARD_PARALLEL_1,
+ common::UnitOfMeasure::Type::ANGULAR, lat_1};
+
+static const ParamMapping *const paramsBonne[] = {
+ &paramLatNatOriginLat1, &paramLongitudeNatOrigin, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramLat1stParallelLatTs = {
+ EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, WKT1_STANDARD_PARALLEL_1,
+ common::UnitOfMeasure::Type::ANGULAR, lat_ts};
+
+static const ParamMapping *const paramsCEA[] = {
+ &paramLat1stParallelLatTs, &paramLongitudeNatOrigin, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping *const paramsEQDC[] = {&paramLatNatLatCenter,
+ &paramLonNatLonCenter,
+ &paramLatitude1stStdParallel,
+ &paramLatitude2ndStdParallel,
+ &paramFalseEasting,
+ &paramFalseNorthing,
+ nullptr};
+
+static const ParamMapping *const paramsLonNatOrigin[] = {
+ &paramLongitudeNatOrigin, &paramFalseEasting, &paramFalseNorthing, nullptr};
+
+static const ParamMapping *const paramsEqc[] = // same as paramsCEA
+ {&paramLat1stParallelLatTs, &paramLongitudeNatOrigin, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramSatelliteHeight = {
+ "Satellite Height", 0, "satellite_height",
+ common::UnitOfMeasure::Type::LINEAR, h};
+
+static const ParamMapping *const paramsGeos[] = {
+ &paramLongitudeNatOrigin, &paramSatelliteHeight, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramLatCentreLatCenter = {
+ EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, WKT1_LATITUDE_OF_CENTER,
+ common::UnitOfMeasure::Type::ANGULAR, lat_0};
+
+static const ParamMapping paramLonCentreLonCenterLonc = {
+ EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, WKT1_LONGITUDE_OF_CENTER,
+ common::UnitOfMeasure::Type::ANGULAR, lonc};
+
+static const ParamMapping paramLatCentreLatOrigin = {
+ EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, WKT1_LATITUDE_OF_ORIGIN,
+ common::UnitOfMeasure::Type::ANGULAR, lat_0};
+
+static const ParamMapping paramAzimuth = {
+ EPSG_NAME_PARAMETER_AZIMUTH_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_AZIMUTH_INITIAL_LINE, WKT1_AZIMUTH,
+ common::UnitOfMeasure::Type::ANGULAR, alpha};
+
+static const ParamMapping paramAngleToSkewGrid = {
+ EPSG_NAME_PARAMETER_ANGLE_RECTIFIED_TO_SKEW_GRID,
+ EPSG_CODE_PARAMETER_ANGLE_RECTIFIED_TO_SKEW_GRID, WKT1_RECTIFIED_GRID_ANGLE,
+ common::UnitOfMeasure::Type::ANGULAR, gamma};
+static const ParamMapping paramScaleFactorInitialLine = {
+ EPSG_NAME_PARAMETER_SCALE_FACTOR_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_INITIAL_LINE, WKT1_SCALE_FACTOR,
+ common::UnitOfMeasure::Type::SCALE, k};
+
+static const ParamMapping *const paramsHomVariantA[] = {
+ &paramLatCentreLatCenter,
+ &paramLonCentreLonCenterLonc,
+ &paramAzimuth,
+ &paramAngleToSkewGrid,
+ &paramScaleFactorInitialLine,
+ &paramFalseEasting,
+ &paramFalseNorthing,
+ nullptr};
+
+static const ParamMapping paramFalseEastingProjectionCentre = {
+ EPSG_NAME_PARAMETER_EASTING_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_EASTING_PROJECTION_CENTRE, WKT1_FALSE_EASTING,
+ common::UnitOfMeasure::Type::LINEAR, x_0};
+
+static const ParamMapping paramFalseNorthingProjectionCentre = {
+ EPSG_NAME_PARAMETER_NORTHING_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_NORTHING_PROJECTION_CENTRE, WKT1_FALSE_NORTHING,
+ common::UnitOfMeasure::Type::LINEAR, y_0};
+
+static const ParamMapping *const paramsHomVariantB[] = {
+ &paramLatCentreLatCenter,
+ &paramLonCentreLonCenterLonc,
+ &paramAzimuth,
+ &paramAngleToSkewGrid,
+ &paramScaleFactorInitialLine,
+ &paramFalseEastingProjectionCentre,
+ &paramFalseNorthingProjectionCentre,
+ nullptr};
+
+static const ParamMapping paramLatPoint1 = {
+ "Latitude of 1st point", 0, "latitude_of_point_1",
+ common::UnitOfMeasure::Type::ANGULAR, lat_1};
+
+static const ParamMapping paramLonPoint1 = {
+ "Longitude of 1st point", 0, "longitude_of_point_1",
+ common::UnitOfMeasure::Type::ANGULAR, lon_1};
+
+static const ParamMapping paramLatPoint2 = {
+ "Latitude of 2nd point", 0, "latitude_of_point_2",
+ common::UnitOfMeasure::Type::ANGULAR, lat_2};
+
+static const ParamMapping paramLonPoint2 = {
+ "Longitude of 2nd point", 0, "longitude_of_point_2",
+ common::UnitOfMeasure::Type::ANGULAR, lon_2};
+
+static const ParamMapping *const paramsHomTwoPoint[] = {
+ &paramLatCentreLatOrigin,
+ &paramLatPoint1,
+ &paramLonPoint1,
+ &paramLatPoint2,
+ &paramLonPoint2,
+ &paramScaleFactorInitialLine,
+ &paramFalseEastingProjectionCentre,
+ &paramFalseNorthingProjectionCentre,
+ nullptr};
+
+static const ParamMapping *const paramsIMWP[] = {
+ &paramLongitudeNatOrigin, &paramLatitude1stStdParallel,
+ &paramLatitude2ndStdParallel, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramLonCentreLonCenter = {
+ EPSG_NAME_PARAMETER_LONGITUDE_OF_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_ORIGIN, WKT1_LONGITUDE_OF_CENTER,
+ common::UnitOfMeasure::Type::ANGULAR, lon_0};
+
+static const ParamMapping paramColatitudeConeAxis = {
+ EPSG_NAME_PARAMETER_COLATITUDE_CONE_AXIS,
+ EPSG_CODE_PARAMETER_COLATITUDE_CONE_AXIS, WKT1_AZIMUTH,
+ common::UnitOfMeasure::Type::ANGULAR,
+ nullptr}; /* ignored by PROJ currently */
+
+static const ParamMapping paramLatitudePseudoStdParallel = {
+ EPSG_NAME_PARAMETER_LATITUDE_PSEUDO_STANDARD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_PSEUDO_STANDARD_PARALLEL,
+ "pseudo_standard_parallel_1", common::UnitOfMeasure::Type::ANGULAR,
+ nullptr}; /* ignored by PROJ currently */
+
+static const ParamMapping paramScaleFactorPseudoStdParallel = {
+ EPSG_NAME_PARAMETER_SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL,
+ WKT1_SCALE_FACTOR, common::UnitOfMeasure::Type::SCALE,
+ k}; /* ignored by PROJ currently */
+
+static const ParamMapping *const krovakParameters[] = {
+ &paramLatCentreLatCenter,
+ &paramLonCentreLonCenter,
+ &paramColatitudeConeAxis,
+ &paramLatitudePseudoStdParallel,
+ &paramScaleFactorPseudoStdParallel,
+ &paramFalseEasting,
+ &paramFalseNorthing,
+ nullptr};
+
+static const ParamMapping *const paramsLaea[] = {
+ &paramLatNatLatCenter, &paramLonNatLonCenter, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping *const paramsMiller[] = {
+ &paramLonNatLonCenter, &paramFalseEasting, &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramLatMerc1SP = {
+ EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ nullptr, // always set to zero, not to be exported in WKT1
+ common::UnitOfMeasure::Type::ANGULAR,
+ nullptr}; // always set to zero, not to be exported in PROJ strings
+
+static const ParamMapping paramScaleFactorK = {
+ EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, WKT1_SCALE_FACTOR,
+ common::UnitOfMeasure::Type::SCALE, k};
+
+static const ParamMapping *const paramsMerc1SP[] = {
+ &paramLatMerc1SP, &paramLongitudeNatOrigin, &paramScaleFactorK,
+ &paramFalseEasting, &paramFalseNorthing, nullptr};
+
+static const ParamMapping *const paramsMerc2SP[] = {
+ &paramLat1stParallelLatTs, &paramLongitudeNatOrigin, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping *const paramsObliqueStereo[] = {
+ &paramLatitudeNatOrigin, &paramLongitudeNatOrigin, &paramScaleFactorK,
+ &paramFalseEasting, &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramLatStdParallel = {
+ EPSG_NAME_PARAMETER_LATITUDE_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_STD_PARALLEL, WKT1_LATITUDE_OF_ORIGIN,
+ common::UnitOfMeasure::Type::ANGULAR, lat_ts};
+
+static const ParamMapping paramsLonOrigin = {
+ EPSG_NAME_PARAMETER_LONGITUDE_OF_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_ORIGIN, WKT1_CENTRAL_MERIDIAN,
+ common::UnitOfMeasure::Type::ANGULAR, lon_0};
+
+static const ParamMapping *const paramsPolarStereo[] = {
+ &paramLatStdParallel, &paramsLonOrigin, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping *const paramsLonNatOriginLongitudeCentre[] = {
+ &paramLonNatLonCenter, &paramFalseEasting, &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramLatTrueScaleWag3 = {
+ "Latitude of true scale", 0, WKT1_LATITUDE_OF_ORIGIN,
+ common::UnitOfMeasure::Type::ANGULAR, lat_ts};
+
+static const ParamMapping *const paramsWag3[] = {
+ &paramLatTrueScaleWag3, &paramLongitudeNatOrigin, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramPegLat = {
+ "Peg point latitude", 0, "peg_point_latitude",
+ common::UnitOfMeasure::Type::ANGULAR, "plat_0"};
+
+static const ParamMapping paramPegLon = {
+ "Peg point longitude", 0, "peg_point_longitude",
+ common::UnitOfMeasure::Type::ANGULAR, "plon_0"};
+
+static const ParamMapping paramPegHeading = {
+ "Peg point heading", 0, "peg_point_heading",
+ common::UnitOfMeasure::Type::ANGULAR, "phdg_0"};
+
+static const ParamMapping paramPegHeight = {
+ "Peg point height", 0, "peg_point_height",
+ common::UnitOfMeasure::Type::LINEAR, "h_0"};
+
+static const ParamMapping *const paramsSch[] = {
+ &paramPegLat, &paramPegLon, &paramPegHeading, &paramPegHeight, nullptr};
+
+static const ParamMapping *const paramsWink1[] = {
+ &paramLongitudeNatOrigin, &paramLat1stParallelLatTs, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping *const paramsWink2[] = {
+ &paramLongitudeNatOrigin, &paramLatitude1stStdParallel, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramLatLoxim = {
+ EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_LATITUDE_OF_ORIGIN,
+ common::UnitOfMeasure::Type::ANGULAR, lat_1};
+
+static const ParamMapping *const paramsLoxim[] = {
+ &paramLatLoxim, &paramLongitudeNatOrigin, &paramFalseEasting,
+ &paramFalseNorthing, nullptr};
+
+static const ParamMapping paramLonCentre = {
+ EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, nullptr,
+ common::UnitOfMeasure::Type::ANGULAR, lon_0};
+
+static const ParamMapping paramLabordeObliqueMercatorAzimuth = {
+ EPSG_NAME_PARAMETER_AZIMUTH_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_AZIMUTH_INITIAL_LINE, nullptr,
+ common::UnitOfMeasure::Type::ANGULAR, "azi"};
+
+static const ParamMapping *const paramsLabordeObliqueMercator[] = {
+ &paramLatCentreLatOrigin,
+ &paramLonCentre,
+ &paramLabordeObliqueMercatorAzimuth,
+ &paramScaleFactorInitialLine,
+ &paramFalseEasting,
+ &paramFalseNorthing,
+ nullptr};
+
+static const MethodMapping methodMappings[] = {
+ {EPSG_NAME_METHOD_TRANSVERSE_MERCATOR, EPSG_CODE_METHOD_TRANSVERSE_MERCATOR,
+ "Transverse_Mercator", "tmerc", nullptr, paramsNatOriginScale},
+
+ {EPSG_NAME_METHOD_TRANSVERSE_MERCATOR_SOUTH_ORIENTATED,
+ EPSG_CODE_METHOD_TRANSVERSE_MERCATOR_SOUTH_ORIENTATED,
+ "Transverse_Mercator_South_Orientated", "tmerc", "axis=wsu",
+ paramsNatOriginScale},
+
+ {PROJ_WKT2_NAME_METHOD_TWO_POINT_EQUIDISTANT, 0, "Two_Point_Equidistant",
+ "tpeqd", nullptr, paramsTPEQD},
+
+ {EPSG_NAME_METHOD_TUNISIA_MAPPING_GRID,
+ EPSG_CODE_METHOD_TUNISIA_MAPPING_GRID, "Tunisia_Mapping_Grid", nullptr,
+ nullptr, // no proj equivalent
+ paramsTMG},
+
+ {EPSG_NAME_METHOD_ALBERS_EQUAL_AREA, EPSG_CODE_METHOD_ALBERS_EQUAL_AREA,
+ "Albers_Conic_Equal_Area", "aea", nullptr, paramsAEA},
+
+ {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_1SP,
+ EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP,
+ "Lambert_Conformal_Conic_1SP", "lcc", nullptr,
+ []() {
+ static const ParamMapping paramLatLCC1SP = {
+ EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ WKT1_LATITUDE_OF_ORIGIN, common::UnitOfMeasure::Type::ANGULAR,
+ lat_1};
+
+ static const ParamMapping *const x[] = {
+ &paramLatLCC1SP, &paramLongitudeNatOrigin, &paramScaleFactor,
+ &paramFalseEasting, &paramFalseNorthing, nullptr,
+ };
+ return x;
+ }()},
+
+ {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
+ EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
+ "Lambert_Conformal_Conic_2SP", "lcc", nullptr, paramsLCC2SP},
+
+ {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN,
+ EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN,
+ nullptr, // no mapping to WKT1_GDAL
+ "lcc", nullptr, paramsLCC2SPMichigan},
+
+ {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_BELGIUM,
+ EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_BELGIUM,
+ "Lambert_Conformal_Conic_2SP_Belgium", "lcc",
+ nullptr, // FIXME: this is what is done in GDAL, but the formula of
+ // LCC 2SP
+ // Belgium in the EPSG 7.2 guidance is difference from the regular
+ // LCC 2SP
+ paramsLCC2SP},
+
+ {EPSG_NAME_METHOD_MODIFIED_AZIMUTHAL_EQUIDISTANT,
+ EPSG_CODE_METHOD_MODIFIED_AZIMUTHAL_EQUIDISTANT, "Azimuthal_Equidistant",
+ "aeqd", nullptr, paramsAEQD},
+
+ {EPSG_NAME_METHOD_GUAM_PROJECTION, EPSG_CODE_METHOD_GUAM_PROJECTION,
+ nullptr, // no mapping to GDAL WKT1
+ "aeqd", "guam", paramsNatOrigin},
+
+ {EPSG_NAME_METHOD_BONNE, EPSG_CODE_METHOD_BONNE, "Bonne", "bonne", nullptr,
+ paramsBonne},
+
+ {EPSG_NAME_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL,
+ EPSG_CODE_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL,
+ "Cylindrical_Equal_Area", "cea", nullptr, paramsCEA},
+
+ {EPSG_NAME_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA,
+ EPSG_CODE_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA, "Cylindrical_Equal_Area",
+ "cea", nullptr, paramsCEA},
+
+ {EPSG_NAME_METHOD_CASSINI_SOLDNER, EPSG_CODE_METHOD_CASSINI_SOLDNER,
+ "Cassini_Soldner", "cass", nullptr, paramsNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_EQUIDISTANT_CONIC, 0, "Equidistant_Conic", "eqdc",
+ nullptr, paramsEQDC},
+
+ {PROJ_WKT2_NAME_METHOD_ECKERT_I, 0, "Eckert_I", "eck1", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_ECKERT_II, 0, "Eckert_II", "eck2", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_ECKERT_III, 0, "Eckert_III", "eck3", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_ECKERT_IV, 0, "Eckert_IV", "eck4", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_ECKERT_V, 0, "Eckert_V", "eck5", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_ECKERT_VI, 0, "Eckert_VI", "eck6", nullptr,
+ paramsLonNatOrigin},
+
+ {EPSG_NAME_METHOD_EQUIDISTANT_CYLINDRICAL,
+ EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL, "Equirectangular", "eqc",
+ nullptr, paramsEqc},
+
+ {EPSG_NAME_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL,
+ EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL, "Equirectangular",
+ "eqc", nullptr, paramsEqc},
+
+ {PROJ_WKT2_NAME_METHOD_GALL_STEREOGRAPHIC, 0, "Gall_Stereographic", "gall",
+ nullptr, paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_GOODE_HOMOLOSINE, 0, "Goode_Homolosine", "goode",
+ nullptr, paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_INTERRUPTED_GOODE_HOMOLOSINE, 0,
+ "Interrupted_Goode_Homolosine", "igh", nullptr, paramsLonNatOrigin},
+
+ // No WKT1 representation fr sweep=x
+ {PROJ_WKT2_NAME_METHOD_GEOSTATIONARY_SATELLITE_SWEEP_X, 0, nullptr, "geos",
+ "sweep=x", paramsGeos},
+
+ {PROJ_WKT2_NAME_METHOD_GEOSTATIONARY_SATELLITE_SWEEP_Y, 0,
+ "Geostationary_Satellite", "geos", nullptr, paramsGeos},
+
+ {PROJ_WKT2_NAME_METHOD_GAUSS_SCHREIBER_TRANSVERSE_MERCATOR, 0,
+ "Gauss_Schreiber_Transverse_Mercator", "gstmerc", nullptr,
+ paramsNatOriginScale},
+
+ {PROJ_WKT2_NAME_METHOD_GNOMONIC, 0, "Gnomonic", "gnom", nullptr,
+ paramsNatOrigin},
+
+ {EPSG_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A,
+ EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A,
+ "Hotine_Oblique_Mercator", "omerc", "no_uoff", paramsHomVariantA},
+
+ {EPSG_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_B,
+ EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_B,
+ "Hotine_Oblique_Mercator_Azimuth_Center", "omerc", nullptr,
+ paramsHomVariantB},
+
+ {PROJ_WKT2_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN, 0,
+ "Hotine_Oblique_Mercator_Two_Point_Natural_Origin", "omerc", nullptr,
+ paramsHomTwoPoint},
+
+ {PROJ_WKT2_NAME_INTERNATIONAL_MAP_WORLD_POLYCONIC, 0,
+ "International_Map_of_the_World_Polyconic", "imw_p", nullptr, paramsIMWP},
+
+ {EPSG_NAME_METHOD_KROVAK_NORTH_ORIENTED,
+ EPSG_CODE_METHOD_KROVAK_NORTH_ORIENTED, "Krovak", "krovak", nullptr,
+ krovakParameters},
+
+ {EPSG_NAME_METHOD_KROVAK, EPSG_CODE_METHOD_KROVAK, "Krovak", "krovak",
+ "axis=swu", krovakParameters},
+
+ {EPSG_NAME_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA,
+ EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA,
+ "Lambert_Azimuthal_Equal_Area", "laea", nullptr, paramsLaea},
+
+ {EPSG_NAME_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA_SPHERICAL,
+ EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA_SPHERICAL,
+ "Lambert_Azimuthal_Equal_Area", "laea", nullptr, paramsLaea},
+
+ {PROJ_WKT2_NAME_METHOD_MILLER_CYLINDRICAL, 0, "Miller_Cylindrical", "mill",
+ "R_A", paramsMiller},
+
+ {EPSG_NAME_METHOD_MERCATOR_VARIANT_A, EPSG_CODE_METHOD_MERCATOR_VARIANT_A,
+ "Mercator_1SP", "merc", nullptr, paramsMerc1SP},
+
+ {EPSG_NAME_METHOD_MERCATOR_VARIANT_B, EPSG_CODE_METHOD_MERCATOR_VARIANT_B,
+ "Mercator_2SP", "merc", nullptr, paramsMerc2SP},
+
+ {EPSG_NAME_METHOD_POPULAR_VISUALISATION_PSEUDO_MERCATOR,
+ EPSG_CODE_METHOD_POPULAR_VISUALISATION_PSEUDO_MERCATOR,
+ "Popular_Visualisation_Pseudo_Mercator", // particular case actually
+ // handled manually
+ "webmerc", nullptr, paramsNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_MOLLWEIDE, 0, "Mollweide", "moll", nullptr,
+ paramsLonNatOrigin},
+
+ {EPSG_NAME_METHOD_NZMG, EPSG_CODE_METHOD_NZMG, "New_Zealand_Map_Grid",
+ "nzmg", nullptr, paramsNatOrigin},
+
+ {
+ EPSG_NAME_METHOD_OBLIQUE_STEREOGRAPHIC,
+ EPSG_CODE_METHOD_OBLIQUE_STEREOGRAPHIC, "Oblique_Stereographic",
+ "sterea", nullptr, paramsObliqueStereo,
+ },
+
+ {EPSG_NAME_METHOD_ORTHOGRAPHIC, EPSG_CODE_METHOD_ORTHOGRAPHIC,
+ "Orthographic", "ortho", nullptr, paramsNatOrigin},
+
+ {EPSG_NAME_METHOD_AMERICAN_POLYCONIC, EPSG_CODE_METHOD_AMERICAN_POLYCONIC,
+ "Polyconic", "poly", nullptr, paramsNatOrigin},
+
+ {EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A,
+ EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A, "Polar_Stereographic",
+ "stere", nullptr, paramsObliqueStereo},
+
+ {EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B,
+ EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B, "Polar_Stereographic",
+ "stere", nullptr, paramsPolarStereo},
+
+ {PROJ_WKT2_NAME_METHOD_ROBINSON, 0, "Robinson", "robin", nullptr,
+ paramsLonNatOriginLongitudeCentre},
+
+ {PROJ_WKT2_NAME_METHOD_SINUSOIDAL, 0, "Sinusoidal", "sinu", nullptr,
+ paramsLonNatOriginLongitudeCentre},
+
+ {PROJ_WKT2_NAME_METHOD_STEREOGRAPHIC, 0, "Stereographic", "stere", nullptr,
+ paramsObliqueStereo},
+
+ {PROJ_WKT2_NAME_METHOD_VAN_DER_GRINTEN, 0, "VanDerGrinten", "vandg", "R_A",
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_WAGNER_I, 0, "Wagner_I", "wag1", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_WAGNER_II, 0, "Wagner_II", "wag2", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_WAGNER_III, 0, "Wagner_III", "wag3", nullptr,
+ paramsWag3},
+
+ {PROJ_WKT2_NAME_METHOD_WAGNER_IV, 0, "Wagner_IV", "wag4", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_WAGNER_V, 0, "Wagner_V", "wag5", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_WAGNER_VI, 0, "Wagner_VI", "wag6", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_WAGNER_VII, 0, "Wagner_VII", "wag7", nullptr,
+ paramsLonNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_QUADRILATERALIZED_SPHERICAL_CUBE, 0,
+ "Quadrilateralized_Spherical_Cube", "qsc", nullptr, paramsNatOrigin},
+
+ {PROJ_WKT2_NAME_METHOD_SPHERICAL_CROSS_TRACK_HEIGHT, 0,
+ "Spherical_Cross_Track_Height", "sch", nullptr, paramsSch},
+
+ // The following methods have just the WKT <--> PROJ string mapping, but
+ // no setter. Similarly to GDAL
+
+ {"Aitoff", 0, "Aitoff", "aitoff", nullptr, paramsLonNatOrigin},
+
+ {"Winkel I", 0, "Winkel_I", "wink1", nullptr, paramsWink1},
+
+ {"Winkel II", 0, "Winkel_II", "wink2", nullptr, paramsWink2},
+
+ {"Winkel Tripel", 0, "Winkel_Tripel", "wintri", nullptr, paramsWink2},
+
+ {"Craster Parabolic", 0, "Craster_Parabolic", "crast", nullptr,
+ paramsLonNatOrigin},
+
+ {"Loximuthal", 0, "Loximuthal", "loxim", nullptr, paramsLoxim},
+
+ {"Quartic Authalic", 0, "Quartic_Authalic", "qua_aut", nullptr,
+ paramsLonNatOrigin},
+
+ {EPSG_NAME_METHOD_EQUAL_EARTH, EPSG_CODE_METHOD_EQUAL_EARTH, nullptr,
+ "eqearth", nullptr, paramsLonNatOrigin},
+
+ {EPSG_NAME_METHOD_LABORDE_OBLIQUE_MERCATOR,
+ EPSG_CODE_METHOD_LABORDE_OBLIQUE_MERCATOR, nullptr, "labrd", nullptr,
+ paramsLabordeObliqueMercator},
+
+};
+
+#define METHOD_NAME_CODE(method) \
+ { EPSG_NAME_METHOD_##method, EPSG_CODE_METHOD_##method }
+
+static const struct MethodNameCode {
+ const char *name;
+ int epsg_code;
+} methodNameCodes[] = {
+ // Projection methods
+ METHOD_NAME_CODE(TRANSVERSE_MERCATOR),
+ METHOD_NAME_CODE(TRANSVERSE_MERCATOR_SOUTH_ORIENTATED),
+ METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_1SP), METHOD_NAME_CODE(NZMG),
+ METHOD_NAME_CODE(TUNISIA_MAPPING_GRID), METHOD_NAME_CODE(ALBERS_EQUAL_AREA),
+ METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_2SP),
+ METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_2SP_BELGIUM),
+ METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN),
+ METHOD_NAME_CODE(MODIFIED_AZIMUTHAL_EQUIDISTANT),
+ METHOD_NAME_CODE(GUAM_PROJECTION), METHOD_NAME_CODE(BONNE),
+ METHOD_NAME_CODE(LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL),
+ METHOD_NAME_CODE(LAMBERT_CYLINDRICAL_EQUAL_AREA),
+ METHOD_NAME_CODE(CASSINI_SOLDNER),
+ METHOD_NAME_CODE(EQUIDISTANT_CYLINDRICAL),
+ METHOD_NAME_CODE(EQUIDISTANT_CYLINDRICAL_SPHERICAL),
+ METHOD_NAME_CODE(HOTINE_OBLIQUE_MERCATOR_VARIANT_A),
+ METHOD_NAME_CODE(HOTINE_OBLIQUE_MERCATOR_VARIANT_B),
+ METHOD_NAME_CODE(KROVAK_NORTH_ORIENTED), METHOD_NAME_CODE(KROVAK),
+ METHOD_NAME_CODE(LAMBERT_AZIMUTHAL_EQUAL_AREA),
+ METHOD_NAME_CODE(POPULAR_VISUALISATION_PSEUDO_MERCATOR),
+ METHOD_NAME_CODE(MERCATOR_VARIANT_A), METHOD_NAME_CODE(MERCATOR_VARIANT_B),
+ METHOD_NAME_CODE(OBLIQUE_STEREOGRAPHIC),
+ METHOD_NAME_CODE(AMERICAN_POLYCONIC),
+ METHOD_NAME_CODE(POLAR_STEREOGRAPHIC_VARIANT_A),
+ METHOD_NAME_CODE(POLAR_STEREOGRAPHIC_VARIANT_B),
+ METHOD_NAME_CODE(EQUAL_EARTH), METHOD_NAME_CODE(LABORDE_OBLIQUE_MERCATOR),
+ // Other conversions
+ METHOD_NAME_CODE(CHANGE_VERTICAL_UNIT),
+ METHOD_NAME_CODE(AXIS_ORDER_REVERSAL_2D),
+ METHOD_NAME_CODE(AXIS_ORDER_REVERSAL_3D),
+ METHOD_NAME_CODE(GEOGRAPHIC_GEOCENTRIC),
+ // Transformations
+ METHOD_NAME_CODE(LONGITUDE_ROTATION),
+ METHOD_NAME_CODE(AFFINE_PARAMETRIC_TRANSFORMATION),
+ METHOD_NAME_CODE(COORDINATE_FRAME_GEOCENTRIC),
+ METHOD_NAME_CODE(COORDINATE_FRAME_GEOGRAPHIC_2D),
+ METHOD_NAME_CODE(COORDINATE_FRAME_GEOGRAPHIC_3D),
+ METHOD_NAME_CODE(POSITION_VECTOR_GEOCENTRIC),
+ METHOD_NAME_CODE(POSITION_VECTOR_GEOGRAPHIC_2D),
+ METHOD_NAME_CODE(POSITION_VECTOR_GEOGRAPHIC_3D),
+ METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_GEOCENTRIC),
+ METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D),
+ METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_GEOGRAPHIC_3D),
+ METHOD_NAME_CODE(TIME_DEPENDENT_COORDINATE_FRAME_GEOCENTRIC),
+ METHOD_NAME_CODE(TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_2D),
+ METHOD_NAME_CODE(TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_3D),
+ METHOD_NAME_CODE(TIME_DEPENDENT_POSITION_VECTOR_GEOCENTRIC),
+ METHOD_NAME_CODE(TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_2D),
+ METHOD_NAME_CODE(TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_3D),
+ METHOD_NAME_CODE(MOLODENSKY_BADEKAS_CF_GEOCENTRIC),
+ METHOD_NAME_CODE(MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_2D),
+ METHOD_NAME_CODE(MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_3D),
+ METHOD_NAME_CODE(MOLODENSKY_BADEKAS_PV_GEOCENTRIC),
+ METHOD_NAME_CODE(MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_2D),
+ METHOD_NAME_CODE(MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_3D),
+ METHOD_NAME_CODE(MOLODENSKY), METHOD_NAME_CODE(ABRIDGED_MOLODENSKY),
+ METHOD_NAME_CODE(GEOGRAPHIC2D_OFFSETS),
+ METHOD_NAME_CODE(GEOGRAPHIC2D_WITH_HEIGHT_OFFSETS),
+ METHOD_NAME_CODE(GEOGRAPHIC3D_OFFSETS), METHOD_NAME_CODE(VERTICAL_OFFSET),
+ METHOD_NAME_CODE(NTV2), METHOD_NAME_CODE(NTV1), METHOD_NAME_CODE(NADCON),
+ METHOD_NAME_CODE(VERTCON),
+};
+
+#define PARAM_NAME_CODE(method) \
+ { EPSG_NAME_PARAMETER_##method, EPSG_CODE_PARAMETER_##method }
+
+static const struct ParamNameCode {
+ const char *name;
+ int epsg_code;
+} paramNameCodes[] = {
+ // Parameters of projection methods
+ PARAM_NAME_CODE(COLATITUDE_CONE_AXIS),
+ PARAM_NAME_CODE(LATITUDE_OF_NATURAL_ORIGIN),
+ PARAM_NAME_CODE(LONGITUDE_OF_NATURAL_ORIGIN),
+ PARAM_NAME_CODE(SCALE_FACTOR_AT_NATURAL_ORIGIN),
+ PARAM_NAME_CODE(FALSE_EASTING), PARAM_NAME_CODE(FALSE_NORTHING),
+ PARAM_NAME_CODE(LATITUDE_PROJECTION_CENTRE),
+ PARAM_NAME_CODE(LONGITUDE_PROJECTION_CENTRE),
+ PARAM_NAME_CODE(AZIMUTH_INITIAL_LINE),
+ PARAM_NAME_CODE(ANGLE_RECTIFIED_TO_SKEW_GRID),
+ PARAM_NAME_CODE(SCALE_FACTOR_INITIAL_LINE),
+ PARAM_NAME_CODE(EASTING_PROJECTION_CENTRE),
+ PARAM_NAME_CODE(NORTHING_PROJECTION_CENTRE),
+ PARAM_NAME_CODE(LATITUDE_PSEUDO_STANDARD_PARALLEL),
+ PARAM_NAME_CODE(SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL),
+ PARAM_NAME_CODE(LATITUDE_FALSE_ORIGIN),
+ PARAM_NAME_CODE(LONGITUDE_FALSE_ORIGIN),
+ PARAM_NAME_CODE(LATITUDE_1ST_STD_PARALLEL),
+ PARAM_NAME_CODE(LATITUDE_2ND_STD_PARALLEL),
+ PARAM_NAME_CODE(EASTING_FALSE_ORIGIN),
+ PARAM_NAME_CODE(NORTHING_FALSE_ORIGIN),
+ PARAM_NAME_CODE(LATITUDE_STD_PARALLEL),
+ PARAM_NAME_CODE(LONGITUDE_OF_ORIGIN),
+ PARAM_NAME_CODE(ELLIPSOID_SCALE_FACTOR),
+ // Parameters of transformations
+ PARAM_NAME_CODE(SEMI_MAJOR_AXIS_DIFFERENCE),
+ PARAM_NAME_CODE(FLATTENING_DIFFERENCE),
+ PARAM_NAME_CODE(LATITUDE_LONGITUDE_DIFFERENCE_FILE),
+ PARAM_NAME_CODE(GEOID_CORRECTION_FILENAME),
+ PARAM_NAME_CODE(VERTICAL_OFFSET_FILE),
+ PARAM_NAME_CODE(LATITUDE_DIFFERENCE_FILE),
+ PARAM_NAME_CODE(LONGITUDE_DIFFERENCE_FILE),
+ PARAM_NAME_CODE(UNIT_CONVERSION_SCALAR), PARAM_NAME_CODE(LATITUDE_OFFSET),
+ PARAM_NAME_CODE(LONGITUDE_OFFSET), PARAM_NAME_CODE(VERTICAL_OFFSET),
+ PARAM_NAME_CODE(GEOID_UNDULATION), PARAM_NAME_CODE(A0), PARAM_NAME_CODE(A1),
+ PARAM_NAME_CODE(A2), PARAM_NAME_CODE(B0), PARAM_NAME_CODE(B1),
+ PARAM_NAME_CODE(B2), PARAM_NAME_CODE(X_AXIS_TRANSLATION),
+ PARAM_NAME_CODE(Y_AXIS_TRANSLATION), PARAM_NAME_CODE(Z_AXIS_TRANSLATION),
+ PARAM_NAME_CODE(X_AXIS_ROTATION), PARAM_NAME_CODE(Y_AXIS_ROTATION),
+ PARAM_NAME_CODE(Z_AXIS_ROTATION), PARAM_NAME_CODE(SCALE_DIFFERENCE),
+ PARAM_NAME_CODE(RATE_X_AXIS_TRANSLATION),
+ PARAM_NAME_CODE(RATE_Y_AXIS_TRANSLATION),
+ PARAM_NAME_CODE(RATE_Z_AXIS_TRANSLATION),
+ PARAM_NAME_CODE(RATE_X_AXIS_ROTATION),
+ PARAM_NAME_CODE(RATE_Y_AXIS_ROTATION),
+ PARAM_NAME_CODE(RATE_Z_AXIS_ROTATION),
+ PARAM_NAME_CODE(RATE_SCALE_DIFFERENCE), PARAM_NAME_CODE(REFERENCE_EPOCH),
+ PARAM_NAME_CODE(TRANSFORMATION_REFERENCE_EPOCH),
+ PARAM_NAME_CODE(ORDINATE_1_EVAL_POINT),
+ PARAM_NAME_CODE(ORDINATE_2_EVAL_POINT),
+ PARAM_NAME_CODE(ORDINATE_3_EVAL_POINT),
+};
+
+// end of anonymous namespace
+}
+
+// ---------------------------------------------------------------------------
+
+//! @endcond
+
+#endif // COORDINATEOPERATION_CONSTANTS_HH_INCLUDED
diff --git a/include/proj/internal/coordinateoperation_internal.hpp b/include/proj/internal/coordinateoperation_internal.hpp
new file mode 100644
index 00000000..83e1e987
--- /dev/null
+++ b/include/proj/internal/coordinateoperation_internal.hpp
@@ -0,0 +1,274 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef FROM_PROJ_CPP
+#error This file should only be included from a PROJ cpp file
+#endif
+
+#ifndef COORDINATEOPERATION_INTERNAL_HH_INCLUDED
+#define COORDINATEOPERATION_INTERNAL_HH_INCLUDED
+
+#include "proj/coordinateoperation.hpp"
+
+#include <vector>
+
+//! @cond Doxygen_Suppress
+
+NS_PROJ_START
+
+namespace operation {
+
+struct ParamMapping {
+ const char *wkt2_name;
+ const int epsg_code;
+ const char *wkt1_name;
+ const common::UnitOfMeasure::Type unit_type;
+ const char *proj_name;
+};
+
+struct MethodMapping {
+ const char *wkt2_name;
+ const int epsg_code;
+ const char *wkt1_name;
+ const char *proj_name_main;
+ const char *proj_name_aux;
+ const ParamMapping *const *params;
+};
+
+const MethodMapping *getMapping(int epsg_code) noexcept;
+const MethodMapping *getMappingFromWKT1(const std::string &wkt1_name) noexcept;
+const MethodMapping *getMapping(const char *wkt2_name) noexcept;
+const MethodMapping *getMapping(const OperationMethod *method) noexcept;
+std::vector<const MethodMapping *>
+getMappingsFromPROJName(const std::string &projName);
+const ParamMapping *getMapping(const MethodMapping *mapping,
+ const OperationParameterValue *param);
+const ParamMapping *getMappingFromWKT1(const MethodMapping *mapping,
+ const std::string &wkt1_name);
+// ---------------------------------------------------------------------------
+
+struct ESRIParamMapping {
+ const char *esri_name;
+ const char *wkt2_name;
+ int epsg_code;
+ float fixed_value;
+};
+
+struct ESRIMethodMapping {
+ const char *esri_name;
+ const char *wkt2_name;
+ int epsg_code;
+ const ESRIParamMapping *const params;
+};
+
+std::vector<const ESRIMethodMapping *>
+getMappingsFromESRI(const std::string &esri_name);
+
+// ---------------------------------------------------------------------------
+
+bool isAxisOrderReversal(int methodEPSGCode);
+
+// ---------------------------------------------------------------------------
+
+class InverseCoordinateOperation;
+/** Shared pointer of InverseCoordinateOperation */
+using InverseCoordinateOperationPtr =
+ std::shared_ptr<InverseCoordinateOperation>;
+/** Non-null shared pointer of InverseCoordinateOperation */
+using InverseCoordinateOperationNNPtr = util::nn<InverseCoordinateOperationPtr>;
+
+/** \brief Inverse operation of a CoordinateOperation.
+ *
+ * This is used when there is no straightforward way of building another
+ * subclass of CoordinateOperation that models the inverse operation.
+ */
+class InverseCoordinateOperation : virtual public CoordinateOperation {
+ public:
+ InverseCoordinateOperation(const CoordinateOperationNNPtr &forwardOperation,
+ bool wktSupportsInversion);
+
+ ~InverseCoordinateOperation() override;
+
+ void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+
+ CoordinateOperationNNPtr inverse() const override;
+
+ protected:
+ CoordinateOperationNNPtr forwardOperation_;
+ bool wktSupportsInversion_;
+
+ void setPropertiesFromForward();
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Inverse of a conversion. */
+class InverseConversion : public Conversion, public InverseCoordinateOperation {
+ public:
+ explicit InverseConversion(const ConversionNNPtr &forward);
+
+ ~InverseConversion() override;
+
+ void _exportToWKT(io::WKTFormatter *formatter) const override {
+ Conversion::_exportToWKT(formatter);
+ }
+
+ void
+ _exportToPROJString(io::PROJStringFormatter *formatter) const override {
+ InverseCoordinateOperation::_exportToPROJString(formatter);
+ }
+
+ bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override {
+ return InverseCoordinateOperation::_isEquivalentTo(other, criterion);
+ }
+
+ CoordinateOperationNNPtr inverse() const override {
+ return InverseCoordinateOperation::inverse();
+ }
+
+ ConversionNNPtr inverseAsConversion() const;
+
+#ifdef _MSC_VER
+ // To avoid a warning C4250: 'osgeo::proj::operation::InverseConversion':
+ // inherits
+ // 'osgeo::proj::operation::SingleOperation::osgeo::proj::operation::SingleOperation::gridsNeeded'
+ // via dominance
+ std::set<GridDescription>
+ gridsNeeded(const io::DatabaseContextPtr &databaseContext) const override {
+ return SingleOperation::gridsNeeded(databaseContext);
+ }
+#endif
+
+ static CoordinateOperationNNPtr create(const ConversionNNPtr &forward);
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Inverse of a transformation. */
+class InverseTransformation : public Transformation,
+ public InverseCoordinateOperation {
+ public:
+ explicit InverseTransformation(const TransformationNNPtr &forward);
+
+ ~InverseTransformation() override;
+
+ void _exportToWKT(io::WKTFormatter *formatter) const override;
+
+ void
+ _exportToPROJString(io::PROJStringFormatter *formatter) const override {
+ return InverseCoordinateOperation::_exportToPROJString(formatter);
+ }
+
+ bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override {
+ return InverseCoordinateOperation::_isEquivalentTo(other, criterion);
+ }
+
+ CoordinateOperationNNPtr inverse() const override {
+ return InverseCoordinateOperation::inverse();
+ }
+
+#ifdef _MSC_VER
+ // To avoid a warning C4250:
+ // 'osgeo::proj::operation::InverseTransformation': inherits
+ // 'osgeo::proj::operation::SingleOperation::osgeo::proj::operation::SingleOperation::gridsNeeded'
+ // via dominance
+ std::set<GridDescription>
+ gridsNeeded(const io::DatabaseContextPtr &databaseContext) const override {
+ return SingleOperation::gridsNeeded(databaseContext);
+ }
+#endif
+
+ static TransformationNNPtr create(const TransformationNNPtr &forward);
+};
+
+// ---------------------------------------------------------------------------
+
+class PROJBasedOperation;
+/** Shared pointer of PROJBasedOperation */
+using PROJBasedOperationPtr = std::shared_ptr<PROJBasedOperation>;
+/** Non-null shared pointer of PROJBasedOperation */
+using PROJBasedOperationNNPtr = util::nn<PROJBasedOperationPtr>;
+
+/** \brief A PROJ-string based coordinate operation.
+ */
+class PROJBasedOperation : public SingleOperation {
+ public:
+ ~PROJBasedOperation() override;
+
+ void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ CoordinateOperationNNPtr inverse() const override;
+
+ static PROJBasedOperationNNPtr
+ create(const util::PropertyMap &properties, const std::string &PROJString,
+ const crs::CRSPtr &sourceCRS, const crs::CRSPtr &targetCRS,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ static PROJBasedOperationNNPtr
+ create(const util::PropertyMap &properties,
+ const io::IPROJStringExportableNNPtr &projExportable, bool inverse,
+ const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS,
+ const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
+
+ std::set<GridDescription>
+ gridsNeeded(const io::DatabaseContextPtr &databaseContext) const override;
+
+ protected:
+ PROJBasedOperation(const OperationMethodNNPtr &methodIn,
+ const std::vector<GeneralParameterValueNNPtr> &values);
+
+ void _exportToPROJString(io::PROJStringFormatter *formatter)
+ const override; // throw(FormattingException)
+
+ INLINED_MAKE_SHARED
+
+ private:
+ io::IPROJStringExportablePtr projStringExportable_{};
+ bool inverse_ = false;
+};
+
+} // namespace operation
+
+NS_PROJ_END
+
+//! @endcond
+
+#endif // COORDINATEOPERATION_INTERNAL_HH_INCLUDED
diff --git a/include/proj/internal/coordinatesystem_internal.hpp b/include/proj/internal/coordinatesystem_internal.hpp
new file mode 100644
index 00000000..63c5f7af
--- /dev/null
+++ b/include/proj/internal/coordinatesystem_internal.hpp
@@ -0,0 +1,104 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef FROM_PROJ_CPP
+#error This file should only be included from a PROJ cpp file
+#endif
+
+#ifndef COORDINATESYSTEM_INTERNAL_HH_INCLUDED
+#define COORDINATESYSTEM_INTERNAL_HH_INCLUDED
+
+#include "proj/util.hpp"
+
+#include <map>
+#include <set>
+#include <string>
+
+//! @cond Doxygen_Suppress
+
+NS_PROJ_START
+
+namespace cs {
+
+// ---------------------------------------------------------------------------
+
+class AxisDirectionWKT1 : public util::CodeList {
+ public:
+ static const AxisDirectionWKT1 *valueOf(const std::string &nameIn);
+
+ static const AxisDirectionWKT1 NORTH;
+ static const AxisDirectionWKT1 SOUTH;
+ static const AxisDirectionWKT1 EAST;
+ static const AxisDirectionWKT1 WEST;
+ static const AxisDirectionWKT1 UP;
+ static const AxisDirectionWKT1 DOWN;
+ static const AxisDirectionWKT1 OTHER;
+
+ private:
+ explicit AxisDirectionWKT1(const std::string &nameIn);
+
+ static std::map<std::string, const AxisDirectionWKT1 *> registry;
+};
+
+// ---------------------------------------------------------------------------
+
+class AxisName {
+ public:
+ static const std::string Longitude;
+ static const std::string Latitude;
+ static const std::string Easting;
+ static const std::string Northing;
+ static const std::string Westing;
+ static const std::string Southing;
+ static const std::string Ellipsoidal_height;
+ static const std::string Geocentric_X;
+ static const std::string Geocentric_Y;
+ static const std::string Geocentric_Z;
+};
+
+// ---------------------------------------------------------------------------
+
+class AxisAbbreviation {
+ public:
+ static const std::string lon;
+ static const std::string lat;
+ static const std::string E;
+ static const std::string N;
+ static const std::string h;
+ static const std::string X;
+ static const std::string Y;
+ static const std::string Z;
+};
+
+} // namespace cs
+
+NS_PROJ_END
+
+//! @endcond
+
+#endif // COORDINATESYSTEM_INTERNAL_HH_INCLUDED
diff --git a/include/proj/internal/esri_projection_mappings.hpp b/include/proj/internal/esri_projection_mappings.hpp
new file mode 100644
index 00000000..4ceeb300
--- /dev/null
+++ b/include/proj/internal/esri_projection_mappings.hpp
@@ -0,0 +1,887 @@
+// This file was generated by scripts/build_esri_projection_mapping.py. DO NOT
+// EDIT !
+
+#ifndef FROM_COORDINATE_OPERATION_CPP
+#error This file should only be included from coordinateoperation.cpp
+#endif
+
+#ifndef ESRI_PROJECTION_MAPPINGS_HH_INCLUDED
+#define ESRI_PROJECTION_MAPPINGS_HH_INCLUDED
+
+#include "coordinateoperation_internal.hpp"
+
+//! @cond Doxygen_Suppress
+
+// ---------------------------------------------------------------------------
+
+// anonymous namespace
+namespace {
+
+using namespace ::NS_PROJ;
+using namespace ::NS_PROJ::operation;
+
+static const ESRIParamMapping paramsESRI_Plate_Carree[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Equidistant_Cylindrical[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Miller_Cylindrical[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Mercator[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Gauss_Kruger[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Transverse_Mercator[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Albers[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_EASTING_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_EASTING_FALSE_ORIGIN, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_NORTHING_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_NORTHING_FALSE_ORIGIN, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_FALSE_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {"Standard_Parallel_2", EPSG_NAME_PARAMETER_LATITUDE_2ND_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_2ND_STD_PARALLEL, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_FALSE_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Sinusoidal[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Mollweide[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Eckert_I[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Eckert_II[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Eckert_III[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Eckert_IV[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Eckert_V[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Eckert_VI[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Gall_Stereographic[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Winkel_I[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Winkel_II[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Lambert_Conformal_Conic_alt1[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+static const ESRIParamMapping paramsESRI_Lambert_Conformal_Conic_alt2[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_EASTING_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_EASTING_FALSE_ORIGIN, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_NORTHING_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_NORTHING_FALSE_ORIGIN, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_FALSE_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {"Standard_Parallel_2", EPSG_NAME_PARAMETER_LATITUDE_2ND_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_2ND_STD_PARALLEL, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_FALSE_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+static const ESRIParamMapping paramsESRI_Lambert_Conformal_Conic_alt3[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_EASTING_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_EASTING_FALSE_ORIGIN, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_NORTHING_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_NORTHING_FALSE_ORIGIN, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_FALSE_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {"Standard_Parallel_2", EPSG_NAME_PARAMETER_LATITUDE_2ND_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_2ND_STD_PARALLEL, 0.0},
+ {"Scale_Factor", nullptr, 0, 1.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_FALSE_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+static const ESRIParamMapping paramsESRI_Lambert_Conformal_Conic_alt4[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_EASTING_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_EASTING_FALSE_ORIGIN, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_NORTHING_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_NORTHING_FALSE_ORIGIN, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_FALSE_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {"Standard_Parallel_2", EPSG_NAME_PARAMETER_LATITUDE_2ND_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_2ND_STD_PARALLEL, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_ELLIPSOID_SCALE_FACTOR,
+ EPSG_CODE_PARAMETER_ELLIPSOID_SCALE_FACTOR, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_FALSE_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_FALSE_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Polyconic[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Quartic_Authalic[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Loximuthal[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Central_Parallel", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Bonne[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping
+ paramsESRI_Hotine_Oblique_Mercator_Two_Point_Natural_Origin[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_EASTING_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_EASTING_PROJECTION_CENTRE, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_NORTHING_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_NORTHING_PROJECTION_CENTRE, 0.0},
+ {"Latitude_Of_1st_Point", "Latitude of 1st point", 0, 0.0},
+ {"Latitude_Of_2nd_Point", "Latitude of 2nd point", 0, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_INITIAL_LINE, 0.0},
+ {"Longitude_Of_1st_Point", "Longitude of 1st point", 0, 0.0},
+ {"Longitude_Of_2nd_Point", "Longitude of 2nd point", 0, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Stereographic[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Equidistant_Conic[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {"Standard_Parallel_2", EPSG_NAME_PARAMETER_LATITUDE_2ND_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_2ND_STD_PARALLEL, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Cassini[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Scale_Factor", nullptr, 0, 1.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Van_der_Grinten_I[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Robinson[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Two_Point_Equidistant[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Latitude_Of_1st_Point", "Latitude of 1st point", 0, 0.0},
+ {"Latitude_Of_2nd_Point", "Latitude of 2nd point", 0, 0.0},
+ {"Longitude_Of_1st_Point", "Longitude of 1st point", 0, 0.0},
+ {"Longitude_Of_2nd_Point", "Longitude of 2nd point", 0, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Azimuthal_Equidistant[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Lambert_Azimuthal_Equal_Area[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Cylindrical_Equal_Area[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping
+ paramsESRI_Hotine_Oblique_Mercator_Two_Point_Center[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_EASTING_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_EASTING_PROJECTION_CENTRE, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_NORTHING_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_NORTHING_PROJECTION_CENTRE, 0.0},
+ {"Latitude_Of_1st_Point", "Latitude of 1st point", 0, 0.0},
+ {"Latitude_Of_2nd_Point", "Latitude of 2nd point", 0, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_INITIAL_LINE, 0.0},
+ {"Longitude_Of_1st_Point", "Longitude of 1st point", 0, 0.0},
+ {"Longitude_Of_2nd_Point", "Longitude of 2nd point", 0, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping
+ paramsESRI_Hotine_Oblique_Mercator_Azimuth_Natural_Origin[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_INITIAL_LINE, 0.0},
+ {"Azimuth", EPSG_NAME_PARAMETER_AZIMUTH_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_AZIMUTH_INITIAL_LINE, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping
+ paramsESRI_Hotine_Oblique_Mercator_Azimuth_Center[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_EASTING_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_EASTING_PROJECTION_CENTRE, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_NORTHING_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_NORTHING_PROJECTION_CENTRE, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_INITIAL_LINE, 0.0},
+ {"Azimuth", EPSG_NAME_PARAMETER_AZIMUTH_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_AZIMUTH_INITIAL_LINE, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Double_Stereographic[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Krovak_alt1[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Pseudo_Standard_Parallel_1",
+ EPSG_NAME_PARAMETER_LATITUDE_PSEUDO_STANDARD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_PSEUDO_STANDARD_PARALLEL, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL, 0.0},
+ {"Azimuth", EPSG_NAME_PARAMETER_COLATITUDE_CONE_AXIS,
+ EPSG_CODE_PARAMETER_COLATITUDE_CONE_AXIS, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_OF_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_ORIGIN, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, 0.0},
+ {"X_Scale", nullptr, 0, 1.0},
+ {"Y_Scale", nullptr, 0, 1.0},
+ {"XY_Plane_Rotation", nullptr, 0, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+static const ESRIParamMapping paramsESRI_Krovak_alt2[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Pseudo_Standard_Parallel_1",
+ EPSG_NAME_PARAMETER_LATITUDE_PSEUDO_STANDARD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_PSEUDO_STANDARD_PARALLEL, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL, 0.0},
+ {"Azimuth", EPSG_NAME_PARAMETER_COLATITUDE_CONE_AXIS,
+ EPSG_CODE_PARAMETER_COLATITUDE_CONE_AXIS, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_OF_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_ORIGIN, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, 0.0},
+ {"X_Scale", nullptr, 0, -1.0},
+ {"Y_Scale", nullptr, 0, 1.0},
+ {"XY_Plane_Rotation", nullptr, 0, 90.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_New_Zealand_Map_Grid[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Longitude_Of_Origin", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Orthographic[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Winkel_Tripel[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Aitoff[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Craster_Parabolic[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Gnomonic[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Stereographic_North_Pole[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_STD_PARALLEL, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Stereographic_South_Pole[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_STD_PARALLEL, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping
+ paramsESRI_Rectified_Skew_Orthomorphic_Natural_Origin[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_INITIAL_LINE, 0.0},
+ {"Azimuth", EPSG_NAME_PARAMETER_AZIMUTH_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_AZIMUTH_INITIAL_LINE, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, 0.0},
+ {"XY_Plane_Rotation", EPSG_NAME_PARAMETER_ANGLE_RECTIFIED_TO_SKEW_GRID,
+ EPSG_CODE_PARAMETER_ANGLE_RECTIFIED_TO_SKEW_GRID, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Rectified_Skew_Orthomorphic_Center[] =
+ {{"False_Easting", EPSG_NAME_PARAMETER_EASTING_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_EASTING_PROJECTION_CENTRE, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_NORTHING_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_NORTHING_PROJECTION_CENTRE, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_INITIAL_LINE, 0.0},
+ {"Azimuth", EPSG_NAME_PARAMETER_AZIMUTH_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_AZIMUTH_INITIAL_LINE, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, 0.0},
+ {"XY_Plane_Rotation", EPSG_NAME_PARAMETER_ANGLE_RECTIFIED_TO_SKEW_GRID,
+ EPSG_CODE_PARAMETER_ANGLE_RECTIFIED_TO_SKEW_GRID, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Goode_Homolosine[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Equidistant_Cylindrical_Ellipsoidal[] =
+ {{"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
+ EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Laborde_Oblique_Mercator[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_INITIAL_LINE, 0.0},
+ {"Azimuth", EPSG_NAME_PARAMETER_AZIMUTH_INITIAL_LINE,
+ EPSG_CODE_PARAMETER_AZIMUTH_INITIAL_LINE, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
+ EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Gnomonic_Ellipsoidal[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Center", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Wagner_IV[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Latitude_Of_Origin", nullptr, 0, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Wagner_V[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Wagner_VII[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Geostationary_Satellite[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Longitude_Of_Center", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Height", "Satellite Height", 0, 0.0},
+ {"Option", nullptr, 0, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIParamMapping paramsESRI_Mercator_Auxiliary_Sphere[] = {
+ {"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
+ EPSG_CODE_PARAMETER_FALSE_EASTING, 0.0},
+ {"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
+ EPSG_CODE_PARAMETER_FALSE_NORTHING, 0.0},
+ {"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Standard_Parallel_1", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, 0.0},
+ {"Auxiliary_Sphere_Type", nullptr, 0, 0.0},
+ {nullptr, nullptr, 0, 0.0}};
+
+static const ESRIMethodMapping esriMappings[] = {
+ {"Plate_Carree", EPSG_NAME_METHOD_EQUIDISTANT_CYLINDRICAL,
+ EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL, paramsESRI_Plate_Carree},
+ {"Plate_Carree", EPSG_NAME_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL,
+ EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL,
+ paramsESRI_Plate_Carree},
+ {"Equidistant_Cylindrical", EPSG_NAME_METHOD_EQUIDISTANT_CYLINDRICAL,
+ EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL,
+ paramsESRI_Equidistant_Cylindrical},
+ {"Miller_Cylindrical", PROJ_WKT2_NAME_METHOD_MILLER_CYLINDRICAL, 0,
+ paramsESRI_Miller_Cylindrical},
+ {"Mercator", EPSG_NAME_METHOD_MERCATOR_VARIANT_B,
+ EPSG_CODE_METHOD_MERCATOR_VARIANT_B, paramsESRI_Mercator},
+ {"Gauss_Kruger", EPSG_NAME_METHOD_TRANSVERSE_MERCATOR,
+ EPSG_CODE_METHOD_TRANSVERSE_MERCATOR, paramsESRI_Gauss_Kruger},
+ {"Transverse_Mercator", EPSG_NAME_METHOD_TRANSVERSE_MERCATOR,
+ EPSG_CODE_METHOD_TRANSVERSE_MERCATOR, paramsESRI_Transverse_Mercator},
+ {"Albers", EPSG_NAME_METHOD_ALBERS_EQUAL_AREA,
+ EPSG_CODE_METHOD_ALBERS_EQUAL_AREA, paramsESRI_Albers},
+ {"Sinusoidal", PROJ_WKT2_NAME_METHOD_SINUSOIDAL, 0, paramsESRI_Sinusoidal},
+ {"Mollweide", PROJ_WKT2_NAME_METHOD_MOLLWEIDE, 0, paramsESRI_Mollweide},
+ {"Eckert_I", PROJ_WKT2_NAME_METHOD_ECKERT_I, 0, paramsESRI_Eckert_I},
+ {"Eckert_II", PROJ_WKT2_NAME_METHOD_ECKERT_II, 0, paramsESRI_Eckert_II},
+ {"Eckert_III", PROJ_WKT2_NAME_METHOD_ECKERT_III, 0, paramsESRI_Eckert_III},
+ {"Eckert_IV", PROJ_WKT2_NAME_METHOD_ECKERT_IV, 0, paramsESRI_Eckert_IV},
+ {"Eckert_V", PROJ_WKT2_NAME_METHOD_ECKERT_V, 0, paramsESRI_Eckert_V},
+ {"Eckert_VI", PROJ_WKT2_NAME_METHOD_ECKERT_VI, 0, paramsESRI_Eckert_VI},
+ {"Gall_Stereographic", PROJ_WKT2_NAME_METHOD_GALL_STEREOGRAPHIC, 0,
+ paramsESRI_Gall_Stereographic},
+ {"Winkel_I", "Winkel I", 0, paramsESRI_Winkel_I},
+ {"Winkel_II", "Winkel II", 0, paramsESRI_Winkel_II},
+ {"Lambert_Conformal_Conic", EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_1SP,
+ EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP,
+ paramsESRI_Lambert_Conformal_Conic_alt1},
+ {"Lambert_Conformal_Conic", EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
+ EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
+ paramsESRI_Lambert_Conformal_Conic_alt2},
+ {"Lambert_Conformal_Conic", EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
+ EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
+ paramsESRI_Lambert_Conformal_Conic_alt3},
+ {"Lambert_Conformal_Conic",
+ EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN,
+ EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN,
+ paramsESRI_Lambert_Conformal_Conic_alt4},
+ {"Polyconic", EPSG_NAME_METHOD_AMERICAN_POLYCONIC,
+ EPSG_CODE_METHOD_AMERICAN_POLYCONIC, paramsESRI_Polyconic},
+ {"Quartic_Authalic", "Quartic Authalic", 0, paramsESRI_Quartic_Authalic},
+ {"Loximuthal", "Loximuthal", 0, paramsESRI_Loximuthal},
+ {"Bonne", EPSG_NAME_METHOD_BONNE, EPSG_CODE_METHOD_BONNE, paramsESRI_Bonne},
+ {"Hotine_Oblique_Mercator_Two_Point_Natural_Origin",
+ PROJ_WKT2_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN, 0,
+ paramsESRI_Hotine_Oblique_Mercator_Two_Point_Natural_Origin},
+ {"Stereographic", PROJ_WKT2_NAME_METHOD_STEREOGRAPHIC, 0,
+ paramsESRI_Stereographic},
+ {"Equidistant_Conic", PROJ_WKT2_NAME_METHOD_EQUIDISTANT_CONIC, 0,
+ paramsESRI_Equidistant_Conic},
+ {"Cassini", EPSG_NAME_METHOD_CASSINI_SOLDNER,
+ EPSG_CODE_METHOD_CASSINI_SOLDNER, paramsESRI_Cassini},
+ {"Van_der_Grinten_I", PROJ_WKT2_NAME_METHOD_VAN_DER_GRINTEN, 0,
+ paramsESRI_Van_der_Grinten_I},
+ {"Robinson", PROJ_WKT2_NAME_METHOD_ROBINSON, 0, paramsESRI_Robinson},
+ {"Two_Point_Equidistant", PROJ_WKT2_NAME_METHOD_TWO_POINT_EQUIDISTANT, 0,
+ paramsESRI_Two_Point_Equidistant},
+ {"Azimuthal_Equidistant", EPSG_NAME_METHOD_MODIFIED_AZIMUTHAL_EQUIDISTANT,
+ EPSG_CODE_METHOD_MODIFIED_AZIMUTHAL_EQUIDISTANT,
+ paramsESRI_Azimuthal_Equidistant},
+ {"Lambert_Azimuthal_Equal_Area",
+ EPSG_NAME_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA,
+ EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA,
+ paramsESRI_Lambert_Azimuthal_Equal_Area},
+ {"Cylindrical_Equal_Area",
+ EPSG_NAME_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL,
+ EPSG_CODE_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL,
+ paramsESRI_Cylindrical_Equal_Area},
+ {"Hotine_Oblique_Mercator_Two_Point_Center",
+ PROJ_WKT2_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN, 0,
+ paramsESRI_Hotine_Oblique_Mercator_Two_Point_Center},
+ {"Hotine_Oblique_Mercator_Azimuth_Natural_Origin",
+ EPSG_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A,
+ EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A,
+ paramsESRI_Hotine_Oblique_Mercator_Azimuth_Natural_Origin},
+ {"Hotine_Oblique_Mercator_Azimuth_Center",
+ EPSG_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_B,
+ EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_B,
+ paramsESRI_Hotine_Oblique_Mercator_Azimuth_Center},
+ {"Double_Stereographic", EPSG_NAME_METHOD_OBLIQUE_STEREOGRAPHIC,
+ EPSG_CODE_METHOD_OBLIQUE_STEREOGRAPHIC, paramsESRI_Double_Stereographic},
+ {"Krovak", EPSG_NAME_METHOD_KROVAK, EPSG_CODE_METHOD_KROVAK,
+ paramsESRI_Krovak_alt1},
+ {"Krovak", EPSG_NAME_METHOD_KROVAK_NORTH_ORIENTED,
+ EPSG_CODE_METHOD_KROVAK_NORTH_ORIENTED, paramsESRI_Krovak_alt2},
+ {"New_Zealand_Map_Grid", EPSG_NAME_METHOD_NZMG, EPSG_CODE_METHOD_NZMG,
+ paramsESRI_New_Zealand_Map_Grid},
+ {"Orthographic", EPSG_NAME_METHOD_ORTHOGRAPHIC,
+ EPSG_CODE_METHOD_ORTHOGRAPHIC, paramsESRI_Orthographic},
+ {"Winkel_Tripel", "Winkel Tripel", 0, paramsESRI_Winkel_Tripel},
+ {"Aitoff", "Aitoff", 0, paramsESRI_Aitoff},
+ {"Craster_Parabolic", "Craster Parabolic", 0, paramsESRI_Craster_Parabolic},
+ {"Gnomonic", PROJ_WKT2_NAME_METHOD_GNOMONIC, 0, paramsESRI_Gnomonic},
+ {"Stereographic_North_Pole", EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B,
+ EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B,
+ paramsESRI_Stereographic_North_Pole},
+ {"Stereographic_South_Pole", EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B,
+ EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B,
+ paramsESRI_Stereographic_South_Pole},
+ {"Rectified_Skew_Orthomorphic_Natural_Origin",
+ EPSG_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A,
+ EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A,
+ paramsESRI_Rectified_Skew_Orthomorphic_Natural_Origin},
+ {"Rectified_Skew_Orthomorphic_Center",
+ EPSG_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_B,
+ EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_B,
+ paramsESRI_Rectified_Skew_Orthomorphic_Center},
+ {"Goode_Homolosine", "Goode Homolosine", 0, paramsESRI_Goode_Homolosine},
+ {"Equidistant_Cylindrical_Ellipsoidal",
+ EPSG_NAME_METHOD_EQUIDISTANT_CYLINDRICAL,
+ EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL,
+ paramsESRI_Equidistant_Cylindrical_Ellipsoidal},
+ {"Laborde_Oblique_Mercator", EPSG_NAME_METHOD_LABORDE_OBLIQUE_MERCATOR,
+ EPSG_CODE_METHOD_LABORDE_OBLIQUE_MERCATOR,
+ paramsESRI_Laborde_Oblique_Mercator},
+ {"Gnomonic_Ellipsoidal", PROJ_WKT2_NAME_METHOD_GNOMONIC, 0,
+ paramsESRI_Gnomonic_Ellipsoidal},
+ {"Wagner_IV", PROJ_WKT2_NAME_METHOD_WAGNER_IV, 0, paramsESRI_Wagner_IV},
+ {"Wagner_V", PROJ_WKT2_NAME_METHOD_WAGNER_V, 0, paramsESRI_Wagner_V},
+ {"Wagner_VII", PROJ_WKT2_NAME_METHOD_WAGNER_VII, 0, paramsESRI_Wagner_VII},
+ {"Geostationary_Satellite",
+ PROJ_WKT2_NAME_METHOD_GEOSTATIONARY_SATELLITE_SWEEP_Y, 0,
+ paramsESRI_Geostationary_Satellite},
+ {"Mercator_Auxiliary_Sphere",
+ EPSG_NAME_METHOD_POPULAR_VISUALISATION_PSEUDO_MERCATOR,
+ EPSG_CODE_METHOD_POPULAR_VISUALISATION_PSEUDO_MERCATOR,
+ paramsESRI_Mercator_Auxiliary_Sphere},
+};
+
+// ---------------------------------------------------------------------------
+
+// end of anonymous namespace
+}
+
+//! @endcond
+
+#endif // ESRI_PROJECTION_MAPPINGS_HH_INCLUDED
diff --git a/include/proj/internal/internal.hpp b/include/proj/internal/internal.hpp
new file mode 100644
index 00000000..cbf6e259
--- /dev/null
+++ b/include/proj/internal/internal.hpp
@@ -0,0 +1,190 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef FROM_PROJ_CPP
+#error This file should only be included from a PROJ cpp file
+#endif
+
+#ifndef INTERNAL_HH_INCLUDED
+#define INTERNAL_HH_INCLUDED
+
+#if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
+#error Must have C++11 or newer.
+#endif
+
+#include <cassert>
+#include <cstring>
+#include <memory>
+#include <string>
+#ifndef DOXYGEN_ENABLED
+#include <type_traits> // for std::is_base_of
+#endif
+#include <vector>
+
+#include "proj/util.hpp"
+
+//! @cond Doxygen_Suppress
+
+#if ((defined(__clang__) && \
+ (__clang_major__ > 3 || \
+ (__clang_major__ == 3 && __clang_minor__ >= 7))) || \
+ __GNUC__ >= 7)
+/** Macro for fallthrough in a switch case construct */
+#define PROJ_FALLTHROUGH [[clang::fallthrough]];
+#else
+/** Macro for fallthrough in a switch case construct */
+#define PROJ_FALLTHROUGH
+#endif
+
+#if defined(__clang__) || defined(_MSC_VER)
+#define COMPILER_WARNS_ABOUT_ABSTRACT_VBASE_INIT
+#endif
+
+#if !(defined(__clang__) && __clang_major__ < 5) && !defined(__INTEL_COMPILER)
+#define SUPPORT_DELETED_FUNCTION
+#endif
+
+NS_PROJ_START
+
+namespace operation {
+class OperationParameterValue;
+} // namespace operation
+
+namespace internal {
+
+/** Use cpl::down_cast<Derived*>(pointer_to_base) as equivalent of
+ * static_cast<Derived*>(pointer_to_base) with safe checking in debug
+ * mode.
+ *
+ * Only works if no virtual inheritance is involved.
+ *
+ * @param f pointer to a base class
+ * @return pointer to a derived class
+ */
+template <typename To, typename From> inline To down_cast(From *f) {
+ static_assert(
+ (std::is_base_of<From, typename std::remove_pointer<To>::type>::value),
+ "target type not derived from source type");
+ assert(f == nullptr || dynamic_cast<To>(f) != nullptr);
+ return static_cast<To>(f);
+}
+
+/* Borrowed from C++14 */
+template <typename T, typename... Args>
+std::unique_ptr<T> make_unique(Args &&... args) {
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+PROJ_FOR_TEST std::string replaceAll(const std::string &str,
+ const std::string &before,
+ const std::string &after);
+
+size_t ci_find(const std::string &osStr, const char *needle) noexcept;
+
+size_t ci_find(const std::string &osStr, const std::string &needle,
+ size_t startPos = 0) noexcept;
+
+inline bool starts_with(const std::string &str,
+ const std::string &prefix) noexcept {
+ if (str.size() < prefix.size()) {
+ return false;
+ }
+ return std::memcmp(str.c_str(), prefix.c_str(), prefix.size()) == 0;
+}
+
+inline bool starts_with(const std::string &str, const char *prefix) noexcept {
+ const size_t prefixSize = std::strlen(prefix);
+ if (str.size() < prefixSize) {
+ return false;
+ }
+ return std::memcmp(str.c_str(), prefix, prefixSize) == 0;
+}
+
+bool ci_starts_with(const char *str, const char *prefix) noexcept;
+
+bool ci_starts_with(const std::string &str, const std::string &prefix) noexcept;
+
+bool ends_with(const std::string &str, const std::string &suffix) noexcept;
+
+PROJ_FOR_TEST std::string tolower(const std::string &osStr);
+
+std::string toupper(const std::string &osStr);
+
+PROJ_FOR_TEST std::vector<std::string> split(const std::string &osStr,
+ char separator);
+
+bool ci_equal(const char *a, const char *b) noexcept;
+
+#ifdef SUPPORT_DELETED_FUNCTION
+bool ci_equal(const char *a, const std::string &b) = delete;
+#endif
+
+PROJ_FOR_TEST bool ci_equal(const std::string &a, const char *b) noexcept;
+
+PROJ_FOR_TEST bool ci_equal(const std::string &a,
+ const std::string &b) noexcept;
+
+std::string stripQuotes(const std::string &osStr);
+
+std::string toString(int val);
+
+PROJ_FOR_TEST std::string toString(double val, int precision = 15);
+
+PROJ_FOR_TEST double
+c_locale_stod(const std::string &s); // throw(std::invalid_argument)
+
+#ifdef SUPPORT_DELETED_FUNCTION
+std::string concat(const std::string &, const std::string &) = delete;
+std::string concat(const char *, const char *) = delete;
+#endif
+std::string concat(const char *a, const std::string &b);
+#ifdef SUPPORT_DELETED_FUNCTION
+std::string concat(const std::string &, const char *) = delete;
+std::string concat(const char *, const char *, const char *) = delete;
+std::string concat(const char *, const char *, const std::string &) = delete;
+#endif
+std::string concat(const char *a, const std::string &b, const char *c);
+#ifdef SUPPORT_DELETED_FUNCTION
+std::string concat(const char *, const std::string &,
+ const std::string &) = delete;
+std::string concat(const std::string &, const char *, const char *) = delete;
+std::string concat(const std::string &, const char *,
+ const std::string &) = delete;
+std::string concat(const std::string &, const std::string &,
+ const char *) = delete;
+std::string concat(const std::string &, const std::string &,
+ const std::string &) = delete;
+#endif
+
+} // namespace internal
+
+NS_PROJ_END
+
+//! @endcond
+
+#endif // INTERNAL_HH_INCLUDED
diff --git a/include/proj/internal/io_internal.hpp b/include/proj/internal/io_internal.hpp
new file mode 100644
index 00000000..8a32c6eb
--- /dev/null
+++ b/include/proj/internal/io_internal.hpp
@@ -0,0 +1,163 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef FROM_PROJ_CPP
+#error This file should only be included from a PROJ cpp file
+#endif
+
+#ifndef IO_INTERNAL_HH_INCLUDED
+#define IO_INTERNAL_HH_INCLUDED
+
+#include <string>
+#include <vector>
+
+#include "proj/util.hpp"
+
+//! @cond Doxygen_Suppress
+
+NS_PROJ_START
+
+namespace io {
+
+// ---------------------------------------------------------------------------
+
+class WKTConstants {
+ public:
+ // WKT1
+ static const std::string GEOCCS;
+ static const std::string GEOGCS;
+ static const std::string DATUM; // WKT2 preferred too
+ static const std::string UNIT;
+ static const std::string SPHEROID;
+ static const std::string AXIS; // WKT2 too
+ static const std::string PRIMEM; // WKT2 too
+ static const std::string AUTHORITY;
+ static const std::string PROJCS;
+ static const std::string PROJECTION;
+ static const std::string PARAMETER; // WKT2 too
+ static const std::string VERT_CS;
+ static const std::string VERT_DATUM;
+ static const std::string COMPD_CS;
+ static const std::string TOWGS84; // WKT1 only
+ static const std::string EXTENSION; // WKT1 only - GDAL specific
+ static const std::string LOCAL_CS; // WKT1 only
+ static const std::string LOCAL_DATUM; // WKT1 only
+
+ // WKT2 preferred
+ static const std::string GEODCRS;
+ static const std::string LENGTHUNIT;
+ static const std::string ANGLEUNIT;
+ static const std::string SCALEUNIT;
+ static const std::string TIMEUNIT;
+ static const std::string ELLIPSOID;
+ static const std::string CS;
+ static const std::string ID;
+ static const std::string PROJCRS;
+ static const std::string BASEGEODCRS;
+ static const std::string MERIDIAN;
+ static const std::string ORDER;
+ static const std::string ANCHOR;
+ static const std::string CONVERSION;
+ static const std::string METHOD;
+ static const std::string REMARK;
+ static const std::string GEOGCRS; // WKT2-2018
+ static const std::string BASEGEOGCRS; // WKT2-2018
+ static const std::string SCOPE;
+ static const std::string AREA;
+ static const std::string BBOX;
+ static const std::string CITATION;
+ static const std::string URI;
+ static const std::string VERTCRS;
+ static const std::string VDATUM;
+ static const std::string COMPOUNDCRS;
+ static const std::string PARAMETERFILE;
+ static const std::string COORDINATEOPERATION;
+ static const std::string SOURCECRS;
+ static const std::string TARGETCRS;
+ static const std::string INTERPOLATIONCRS;
+ static const std::string OPERATIONACCURACY;
+ static const std::string CONCATENATEDOPERATION; // WKT2-2018
+ static const std::string STEP; // WKT2-2018
+ static const std::string BOUNDCRS;
+ static const std::string ABRIDGEDTRANSFORMATION;
+ static const std::string DERIVINGCONVERSION;
+ static const std::string TDATUM;
+ static const std::string CALENDAR; // WKT2-2018
+ static const std::string TIMEORIGIN;
+ static const std::string TIMECRS;
+ static const std::string VERTICALEXTENT;
+ static const std::string TIMEEXTENT;
+ static const std::string USAGE; // WKT2-2018
+ static const std::string DYNAMIC; // WKT2-2018
+ static const std::string FRAMEEPOCH; // WKT2-2018
+ static const std::string MODEL; // WKT2-2018
+ static const std::string VELOCITYGRID; // WKT2-2018
+ static const std::string ENSEMBLE; // WKT2-2018
+ static const std::string MEMBER; // WKT2-2018
+ static const std::string ENSEMBLEACCURACY; // WKT2-2018
+ static const std::string DERIVEDPROJCRS; // WKT2-2018
+ static const std::string BASEPROJCRS; // WKT2-2018
+ static const std::string EDATUM;
+ static const std::string ENGCRS;
+ static const std::string PDATUM;
+ static const std::string PARAMETRICCRS;
+ static const std::string PARAMETRICUNIT;
+ static const std::string BASEVERTCRS;
+ static const std::string BASEENGCRS;
+ static const std::string BASEPARAMCRS;
+ static const std::string BASETIMECRS;
+
+ // WKT2 alternate (longer or shorter)
+ static const std::string GEODETICCRS;
+ static const std::string GEODETICDATUM;
+ static const std::string PROJECTEDCRS;
+ static const std::string PRIMEMERIDIAN;
+ static const std::string GEOGRAPHICCRS; // WKT2-2018
+ static const std::string TRF; // WKT2-2018
+ static const std::string VERTICALCRS;
+ static const std::string VERTICALDATUM;
+ static const std::string VRF; // WKT2-2018
+ static const std::string TIMEDATUM;
+ static const std::string ENGINEERINGDATUM;
+ static const std::string ENGINEERINGCRS;
+ static const std::string PARAMETRICDATUM;
+
+ static const std::vector<std::string> &constants() { return constants_; }
+
+ private:
+ static std::vector<std::string> constants_;
+ static const char *createAndAddToConstantList(const char *text);
+};
+
+} // namespace io
+
+NS_PROJ_END
+
+//! @endcond
+
+#endif // IO_INTERNAL_HH_INCLUDED
diff --git a/include/proj/internal/lru_cache.hpp b/include/proj/internal/lru_cache.hpp
new file mode 100644
index 00000000..2f2c8bd9
--- /dev/null
+++ b/include/proj/internal/lru_cache.hpp
@@ -0,0 +1,223 @@
+/*
+ * LRUCache11 - a templated C++11 based LRU cache class that allows
+ * specification of
+ * key, value and optionally the map container type (defaults to
+ * std::unordered_map)
+ * By using the std::map and a linked list of keys it allows O(1) insert, delete
+ * and
+ * refresh operations.
+ *
+ * This is a header-only library and all you need is the LRUCache11.hpp file
+ *
+ * Github: https://github.com/mohaps/lrucache11
+ *
+ * This is a follow-up to the LRUCache project -
+ * https://github.com/mohaps/lrucache
+ *
+ * Copyright (c) 2012-22 SAURAV MOHAPATRA <mohaps@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*! @cond Doxygen_Suppress */
+
+#pragma once
+#include <algorithm>
+#include <cstdint>
+#include <list>
+#include <mutex>
+#include <stdexcept>
+#include <thread>
+#include <unordered_map>
+
+NS_PROJ_START
+namespace lru11 {
+/*
+ * a noop lockable concept that can be used in place of std::mutex
+ */
+class NullLock {
+ public:
+ // cppcheck-suppress functionStatic
+ void lock() {}
+ // cppcheck-suppress functionStatic
+ void unlock() {}
+ // cppcheck-suppress functionStatic
+ bool try_lock() { return true; }
+};
+
+/**
+ * error raised when a key not in cache is passed to get()
+ */
+class KeyNotFound : public std::invalid_argument {
+ public:
+ KeyNotFound() : std::invalid_argument("key_not_found") {}
+ ~KeyNotFound() override;
+};
+
+#ifndef LRU11_DO_NOT_DEFINE_OUT_OF_CLASS_METHODS
+KeyNotFound::~KeyNotFound() = default;
+#endif
+
+template <typename K, typename V>
+struct KeyValuePair {
+ public:
+ K key;
+ V value;
+
+ KeyValuePair(const K& k, const V& v) : key(k), value(v) {}
+};
+
+/**
+ * The LRU Cache class templated by
+ * Key - key type
+ * Value - value type
+ * MapType - an associative container like std::unordered_map
+ * LockType - a lock type derived from the Lock class (default:
+ *NullLock = no synchronization)
+ *
+ * The default NullLock based template is not thread-safe, however passing
+ *Lock=std::mutex will make it
+ * thread-safe
+ */
+template <class Key, class Value, class Lock = NullLock,
+ class Map = std::unordered_map<
+ Key, typename std::list<KeyValuePair<Key, Value>>::iterator>>
+class Cache {
+ public:
+ typedef KeyValuePair<Key, Value> node_type;
+ typedef std::list<KeyValuePair<Key, Value>> list_type;
+ typedef Map map_type;
+ typedef Lock lock_type;
+ using Guard = std::lock_guard<lock_type>;
+ /**
+ * the max size is the hard limit of keys and (maxSize + elasticity) is the
+ * soft limit
+ * the cache is allowed to grow till maxSize + elasticity and is pruned back
+ * to maxSize keys
+ * set maxSize = 0 for an unbounded cache (but in that case, you're better off
+ * using a std::unordered_map
+ * directly anyway! :)
+ */
+ explicit Cache(size_t maxSize = 64, size_t elasticity = 10)
+ : maxSize_(maxSize), elasticity_(elasticity) {}
+ virtual ~Cache() = default;
+ size_t size() const {
+ Guard g(lock_);
+ return cache_.size();
+ }
+ bool empty() const {
+ Guard g(lock_);
+ return cache_.empty();
+ }
+ void clear() {
+ Guard g(lock_);
+ cache_.clear();
+ keys_.clear();
+ }
+ void insert(const Key& k, const Value& v) {
+ Guard g(lock_);
+ const auto iter = cache_.find(k);
+ if (iter != cache_.end()) {
+ iter->second->value = v;
+ keys_.splice(keys_.begin(), keys_, iter->second);
+ return;
+ }
+
+ keys_.emplace_front(k, v);
+ cache_[k] = keys_.begin();
+ prune();
+ }
+ bool tryGet(const Key& kIn, Value& vOut) {
+ Guard g(lock_);
+ const auto iter = cache_.find(kIn);
+ if (iter == cache_.end()) {
+ return false;
+ }
+ keys_.splice(keys_.begin(), keys_, iter->second);
+ vOut = iter->second->value;
+ return true;
+ }
+ /**
+ * The const reference returned here is only
+ * guaranteed to be valid till the next insert/delete
+ */
+ const Value& get(const Key& k) {
+ Guard g(lock_);
+ const auto iter = cache_.find(k);
+ if (iter == cache_.end()) {
+ throw KeyNotFound();
+ }
+ keys_.splice(keys_.begin(), keys_, iter->second);
+ return iter->second->value;
+ }
+ /**
+ * returns a copy of the stored object (if found)
+ */
+ Value getCopy(const Key& k) {
+ return get(k);
+ }
+ bool remove(const Key& k) {
+ Guard g(lock_);
+ auto iter = cache_.find(k);
+ if (iter == cache_.end()) {
+ return false;
+ }
+ keys_.erase(iter->second);
+ cache_.erase(iter);
+ return true;
+ }
+ bool contains(const Key& k) {
+ Guard g(lock_);
+ return cache_.find(k) != cache_.end();
+ }
+
+ size_t getMaxSize() const { return maxSize_; }
+ size_t getElasticity() const { return elasticity_; }
+ size_t getMaxAllowedSize() const { return maxSize_ + elasticity_; }
+ template <typename F>
+ void cwalk(F& f) const {
+ Guard g(lock_);
+ std::for_each(keys_.begin(), keys_.end(), f);
+ }
+
+ protected:
+ size_t prune() {
+ size_t maxAllowed = maxSize_ + elasticity_;
+ if (maxSize_ == 0 || cache_.size() <= maxAllowed) { /* ERO: changed < to <= */
+ return 0;
+ }
+ size_t count = 0;
+ while (cache_.size() > maxSize_) {
+ cache_.erase(keys_.back().key);
+ keys_.pop_back();
+ ++count;
+ }
+ return count;
+ }
+
+ private:
+ // Dissallow copying.
+ Cache(const Cache&) = delete;
+ Cache& operator=(const Cache&) = delete;
+
+ mutable Lock lock_{};
+ Map cache_{};
+ list_type keys_{};
+ size_t maxSize_;
+ size_t elasticity_;
+};
+
+} // namespace LRUCache11
+NS_PROJ_END
+
+/*! @endcond */
diff --git a/include/proj/io.hpp b/include/proj/io.hpp
new file mode 100644
index 00000000..689fede1
--- /dev/null
+++ b/include/proj/io.hpp
@@ -0,0 +1,970 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef IO_HH_INCLUDED
+#define IO_HH_INCLUDED
+
+#include <list>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "util.hpp"
+
+NS_PROJ_START
+
+namespace common {
+class UnitOfMeasure;
+using UnitOfMeasurePtr = std::shared_ptr<UnitOfMeasure>;
+using UnitOfMeasureNNPtr = util::nn<UnitOfMeasurePtr>;
+
+class IdentifiedObject;
+using IdentifiedObjectPtr = std::shared_ptr<IdentifiedObject>;
+using IdentifiedObjectNNPtr = util::nn<IdentifiedObjectPtr>;
+} // namespace common
+
+namespace cs {
+class CoordinateSystem;
+using CoordinateSystemPtr = std::shared_ptr<CoordinateSystem>;
+using CoordinateSystemNNPtr = util::nn<CoordinateSystemPtr>;
+} // namespace cs
+
+namespace metadata {
+class Extent;
+using ExtentPtr = std::shared_ptr<Extent>;
+using ExtentNNPtr = util::nn<ExtentPtr>;
+} // namespace metadata
+
+namespace datum {
+class Datum;
+using DatumPtr = std::shared_ptr<Datum>;
+using DatumNNPtr = util::nn<DatumPtr>;
+
+class Ellipsoid;
+using EllipsoidPtr = std::shared_ptr<Ellipsoid>;
+using EllipsoidNNPtr = util::nn<EllipsoidPtr>;
+
+class PrimeMeridian;
+using PrimeMeridianPtr = std::shared_ptr<PrimeMeridian>;
+using PrimeMeridianNNPtr = util::nn<PrimeMeridianPtr>;
+
+class GeodeticReferenceFrame;
+using GeodeticReferenceFramePtr = std::shared_ptr<GeodeticReferenceFrame>;
+using GeodeticReferenceFrameNNPtr = util::nn<GeodeticReferenceFramePtr>;
+
+class VerticalReferenceFrame;
+using VerticalReferenceFramePtr = std::shared_ptr<VerticalReferenceFrame>;
+using VerticalReferenceFrameNNPtr = util::nn<VerticalReferenceFramePtr>;
+} // namespace datum
+
+namespace crs {
+class CRS;
+using CRSPtr = std::shared_ptr<CRS>;
+using CRSNNPtr = util::nn<CRSPtr>;
+
+class GeodeticCRS;
+using GeodeticCRSPtr = std::shared_ptr<GeodeticCRS>;
+using GeodeticCRSNNPtr = util::nn<GeodeticCRSPtr>;
+
+class GeographicCRS;
+using GeographicCRSPtr = std::shared_ptr<GeographicCRS>;
+using GeographicCRSNNPtr = util::nn<GeographicCRSPtr>;
+
+class VerticalCRS;
+using VerticalCRSPtr = std::shared_ptr<VerticalCRS>;
+using VerticalCRSNNPtr = util::nn<VerticalCRSPtr>;
+
+class ProjectedCRS;
+using ProjectedCRSPtr = std::shared_ptr<ProjectedCRS>;
+using ProjectedCRSNNPtr = util::nn<ProjectedCRSPtr>;
+
+class CompoundCRS;
+using CompoundCRSPtr = std::shared_ptr<CompoundCRS>;
+using CompoundCRSNNPtr = util::nn<CompoundCRSPtr>;
+} // namespace crs
+
+namespace operation {
+class Conversion;
+using ConversionPtr = std::shared_ptr<Conversion>;
+using ConversionNNPtr = util::nn<ConversionPtr>;
+
+class CoordinateOperation;
+using CoordinateOperationPtr = std::shared_ptr<CoordinateOperation>;
+using CoordinateOperationNNPtr = util::nn<CoordinateOperationPtr>;
+} // namespace operation
+
+/** osgeo.proj.io namespace.
+ *
+ * \brief I/O classes
+ */
+namespace io {
+
+class DatabaseContext;
+/** Shared pointer of DatabaseContext. */
+using DatabaseContextPtr = std::shared_ptr<DatabaseContext>;
+/** Non-null shared pointer of DatabaseContext. */
+using DatabaseContextNNPtr = util::nn<DatabaseContextPtr>;
+
+// ---------------------------------------------------------------------------
+
+class WKTFormatter;
+/** WKTFormatter unique pointer. */
+using WKTFormatterPtr = std::unique_ptr<WKTFormatter>;
+/** Non-null WKTFormatter unique pointer. */
+using WKTFormatterNNPtr = util::nn<WKTFormatterPtr>;
+
+/** \brief Formatter to WKT strings.
+ *
+ * An instance of this class can only be used by a single
+ * thread at a time.
+ */
+class PROJ_GCC_DLL WKTFormatter {
+ public:
+ /** WKT variant. */
+ enum class PROJ_MSVC_DLL Convention {
+ /** Full WKT2 string, conforming to ISO 19162:2015(E) / OGC 12-063r5
+ * (\ref WKT2_2015) with all possible nodes and new keyword names.
+ */
+ WKT2,
+ WKT2_2015 = WKT2,
+
+ /** Same as WKT2 with the following exceptions:
+ * <ul>
+ * <li>UNIT keyword used.</li>
+ * <li>ID node only on top element.</li>
+ * <li>No ORDER element in AXIS element.</li>
+ * <li>PRIMEM node omitted if it is Greenwich.</li>
+ * <li>ELLIPSOID.UNIT node omitted if it is
+ * UnitOfMeasure::METRE.</li>
+ * <li>PARAMETER.UNIT / PRIMEM.UNIT omitted if same as AXIS.</li>
+ * <li>AXIS.UNIT omitted and replaced by a common GEODCRS.UNIT if
+ * they are all the same on all axis.</li>
+ * </ul>
+ */
+ WKT2_SIMPLIFIED,
+ WKT2_2015_SIMPLIFIED = WKT2_SIMPLIFIED,
+
+ /** Full WKT2 string, conforming to ISO 19162:2018 / OGC 18-010, with
+ * (\ref WKT2_2018) all possible nodes and new keyword names.
+ * Non-normative list of differences:
+ * <ul>
+ * <li>WKT2_2018 uses GEOGCRS / BASEGEOGCRS keywords for
+ * GeographicCRS.</li>
+ * </ul>
+ */
+ WKT2_2018,
+
+ /** WKT2_2018 with the simplification rule of WKT2_SIMPLIFIED */
+ WKT2_2018_SIMPLIFIED,
+
+ /** WKT1 as traditionally output by GDAL, deriving from OGC 01-009.
+ A notable departuPROJ_GCC_DLLre from WKT1_GDAL with respect to OGC
+ 01-009 is
+ that in WKT1_GDAL, the unit of the PRIMEM value is always degrees.
+ */
+ WKT1_GDAL,
+
+ /** WKT1 as traditionally output by ESRI software,
+ * deriving from OGC 99-049. */
+ WKT1_ESRI,
+ };
+
+ PROJ_DLL static WKTFormatterNNPtr
+ create(Convention convention = Convention::WKT2,
+ DatabaseContextPtr dbContext = nullptr);
+ PROJ_DLL static WKTFormatterNNPtr create(const WKTFormatterNNPtr &other);
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~WKTFormatter();
+ //! @endcond
+
+ PROJ_DLL WKTFormatter &setMultiLine(bool multiLine) noexcept;
+ PROJ_DLL WKTFormatter &setIndentationWidth(int width) noexcept;
+ PROJ_DLL WKTFormatter &setOutputAxis(bool outputAxis) noexcept;
+ PROJ_DLL WKTFormatter &setStrict(bool strict) noexcept;
+ PROJ_DLL bool isStrict() const noexcept;
+
+ PROJ_DLL const std::string &toString() const;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_DLL WKTFormatter &
+ setOutputId(bool outputIdIn);
+
+ PROJ_INTERNAL void enter();
+ PROJ_INTERNAL void leave();
+
+ PROJ_INTERNAL void startNode(const std::string &keyword, bool hasId);
+ PROJ_INTERNAL void endNode();
+
+ PROJ_DLL WKTFormatter &simulCurNodeHasId();
+
+ PROJ_INTERNAL void addQuotedString(const char *str);
+ PROJ_INTERNAL void addQuotedString(const std::string &str);
+ PROJ_INTERNAL void add(const std::string &str);
+ PROJ_INTERNAL void add(int number);
+ PROJ_INTERNAL void add(size_t number) = delete;
+ PROJ_INTERNAL void add(double number, int precision = 15);
+
+ PROJ_INTERNAL void pushOutputUnit(bool outputUnitIn);
+ PROJ_INTERNAL void popOutputUnit();
+ PROJ_INTERNAL bool outputUnit() const;
+
+ PROJ_INTERNAL void pushOutputId(bool outputIdIn);
+ PROJ_INTERNAL void popOutputId();
+ PROJ_INTERNAL bool outputId() const;
+
+ PROJ_INTERNAL void
+ pushAxisLinearUnit(const common::UnitOfMeasureNNPtr &unit);
+ PROJ_INTERNAL void popAxisLinearUnit();
+ PROJ_INTERNAL const common::UnitOfMeasureNNPtr &axisLinearUnit() const;
+
+ PROJ_INTERNAL void
+ pushAxisAngularUnit(const common::UnitOfMeasureNNPtr &unit);
+ PROJ_INTERNAL void popAxisAngularUnit();
+ PROJ_INTERNAL const common::UnitOfMeasureNNPtr &axisAngularUnit() const;
+
+ PROJ_INTERNAL void setAbridgedTransformation(bool abriged);
+ PROJ_INTERNAL bool abridgedTransformation() const;
+
+ PROJ_INTERNAL void setUseDerivingConversion(bool useDerivingConversionIn);
+ PROJ_INTERNAL bool useDerivingConversion() const;
+
+ PROJ_INTERNAL void setTOWGS84Parameters(const std::vector<double> &params);
+ PROJ_INTERNAL const std::vector<double> &getTOWGS84Parameters() const;
+
+ PROJ_INTERNAL void setVDatumExtension(const std::string &filename);
+ PROJ_INTERNAL const std::string &getVDatumExtension() const;
+
+ PROJ_INTERNAL void setHDatumExtension(const std::string &filename);
+ PROJ_INTERNAL const std::string &getHDatumExtension() const;
+
+ PROJ_INTERNAL static std::string morphNameToESRI(const std::string &name);
+
+#ifdef unused
+ PROJ_INTERNAL void startInversion();
+ PROJ_INTERNAL void stopInversion();
+ PROJ_INTERNAL bool isInverted() const;
+#endif
+
+ PROJ_INTERNAL bool outputAxis() const;
+ PROJ_INTERNAL bool outputAxisOrder() const;
+ PROJ_INTERNAL bool primeMeridianOmittedIfGreenwich() const;
+ PROJ_INTERNAL bool ellipsoidUnitOmittedIfMetre() const;
+ PROJ_INTERNAL bool forceUNITKeyword() const;
+ PROJ_INTERNAL bool primeMeridianOrParameterUnitOmittedIfSameAsAxis() const;
+ PROJ_INTERNAL bool primeMeridianInDegree() const;
+ PROJ_INTERNAL bool outputCSUnitOnlyOnceIfSame() const;
+
+ /** WKT version. */
+ enum class Version {
+ /** WKT1 */
+ WKT1,
+ /** WKT2 / ISO 19162 */
+ WKT2
+ };
+
+ PROJ_INTERNAL Version version() const;
+ PROJ_INTERNAL bool use2018Keywords() const;
+ PROJ_INTERNAL bool useESRIDialect() const;
+
+ PROJ_INTERNAL const DatabaseContextPtr &databaseContext() const;
+
+ //! @endcond
+
+ protected:
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL explicit WKTFormatter(Convention convention);
+ WKTFormatter(const WKTFormatter &other) = delete;
+
+ INLINED_MAKE_UNIQUE
+ //! @endcond
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class PROJStringFormatter;
+/** PROJStringFormatter unique pointer. */
+using PROJStringFormatterPtr = std::unique_ptr<PROJStringFormatter>;
+/** Non-null PROJStringFormatter unique pointer. */
+using PROJStringFormatterNNPtr = util::nn<PROJStringFormatterPtr>;
+
+/** \brief Formatter to PROJ strings.
+ *
+ * An instance of this class can only be used by a single
+ * thread at a time.
+ */
+class PROJ_GCC_DLL PROJStringFormatter {
+ public:
+ /** PROJ variant. */
+ enum class PROJ_MSVC_DLL Convention {
+ /** PROJ v5 (or later versions) string. */
+ PROJ_5,
+
+ /** PROJ v4 string as output by GDAL exportToProj4() */
+ PROJ_4
+ };
+
+ PROJ_DLL static PROJStringFormatterNNPtr
+ create(Convention conventionIn = Convention::PROJ_5,
+ DatabaseContextPtr dbContext = nullptr);
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~PROJStringFormatter();
+ //! @endcond
+
+ PROJ_DLL void setUseETMercForTMerc(bool flag);
+
+ PROJ_DLL const std::string &toString() const;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+
+ PROJ_DLL void
+ startInversion();
+ PROJ_DLL void stopInversion();
+ PROJ_INTERNAL bool isInverted() const;
+ PROJ_INTERNAL bool getUseETMercForTMerc() const;
+
+ PROJ_DLL void
+ ingestPROJString(const std::string &str); // throw ParsingException
+
+ PROJ_DLL void addStep(const char *step);
+ PROJ_DLL void addStep(const std::string &step);
+ PROJ_DLL void setCurrentStepInverted(bool inverted);
+ PROJ_DLL void addParam(const std::string &paramName);
+ PROJ_DLL void addParam(const char *paramName, double val);
+ PROJ_DLL void addParam(const std::string &paramName, double val);
+ PROJ_DLL void addParam(const char *paramName, int val);
+ PROJ_DLL void addParam(const std::string &paramName, int val);
+ PROJ_DLL void addParam(const char *paramName, const char *val);
+ PROJ_DLL void addParam(const char *paramName, const std::string &val);
+ PROJ_DLL void addParam(const std::string &paramName, const char *val);
+ PROJ_DLL void addParam(const std::string &paramName,
+ const std::string &val);
+ PROJ_DLL void addParam(const char *paramName,
+ const std::vector<double> &vals);
+
+ PROJ_INTERNAL std::set<std::string> getUsedGridNames() const;
+
+ PROJ_INTERNAL void setTOWGS84Parameters(const std::vector<double> &params);
+ PROJ_INTERNAL const std::vector<double> &getTOWGS84Parameters() const;
+
+ PROJ_INTERNAL void setVDatumExtension(const std::string &filename);
+ PROJ_INTERNAL const std::string &getVDatumExtension() const;
+
+ PROJ_INTERNAL void setHDatumExtension(const std::string &filename);
+ PROJ_INTERNAL const std::string &getHDatumExtension() const;
+
+ PROJ_INTERNAL void setOmitProjLongLatIfPossible(bool omit);
+ PROJ_INTERNAL bool omitProjLongLatIfPossible() const;
+
+ PROJ_INTERNAL void setOmitZUnitConversion(bool omit);
+ PROJ_INTERNAL bool omitZUnitConversion() const;
+
+ PROJ_INTERNAL const DatabaseContextPtr &databaseContext() const;
+
+ PROJ_INTERNAL Convention convention() const;
+
+ //! @endcond
+
+ protected:
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL explicit PROJStringFormatter(
+ Convention conventionIn, const DatabaseContextPtr &dbContext);
+ PROJStringFormatter(const PROJStringFormatter &other) = delete;
+
+ INLINED_MAKE_UNIQUE
+ //! @endcond
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Exception possibly thrown by IWKTExportable::exportToWKT() or
+ * IPROJStringExportable::exportToPROJString(). */
+class PROJ_GCC_DLL FormattingException : public util::Exception {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL explicit FormattingException(const char *message);
+ PROJ_INTERNAL explicit FormattingException(const std::string &message);
+ PROJ_DLL FormattingException(const FormattingException &other);
+ PROJ_DLL virtual ~FormattingException() override;
+
+ PROJ_INTERNAL static void Throw(const char *msg) PROJ_NO_RETURN;
+ PROJ_INTERNAL static void Throw(const std::string &msg) PROJ_NO_RETURN;
+ //! @endcond
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Exception possibly thrown by WKTNode::createFrom() or
+ * WKTParser::createFromWKT(). */
+class PROJ_GCC_DLL ParsingException : public util::Exception {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL explicit ParsingException(const char *message);
+ PROJ_INTERNAL explicit ParsingException(const std::string &message);
+ PROJ_DLL ParsingException(const ParsingException &other);
+ PROJ_DLL virtual ~ParsingException() override;
+ //! @endcond
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Interface for an object that can be exported to WKT. */
+class PROJ_GCC_DLL IWKTExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL virtual ~IWKTExportable();
+ //! @endcond
+
+ /** Builds a WKT representation. May throw a FormattingException */
+ PROJ_DLL std::string
+ exportToWKT(WKTFormatter *formatter) const; // throw(FormattingException)
+
+ PROJ_PRIVATE :
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL virtual void
+ _exportToWKT(
+ WKTFormatter *formatter) const = 0; // throw(FormattingException)
+ //! @endcond
+};
+
+// ---------------------------------------------------------------------------
+
+class IPROJStringExportable;
+/** Shared pointer of IPROJStringExportable. */
+using IPROJStringExportablePtr = std::shared_ptr<IPROJStringExportable>;
+/** Non-null shared pointer of IPROJStringExportable. */
+using IPROJStringExportableNNPtr = util::nn<IPROJStringExportablePtr>;
+
+/** \brief Interface for an object that can be exported to a PROJ string. */
+class PROJ_GCC_DLL IPROJStringExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL virtual ~IPROJStringExportable();
+ //! @endcond
+
+ /** \brief Builds a PROJ string representation.
+ *
+ * <ul>
+ * <li>For PROJStringFormatter::Convention::PROJ_5 (the default), return
+ * strings that generally express PROJ.5 pipelines.
+ * <ul>
+ * <li>For a crs::GeographicCRS, returns a string expressing the
+ * transformation from geographic coordinates expressed in radian with
+ * longitude, latitude order, and with respect to the international
+ * reference meridian, into geographic coordinates expressed in the units
+ * and axis order of the CRS, taking into account its prime meridian.</li>
+ * <li>For a geocentric crs::GeodeticCRS, returns a string expressing the
+ * transformation from geographic coordinates expressed in radian with
+ * longitude, latitude order, and with respect to the international
+ * reference meridian, into geocentric coordinates.</li>
+ * <li>For a
+ * crs::ProjectedCRS / crs::DerivedGeographicCRS / crs::DerivedProjectedCRS,
+ * returns a string expressing the transformation from the base CRS to the
+ * CRS</li>
+ * <li>For a crs::BoundCRS, throws a FormattingException.</li>
+ * <li>For operation::CoordinateTransformations, returns a PROJ
+ * pipeline.</li>
+ * </ul>
+ *
+ * <li>For PROJStringFormatter::Convention::PROJ_4, format a string
+ * compatible with the OGRSpatialReference::exportToProj4() of GDAL
+ * &lt;=2.3.
+ * <ul>
+ * <li>For a crs::GeographicCRS, returns a proj=longlat string, with
+ * ellipsoid / datum / prime meridian information, ignoring axis order
+ * and unit information.</li>
+ * <li>For a geocentric crs::GeodeticCRS, returns the transformation from
+ * geographic coordinates into geocentric coordinates.</li>
+ * <li>For a crs::ProjectedCRS, returns the projection method, ignoring
+ * axis order.</li>
+ * <li>For a crs::BoundCRS, returns the PROJ string of its source/base CRS,
+ * amended with towgs84 / nadgrids parameter when the deriving conversion
+ * can be expressed in that way.</li>
+ * </ul>
+ * </li>
+ *
+ * </ul>
+ *
+ * @param formatter PROJ string formatter.
+ * @return a PROJ string.
+ * @throw FormattingException */
+ PROJ_DLL std::string exportToPROJString(
+ PROJStringFormatter *formatter) const; // throw(FormattingException)
+
+ PROJ_PRIVATE :
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL virtual void
+ _exportToPROJString(PROJStringFormatter *formatter)
+ const = 0; // throw(FormattingException)
+ //! @endcond
+};
+
+// ---------------------------------------------------------------------------
+
+class WKTNode;
+/** Unique pointer of WKTNode. */
+using WKTNodePtr = std::unique_ptr<WKTNode>;
+/** Non-null unique pointer of WKTNode. */
+using WKTNodeNNPtr = util::nn<WKTNodePtr>;
+
+/** \brief Node in the tree-splitted WKT representation.
+ */
+class PROJ_GCC_DLL WKTNode {
+ public:
+ PROJ_DLL explicit WKTNode(const std::string &valueIn);
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~WKTNode();
+ //! @endcond
+
+ PROJ_DLL const std::string &value() const;
+ PROJ_DLL const std::vector<WKTNodeNNPtr> &children() const;
+
+ PROJ_DLL void addChild(WKTNodeNNPtr &&child);
+ PROJ_DLL const WKTNodePtr &lookForChild(const std::string &childName,
+ int occurrence = 0) const noexcept;
+ PROJ_DLL int countChildrenOfName(const std::string &childName) const
+ noexcept;
+
+ PROJ_DLL std::string toString() const;
+
+ PROJ_DLL static WKTNodeNNPtr createFrom(const std::string &wkt,
+ size_t indexStart = 0);
+
+ protected:
+ PROJ_INTERNAL static WKTNodeNNPtr
+ createFrom(const std::string &wkt, size_t indexStart, int recLevel,
+ size_t &indexEnd); // throw(ParsingException)
+
+ private:
+ friend class WKTParser;
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+PROJ_DLL util::BaseObjectNNPtr
+createFromUserInput(const std::string &text,
+ const DatabaseContextPtr &dbContext);
+
+// ---------------------------------------------------------------------------
+
+/** \brief Parse a WKT string into the appropriate suclass of util::BaseObject.
+ */
+class PROJ_GCC_DLL WKTParser {
+ public:
+ PROJ_DLL WKTParser();
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~WKTParser();
+ //! @endcond
+
+ PROJ_DLL WKTParser &
+ attachDatabaseContext(const DatabaseContextPtr &dbContext);
+
+ PROJ_DLL WKTParser &setStrict(bool strict);
+ PROJ_DLL std::vector<std::string> warningList() const;
+
+ PROJ_DLL util::BaseObjectNNPtr
+ createFromWKT(const std::string &wkt); // throw(ParsingException)
+
+ /** Guessed WKT "dialect" */
+ enum class PROJ_MSVC_DLL WKTGuessedDialect {
+ /** \ref WKT2_2018 */
+ WKT2_2018,
+ /** \ref WKT2_2015 */
+ WKT2_2015,
+ /** \ref WKT1 */
+ WKT1_GDAL,
+ /** ESRI variant of WKT1 */
+ WKT1_ESRI,
+ /** Not WKT / unrecognized */
+ NOT_WKT
+ };
+
+ // cppcheck-suppress functionStatic
+ PROJ_DLL WKTGuessedDialect guessDialect(const std::string &wkt) noexcept;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Parse a PROJ string into the appropriate suclass of util::BaseObject.
+ */
+class PROJ_GCC_DLL PROJStringParser {
+ public:
+ PROJ_DLL PROJStringParser();
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~PROJStringParser();
+ //! @endcond
+
+ PROJ_DLL PROJStringParser &
+ attachDatabaseContext(const DatabaseContextPtr &dbContext);
+
+ PROJ_DLL std::vector<std::string> warningList() const;
+
+ PROJ_DLL util::BaseObjectNNPtr createFromPROJString(
+ const std::string &projString); // throw(ParsingException)
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Database context.
+ *
+ * A database context should be used only by one thread at a time.
+ */
+class PROJ_GCC_DLL DatabaseContext {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~DatabaseContext();
+ //! @endcond
+
+ PROJ_DLL static DatabaseContextNNPtr create();
+
+ PROJ_DLL static DatabaseContextNNPtr
+ create(const std::string &databasePath);
+
+ PROJ_DLL static DatabaseContextNNPtr
+ create(const std::string &databasePath,
+ const std::vector<std::string> &auxiliaryDatabasePaths);
+
+ PROJ_DLL const std::string &getPath() const;
+
+ PROJ_DLL std::set<std::string> getAuthorities() const;
+
+ PROJ_DLL std::vector<std::string> getDatabaseStructure() const;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_DLL void *
+ getSqliteHandle() const;
+
+ PROJ_DLL static DatabaseContextNNPtr create(void *sqlite_handle);
+
+ PROJ_INTERNAL void attachPJContext(void *pjCtxt);
+
+ PROJ_INTERNAL bool lookForGridAlternative(const std::string &officialName,
+ std::string &projFilename,
+ std::string &projFormat,
+ bool &inverse) const;
+
+ PROJ_DLL bool lookForGridInfo(const std::string &projFilename,
+ std::string &fullFilename,
+ std::string &packageName, std::string &url,
+ bool &directDownload, bool &openLicense,
+ bool &gridAvailable) const;
+
+ PROJ_INTERNAL std::string
+ getAliasFromOfficialName(const std::string &officialName,
+ const std::string &tableName,
+ const std::string &source) const;
+
+ PROJ_INTERNAL bool isKnownName(const std::string &name,
+ const std::string &tableName) const;
+
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL DatabaseContext();
+ INLINED_MAKE_SHARED
+ PROJ_FRIEND(AuthorityFactory);
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ DatabaseContext(const DatabaseContext &) = delete;
+ DatabaseContext &operator=(const DatabaseContext &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class AuthorityFactory;
+/** Shared pointer of AuthorityFactory. */
+using AuthorityFactoryPtr = std::shared_ptr<AuthorityFactory>;
+/** Non-null shared pointer of AuthorityFactory. */
+using AuthorityFactoryNNPtr = util::nn<AuthorityFactoryPtr>;
+
+/** \brief Builds object from an authority database.
+ *
+ * A AuthorityFactory should be used only by one thread at a time.
+ *
+ * \remark Implements [AuthorityFactory]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/AuthorityFactory.html)
+ * from \ref GeoAPI
+ */
+class PROJ_GCC_DLL AuthorityFactory {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~AuthorityFactory();
+ //! @endcond
+
+ PROJ_DLL util::BaseObjectNNPtr createObject(const std::string &code) const;
+
+ PROJ_DLL common::UnitOfMeasureNNPtr
+ createUnitOfMeasure(const std::string &code) const;
+
+ PROJ_DLL metadata::ExtentNNPtr createExtent(const std::string &code) const;
+
+ PROJ_DLL datum::PrimeMeridianNNPtr
+ createPrimeMeridian(const std::string &code) const;
+
+ PROJ_DLL std::string identifyBodyFromSemiMajorAxis(double a,
+ double tolerance) const;
+
+ PROJ_DLL datum::EllipsoidNNPtr
+ createEllipsoid(const std::string &code) const;
+
+ PROJ_DLL datum::DatumNNPtr createDatum(const std::string &code) const;
+
+ PROJ_DLL datum::GeodeticReferenceFrameNNPtr
+ createGeodeticDatum(const std::string &code) const;
+
+ PROJ_DLL datum::VerticalReferenceFrameNNPtr
+ createVerticalDatum(const std::string &code) const;
+
+ PROJ_DLL cs::CoordinateSystemNNPtr
+ createCoordinateSystem(const std::string &code) const;
+
+ PROJ_DLL crs::GeodeticCRSNNPtr
+ createGeodeticCRS(const std::string &code) const;
+
+ PROJ_DLL crs::GeographicCRSNNPtr
+ createGeographicCRS(const std::string &code) const;
+
+ PROJ_DLL crs::VerticalCRSNNPtr
+ createVerticalCRS(const std::string &code) const;
+
+ PROJ_DLL operation::ConversionNNPtr
+ createConversion(const std::string &code) const;
+
+ PROJ_DLL crs::ProjectedCRSNNPtr
+ createProjectedCRS(const std::string &code) const;
+
+ PROJ_DLL crs::CompoundCRSNNPtr
+ createCompoundCRS(const std::string &code) const;
+
+ PROJ_DLL crs::CRSNNPtr
+ createCoordinateReferenceSystem(const std::string &code) const;
+
+ PROJ_DLL operation::CoordinateOperationNNPtr
+ createCoordinateOperation(const std::string &code,
+ bool usePROJAlternativeGridNames) const;
+
+ PROJ_DLL std::vector<operation::CoordinateOperationNNPtr>
+ createFromCoordinateReferenceSystemCodes(
+ const std::string &sourceCRSCode,
+ const std::string &targetCRSCode) const;
+
+ PROJ_DLL const std::string &getAuthority() PROJ_CONST_DECL;
+
+ /** Object type. */
+ enum class ObjectType {
+ /** Object of type datum::PrimeMeridian */
+ PRIME_MERIDIAN,
+ /** Object of type datum::Ellipsoid */
+ ELLIPSOID,
+ /** Object of type datum::Datum (and derived classes) */
+ DATUM,
+ /** Object of type datum::GeodeticReferenceFrame (and derived
+ classes) */
+ GEODETIC_REFERENCE_FRAME,
+ /** Object of type datum::VerticalReferenceFrame (and derived
+ classes) */
+ VERTICAL_REFERENCE_FRAME,
+ /** Object of type crs::CRS (and derived classes) */
+ CRS,
+ /** Object of type crs::GeodeticCRS (and derived classes) */
+ GEODETIC_CRS,
+ /** GEODETIC_CRS of type geocentric */
+ GEOCENTRIC_CRS,
+ /** Object of type crs::GeographicCRS (and derived classes) */
+ GEOGRAPHIC_CRS,
+ /** GEOGRAPHIC_CRS of type Geographic 2D */
+ GEOGRAPHIC_2D_CRS,
+ /** GEOGRAPHIC_CRS of type Geographic 3D */
+ GEOGRAPHIC_3D_CRS,
+ /** Object of type crs::ProjectedCRS (and derived classes) */
+ PROJECTED_CRS,
+ /** Object of type crs::VerticalCRS (and derived classes) */
+ VERTICAL_CRS,
+ /** Object of type crs::CompoundCRS (and derived classes) */
+ COMPOUND_CRS,
+ /** Object of type operation::CoordinateOperation (and derived
+ classes) */
+ COORDINATE_OPERATION,
+ /** Object of type operation::Conversion (and derived classes) */
+ CONVERSION,
+ /** Object of type operation::Transformation (and derived classes)
+ */
+ TRANSFORMATION,
+ /** Object of type operation::ConcatenatedOperation (and derived
+ classes) */
+ CONCATENATED_OPERATION,
+ };
+
+ PROJ_DLL std::set<std::string>
+ getAuthorityCodes(const ObjectType &type,
+ bool allowDeprecated = true) const;
+
+ PROJ_DLL std::string getDescriptionText(const std::string &code) const;
+
+ // non-standard
+ PROJ_DLL static AuthorityFactoryNNPtr
+ create(const DatabaseContextNNPtr &context,
+ const std::string &authorityName);
+
+ PROJ_DLL const DatabaseContextNNPtr &databaseContext() const;
+
+ PROJ_DLL std::vector<operation::CoordinateOperationNNPtr>
+ createFromCoordinateReferenceSystemCodes(
+ const std::string &sourceCRSAuthName, const std::string &sourceCRSCode,
+ const std::string &targetCRSAuthName, const std::string &targetCRSCode,
+ bool usePROJAlternativeGridNames, bool discardIfMissingGrid) const;
+
+ PROJ_DLL std::vector<operation::CoordinateOperationNNPtr>
+ createFromCRSCodesWithIntermediates(
+ const std::string &sourceCRSAuthName, const std::string &sourceCRSCode,
+ const std::string &targetCRSAuthName, const std::string &targetCRSCode,
+ bool usePROJAlternativeGridNames, bool discardIfMissingGrid,
+ const std::vector<std::pair<std::string, std::string>>
+ &intermediateCRSAuthCodes) const;
+
+ PROJ_DLL std::string getOfficialNameFromAlias(
+ const std::string &aliasedName, const std::string &tableName,
+ const std::string &source, std::string &outTableName,
+ std::string &outAuthName, std::string &outCode) const;
+
+ PROJ_DLL std::list<common::IdentifiedObjectNNPtr>
+ createObjectsFromName(const std::string &name,
+ const std::vector<ObjectType> &allowedObjectTypes =
+ std::vector<ObjectType>(),
+ bool approximateMatch = true,
+ size_t limitResultCount = 0);
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+
+ PROJ_INTERNAL std::list<datum::EllipsoidNNPtr>
+ createEllipsoidFromExisting(
+ const datum::EllipsoidNNPtr &ellipsoid) const;
+
+ PROJ_INTERNAL std::list<crs::GeodeticCRSNNPtr>
+ createGeodeticCRSFromDatum(const std::string &datum_auth_name,
+ const std::string &datum_code,
+ const std::string &geodetic_crs_type) const;
+
+ PROJ_INTERNAL std::list<crs::GeodeticCRSNNPtr>
+ createGeodeticCRSFromEllipsoid(const std::string &ellipsoid_auth_name,
+ const std::string &ellipsoid_code,
+ const std::string &geodetic_crs_type) const;
+
+ PROJ_INTERNAL std::list<crs::ProjectedCRSNNPtr>
+ createProjectedCRSFromExisting(const crs::ProjectedCRSNNPtr &crs) const;
+
+ PROJ_INTERNAL std::list<crs::CompoundCRSNNPtr>
+ createCompoundCRSFromExisting(const crs::CompoundCRSNNPtr &crs) const;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL AuthorityFactory(const DatabaseContextNNPtr &context,
+ const std::string &authorityName);
+
+ PROJ_INTERNAL crs::CRSNNPtr
+ createCoordinateReferenceSystem(const std::string &code,
+ bool allowCompound) const;
+
+ PROJ_INTERNAL crs::GeodeticCRSNNPtr
+ createGeodeticCRS(const std::string &code, bool geographicOnly) const;
+
+ PROJ_INTERNAL operation::CoordinateOperationNNPtr
+ createCoordinateOperation(const std::string &code, bool allowConcatenated,
+ bool usePROJAlternativeGridNames) const;
+
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Exception thrown when a factory can't create an instance of the
+ * requested object.
+ */
+class PROJ_GCC_DLL FactoryException : public util::Exception {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL explicit FactoryException(const char *message);
+ PROJ_DLL explicit FactoryException(const std::string &message);
+ PROJ_DLL
+ FactoryException(const FactoryException &other);
+ PROJ_DLL ~FactoryException() override;
+ //! @endcond
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Exception thrown when an authority factory can't find the requested
+ * authority code.
+ */
+class PROJ_GCC_DLL NoSuchAuthorityCodeException : public FactoryException {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL explicit NoSuchAuthorityCodeException(const std::string &message,
+ const std::string &authority,
+ const std::string &code);
+ PROJ_DLL
+ NoSuchAuthorityCodeException(const NoSuchAuthorityCodeException &other);
+ PROJ_DLL ~NoSuchAuthorityCodeException() override;
+ //! @endcond
+
+ PROJ_DLL const std::string &getAuthority() const;
+ PROJ_DLL const std::string &getAuthorityCode() const;
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+} // namespace io
+
+NS_PROJ_END
+
+#endif // IO_HH_INCLUDED
diff --git a/include/proj/metadata.hpp b/include/proj/metadata.hpp
new file mode 100644
index 00000000..fc86693d
--- /dev/null
+++ b/include/proj/metadata.hpp
@@ -0,0 +1,458 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef METADATA_HH_INCLUDED
+#define METADATA_HH_INCLUDED
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "io.hpp"
+#include "util.hpp"
+
+NS_PROJ_START
+
+namespace common {
+class UnitOfMeasure;
+using UnitOfMeasurePtr = std::shared_ptr<UnitOfMeasure>;
+using UnitOfMeasureNNPtr = util::nn<UnitOfMeasurePtr>;
+class IdentifiedObject;
+} // namespace common
+
+/** osgeo.proj.metadata namespace
+ *
+ * \brief Common classes from \ref ISO_19115 standard
+ */
+namespace metadata {
+
+// ---------------------------------------------------------------------------
+
+/** \brief Standardized resource reference.
+ *
+ * Local names are names which are directly accessible to and maintained by a
+ * NameSpace within which they are local, indicated by the scope.
+ *
+ * \remark Simplified version of [Citation]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/metadata/citation/Citation.html)
+ * from \ref GeoAPI
+ */
+class PROJ_GCC_DLL Citation : public util::BaseObject {
+ public:
+ PROJ_DLL explicit Citation(const std::string &titleIn);
+ //! @cond Doxygen_Suppress
+ PROJ_DLL Citation();
+ PROJ_DLL Citation(const Citation &other);
+ PROJ_DLL ~Citation();
+ //! @endcond
+
+ PROJ_DLL const util::optional<std::string> &title() PROJ_CONST_DECL;
+
+ protected:
+ PROJ_FRIEND_OPTIONAL(Citation);
+ PROJ_INTERNAL Citation &operator=(const Citation &other);
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class GeographicExtent;
+/** Shared pointer of GeographicExtent. */
+using GeographicExtentPtr = std::shared_ptr<GeographicExtent>;
+/** Non-null shared pointer of GeographicExtent. */
+using GeographicExtentNNPtr = util::nn<GeographicExtentPtr>;
+
+/** \brief Base interface for geographic area of the dataset.
+ *
+ * \remark Simplified version of [GeographicExtent]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/metadata/extent/GeographicExtent.html)
+ * from \ref GeoAPI
+ */
+class PROJ_GCC_DLL GeographicExtent : public util::BaseObject,
+ public util::IComparable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~GeographicExtent() override;
+ //! @endcond
+
+ // GeoAPI has a getInclusion() method. We assume that it is included for our
+ // use
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool _isEquivalentTo(
+ const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override = 0;
+ //! @endcond
+
+ /** \brief Returns whether this extent contains the other one. */
+ PROJ_DLL virtual bool
+ contains(const GeographicExtentNNPtr &other) const = 0;
+
+ /** \brief Returns whether this extent intersects the other one. */
+ PROJ_DLL virtual bool
+ intersects(const GeographicExtentNNPtr &other) const = 0;
+
+ /** \brief Returns the intersection of this extent with another one. */
+ PROJ_DLL virtual GeographicExtentPtr
+ intersection(const GeographicExtentNNPtr &other) const = 0;
+
+ protected:
+ PROJ_INTERNAL GeographicExtent();
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class GeographicBoundingBox;
+/** Shared pointer of GeographicBoundingBox. */
+using GeographicBoundingBoxPtr = std::shared_ptr<GeographicBoundingBox>;
+/** Non-null shared pointer of GeographicBoundingBox. */
+using GeographicBoundingBoxNNPtr = util::nn<GeographicBoundingBoxPtr>;
+
+/** \brief Geographic position of the dataset.
+ *
+ * This is only an approximate so specifying the co-ordinate reference system is
+ * unnecessary.
+ *
+ * \remark Implements [GeographicBoundingBox]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/metadata/extent/GeographicBoundingBox.html)
+ * from \ref GeoAPI
+ */
+class PROJ_GCC_DLL GeographicBoundingBox : public GeographicExtent {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~GeographicBoundingBox() override;
+ //! @endcond
+
+ PROJ_DLL double westBoundLongitude() PROJ_CONST_DECL;
+ PROJ_DLL double southBoundLatitude() PROJ_CONST_DECL;
+ PROJ_DLL double eastBoundLongitude() PROJ_CONST_DECL;
+ PROJ_DLL double northBoundLatitude() PROJ_CONST_DECL;
+
+ PROJ_DLL static GeographicBoundingBoxNNPtr
+ create(double west, double south, double east, double north);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ PROJ_INTERNAL bool
+ contains(const GeographicExtentNNPtr &other) const override;
+
+ PROJ_INTERNAL bool
+ intersects(const GeographicExtentNNPtr &other) const override;
+
+ PROJ_INTERNAL GeographicExtentPtr
+ intersection(const GeographicExtentNNPtr &other) const override;
+
+ protected:
+ PROJ_INTERNAL GeographicBoundingBox(double west, double south, double east,
+ double north);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class TemporalExtent;
+/** Shared pointer of TemporalExtent. */
+using TemporalExtentPtr = std::shared_ptr<TemporalExtent>;
+/** Non-null shared pointer of TemporalExtent. */
+using TemporalExtentNNPtr = util::nn<TemporalExtentPtr>;
+
+/** \brief Time period covered by the content of the dataset.
+ *
+ * \remark Simplified version of [TemporalExtent]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/metadata/extent/TemporalExtent.html)
+ * from \ref GeoAPI
+ */
+class PROJ_GCC_DLL TemporalExtent : public util::BaseObject,
+ public util::IComparable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~TemporalExtent() override;
+ //! @endcond
+
+ PROJ_DLL const std::string &start() PROJ_CONST_DECL;
+ PROJ_DLL const std::string &stop() PROJ_CONST_DECL;
+
+ PROJ_DLL static TemporalExtentNNPtr create(const std::string &start,
+ const std::string &stop);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ PROJ_DLL bool contains(const TemporalExtentNNPtr &other) const;
+
+ PROJ_DLL bool intersects(const TemporalExtentNNPtr &other) const;
+
+ protected:
+ PROJ_INTERNAL TemporalExtent(const std::string &start,
+ const std::string &stop);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class VerticalExtent;
+/** Shared pointer of VerticalExtent. */
+using VerticalExtentPtr = std::shared_ptr<VerticalExtent>;
+/** Non-null shared pointer of VerticalExtent. */
+using VerticalExtentNNPtr = util::nn<VerticalExtentPtr>;
+
+/** \brief Vertical domain of dataset.
+ *
+ * \remark Simplified version of [VerticalExtent]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/metadata/extent/VerticalExtent.html)
+ * from \ref GeoAPI
+ */
+class PROJ_GCC_DLL VerticalExtent : public util::BaseObject,
+ public util::IComparable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~VerticalExtent() override;
+ //! @endcond
+
+ PROJ_DLL double minimumValue() PROJ_CONST_DECL;
+ PROJ_DLL double maximumValue() PROJ_CONST_DECL;
+ PROJ_DLL common::UnitOfMeasureNNPtr &unit() PROJ_CONST_DECL;
+
+ PROJ_DLL static VerticalExtentNNPtr
+ create(double minimumValue, double maximumValue,
+ const common::UnitOfMeasureNNPtr &unitIn);
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ PROJ_DLL bool contains(const VerticalExtentNNPtr &other) const;
+
+ PROJ_DLL bool intersects(const VerticalExtentNNPtr &other) const;
+
+ protected:
+ PROJ_INTERNAL VerticalExtent(double minimumValue, double maximumValue,
+ const common::UnitOfMeasureNNPtr &unitIn);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class Extent;
+/** Shared pointer of Extent. */
+using ExtentPtr = std::shared_ptr<Extent>;
+/** Non-null shared pointer of Extent. */
+using ExtentNNPtr = util::nn<ExtentPtr>;
+
+/** \brief Information about spatial, vertical, and temporal extent.
+ *
+ * \remark Simplified version of [Extent]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/metadata/extent/Extent.html)
+ * from \ref GeoAPI
+ */
+class PROJ_GCC_DLL Extent : public util::BaseObject, public util::IComparable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL Extent(const Extent &other);
+ PROJ_DLL ~Extent() override;
+ //! @endcond
+
+ PROJ_DLL const util::optional<std::string> &description() PROJ_CONST_DECL;
+ PROJ_DLL const std::vector<GeographicExtentNNPtr> &
+ geographicElements() PROJ_CONST_DECL;
+ PROJ_DLL const std::vector<TemporalExtentNNPtr> &
+ temporalElements() PROJ_CONST_DECL;
+ PROJ_DLL const std::vector<VerticalExtentNNPtr> &
+ verticalElements() PROJ_CONST_DECL;
+
+ PROJ_DLL static ExtentNNPtr
+ create(const util::optional<std::string> &descriptionIn,
+ const std::vector<GeographicExtentNNPtr> &geographicElementsIn,
+ const std::vector<VerticalExtentNNPtr> &verticalElementsIn,
+ const std::vector<TemporalExtentNNPtr> &temporalElementsIn);
+
+ PROJ_DLL static ExtentNNPtr
+ createFromBBOX(double west, double south, double east, double north,
+ const util::optional<std::string> &descriptionIn =
+ util::optional<std::string>());
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL bool
+ _isEquivalentTo(const util::IComparable *other,
+ util::IComparable::Criterion criterion =
+ util::IComparable::Criterion::STRICT) const override;
+ //! @endcond
+
+ PROJ_DLL bool contains(const ExtentNNPtr &other) const;
+
+ PROJ_DLL bool intersects(const ExtentNNPtr &other) const;
+
+ PROJ_DLL ExtentPtr intersection(const ExtentNNPtr &other) const;
+
+ PROJ_DLL static const ExtentNNPtr WORLD;
+
+ protected:
+ PROJ_INTERNAL Extent();
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ Extent &operator=(const Extent &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+class Identifier;
+/** Shared pointer of Identifier. */
+using IdentifierPtr = std::shared_ptr<Identifier>;
+/** Non-null shared pointer of Identifier. */
+using IdentifierNNPtr = util::nn<IdentifierPtr>;
+
+/** \brief Value uniquely identifying an object within a namespace.
+ *
+ * \remark Implements Identifier as described in \ref ISO_19111_2018 but which
+ * originates from \ref ISO_19115
+ */
+class PROJ_GCC_DLL Identifier : public util::BaseObject,
+ public io::IWKTExportable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL Identifier(const Identifier &other);
+ PROJ_DLL ~Identifier() override;
+ //! @endcond
+
+ PROJ_DLL static IdentifierNNPtr
+ create(const std::string &codeIn = std::string(),
+ const util::PropertyMap &properties =
+ util::PropertyMap()); // throw(InvalidValueTypeException)
+
+ PROJ_DLL static const std::string AUTHORITY_KEY;
+ PROJ_DLL static const std::string CODE_KEY;
+ PROJ_DLL static const std::string CODESPACE_KEY;
+ PROJ_DLL static const std::string VERSION_KEY;
+ PROJ_DLL static const std::string DESCRIPTION_KEY;
+ PROJ_DLL static const std::string URI_KEY;
+
+ PROJ_DLL static const std::string EPSG;
+ PROJ_DLL static const std::string OGC;
+
+ PROJ_DLL const util::optional<Citation> &authority() PROJ_CONST_DECL;
+ PROJ_DLL const std::string &code() PROJ_CONST_DECL;
+ PROJ_DLL const util::optional<std::string> &codeSpace() PROJ_CONST_DECL;
+ PROJ_DLL const util::optional<std::string> &version() PROJ_CONST_DECL;
+ PROJ_DLL const util::optional<std::string> &description() PROJ_CONST_DECL;
+ PROJ_DLL const util::optional<std::string> &uri() PROJ_CONST_DECL;
+
+ PROJ_DLL static bool isEquivalentName(const char *a,
+ const char *b) noexcept;
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL static std::string
+ canonicalizeName(const std::string &str);
+
+ PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
+ const override; // throw(io::FormattingException)
+
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL explicit Identifier(const std::string &codeIn,
+ const util::PropertyMap &properties);
+
+ PROJ_FRIEND_OPTIONAL(Identifier);
+ INLINED_MAKE_SHARED
+ Identifier &operator=(const Identifier &other) = delete;
+
+ PROJ_FRIEND(common::IdentifiedObject);
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class PositionalAccuracy;
+/** Shared pointer of PositionalAccuracy. */
+using PositionalAccuracyPtr = std::shared_ptr<PositionalAccuracy>;
+/** Non-null shared pointer of PositionalAccuracy. */
+using PositionalAccuracyNNPtr = util::nn<PositionalAccuracyPtr>;
+
+/** \brief Accuracy of the position of features.
+ *
+ * \remark Simplified version of [PositionalAccuracy]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/metadata/quality/PositionalAccuracy.html)
+ * from \ref GeoAPI, which originates from \ref ISO_19115
+ */
+class PROJ_GCC_DLL PositionalAccuracy : public util::BaseObject {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~PositionalAccuracy() override;
+ //! @endcond
+
+ PROJ_DLL const std::string &value() PROJ_CONST_DECL;
+
+ PROJ_DLL static PositionalAccuracyNNPtr create(const std::string &valueIn);
+
+ protected:
+ PROJ_INTERNAL explicit PositionalAccuracy(const std::string &valueIn);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ PositionalAccuracy(const PositionalAccuracy &other) = delete;
+ PositionalAccuracy &operator=(const PositionalAccuracy &other) = delete;
+};
+
+} // namespace metadata
+
+NS_PROJ_END
+
+#endif // METADATA_HH_INCLUDED
diff --git a/include/proj/nn.hpp b/include/proj/nn.hpp
new file mode 100644
index 00000000..4b17a17d
--- /dev/null
+++ b/include/proj/nn.hpp
@@ -0,0 +1,385 @@
+#pragma once
+
+/*
+ * Copyright (c) 2015 Dropbox, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cassert>
+#include <cstdlib>
+#include <functional>
+#include <memory>
+#include <type_traits>
+
+namespace dropbox {
+namespace oxygen {
+
+// Marker type and value for use by nn below.
+struct i_promise_i_checked_for_null_t {};
+static constexpr i_promise_i_checked_for_null_t i_promise_i_checked_for_null{};
+
+// Helper to get the type pointed to by a raw or smart pointer. This can be
+// explicitly
+// specialized if need be to provide compatibility with user-defined smart
+// pointers.
+namespace nn_detail {
+template <typename T> struct element_type {
+ using type = typename T::element_type;
+};
+template <typename Pointee> struct element_type<Pointee *> {
+ using type = Pointee;
+};
+}
+
+template <typename PtrType> class nn;
+
+// Trait to check whether a given type is a non-nullable pointer
+template <typename T> struct is_nn : public std::false_type {};
+template <typename PtrType>
+struct is_nn<nn<PtrType>> : public std::true_type {};
+
+/* nn<PtrType>
+ *
+ * Wrapper around a pointer that is guaranteed to not be null. This works with
+ * raw pointers
+ * as well as any smart pointer: nn<int *>, nn<shared_ptr<DbxTable>>,
+ * nn<unique_ptr<Foo>>,
+ * etc. An nn<PtrType> can be used just like a PtrType.
+ *
+ * An nn<PtrType> can be constructed from another nn<PtrType>, if the underlying
+ * type would
+ * allow such construction. For example, nn<shared_ptr<PtrType>> can be copied
+ * and moved, but
+ * nn<unique_ptr<PtrType>> can only be moved; an nn<unique_ptr<PtrType>> can be
+ * explicitly
+ * (but not implicitly) created from an nn<PtrType*>; implicit upcasts are
+ * allowed; and so on.
+ *
+ * Similarly, non-nullable pointers can be compared with regular or other
+ * non-nullable
+ * pointers, using the same rules as the underlying pointer types.
+ *
+ * This module also provides helpers for creating an nn<PtrType> from operations
+ * that would
+ * always return a non-null pointer: nn_make_unique, nn_make_shared,
+ * nn_shared_from_this, and
+ * nn_addr (a replacement for operator&).
+ *
+ * We abbreviate nn<unique_ptr> as nn_unique_ptr - it's a little more readable.
+ * Likewise,
+ * nn<shared_ptr> can be written as nn_shared_ptr.
+ *
+ * Finally, we define macros NN_CHECK_ASSERT and NN_CHECK_THROW, to convert a
+ * nullable pointer
+ * to a non-nullable pointer. At Dropbox, these use customized error-handling
+ * infrastructure
+ * and are in a separate file. We've included sample implementations here.
+ */
+template <typename PtrType> class nn {
+public:
+ static_assert(!is_nn<PtrType>::value, "nn<nn<T>> is disallowed");
+
+ using element_type = typename nn_detail::element_type<PtrType>::type;
+
+ // Pass through calls to operator* and operator-> transparently
+ element_type &operator*() const { return *ptr; }
+ element_type *operator->() const { return &*ptr; }
+
+ // Expose the underlying PtrType
+ operator const PtrType &() const & { return ptr; }
+ operator PtrType &&() && { return std::move(ptr); }
+
+ // Trying to use the assignment operator to assign a nn<PtrType> to a PtrType
+ // using the
+ // above conversion functions hits an ambiguous resolution bug in clang:
+ // http://llvm.org/bugs/show_bug.cgi?id=18359
+ // While that exists, we can use these as simple ways of accessing the
+ // underlying type
+ // (instead of workarounds calling the operators explicitly or adding a
+ // constructor call).
+ const PtrType &as_nullable() const & { return ptr; }
+ PtrType &&as_nullable() && { return std::move(ptr); }
+
+ // Can't convert to bool (that would be silly). The explicit delete results in
+ // "value of type 'nn<...>' is not contextually convertible to 'bool'", rather
+ // than
+ // "no viable conversion", which is a bit more clear.
+ operator bool() const = delete;
+
+ // Explicitly deleted constructors. These help produce clearer error messages,
+ // as trying
+ // to use them will result in clang printing the whole line, including the
+ // comment.
+ nn(std::nullptr_t) = delete; // nullptr is not allowed here
+ nn &operator=(std::nullptr_t) = delete; // nullptr is not allowed here
+ nn(PtrType) = delete; // must use NN_CHECK_ASSERT or NN_CHECK_THROW
+ nn &operator=(PtrType) = delete; // must use NN_CHECK_ASSERT or NN_CHECK_THROW
+ //PROJ_DLL ~nn();
+
+ // Semi-private constructor for use by NN_CHECK_ macros.
+ explicit nn(i_promise_i_checked_for_null_t, const PtrType &arg) noexcept : ptr(arg) {
+ }
+ explicit nn(i_promise_i_checked_for_null_t, PtrType &&arg) noexcept
+ : ptr(std::move(arg)) {
+ }
+
+ // Type-converting move and copy constructor. We have four separate cases
+ // here, for
+ // implicit and explicit move and copy.
+ template <typename OtherType,
+ typename std::enable_if<
+ std::is_constructible<PtrType, OtherType>::value &&
+ !std::is_convertible<OtherType, PtrType>::value,
+ int>::type = 0>
+ explicit nn(const nn<OtherType> &other)
+ : ptr(other.operator const OtherType &()) {}
+
+ template <typename OtherType,
+ typename std::enable_if<
+ std::is_constructible<PtrType, OtherType>::value &&
+ !std::is_convertible<OtherType, PtrType>::value &&
+ !std::is_pointer<OtherType>::value,
+ int>::type = 0>
+ explicit nn(nn<OtherType> &&other)
+ : ptr(std::move(other).operator OtherType &&()) {}
+
+ template <typename OtherType,
+ typename std::enable_if<
+ std::is_convertible<OtherType, PtrType>::value, int>::type = 0>
+ nn(const nn<OtherType> &other) : ptr(other.operator const OtherType &()) {}
+
+ template <
+ typename OtherType,
+ typename std::enable_if<std::is_convertible<OtherType, PtrType>::value &&
+ !std::is_pointer<OtherType>::value,
+ int>::type = 0>
+ nn(nn<OtherType> &&other) : ptr(std::move(other).operator OtherType &&()) {}
+
+ // A type-converting move and copy assignment operator aren't necessary;
+ // writing
+ // "base_ptr = derived_ptr;" will run the type-converting constructor followed
+ // by the
+ // implicit move assignment operator.
+
+ // Two-argument constructor, designed for use with the shared_ptr aliasing
+ // constructor.
+ // This will not be instantiated if PtrType doesn't have a suitable
+ // constructor.
+ template <
+ typename OtherType,
+ typename std::enable_if<
+ std::is_constructible<PtrType, OtherType, element_type *>::value,
+ int>::type = 0>
+ nn(const nn<OtherType> &ownership_ptr, nn<element_type *> target_ptr)
+ : ptr(ownership_ptr.operator const OtherType &(), target_ptr) {}
+
+ // Comparisons. Other comparisons are implemented in terms of these.
+ template <typename L, typename R>
+ friend bool operator==(const nn<L> &, const R &);
+ template <typename L, typename R>
+ friend bool operator==(const L &, const nn<R> &);
+ template <typename L, typename R>
+ friend bool operator==(const nn<L> &, const nn<R> &);
+
+ template <typename L, typename R>
+ friend bool operator<(const nn<L> &, const R &);
+ template <typename L, typename R>
+ friend bool operator<(const L &, const nn<R> &);
+ template <typename L, typename R>
+ friend bool operator<(const nn<L> &, const nn<R> &);
+
+ // ostream operator
+ template <typename T>
+ friend std::ostream &operator<<(std::ostream &, const nn<T> &);
+
+ template <typename T = PtrType> element_type *get() const {
+ return ptr.get();
+ }
+
+private:
+ // Backing pointer
+ PtrType ptr;
+};
+
+// Base comparisons - these are friends of nn<PtrType>, so they can access .ptr
+// directly.
+template <typename L, typename R> bool operator==(const nn<L> &l, const R &r) {
+ return l.ptr == r;
+}
+template <typename L, typename R> bool operator==(const L &l, const nn<R> &r) {
+ return l == r.ptr;
+}
+template <typename L, typename R>
+bool operator==(const nn<L> &l, const nn<R> &r) {
+ return l.ptr == r.ptr;
+}
+template <typename L, typename R> bool operator<(const nn<L> &l, const R &r) {
+ return l.ptr < r;
+}
+template <typename L, typename R> bool operator<(const L &l, const nn<R> &r) {
+ return l < r.ptr;
+}
+template <typename L, typename R>
+bool operator<(const nn<L> &l, const nn<R> &r) {
+ return l.ptr < r.ptr;
+}
+template <typename T>
+std::ostream &operator<<(std::ostream &os, const nn<T> &p) {
+ return os << p.ptr;
+}
+
+#define NN_DERIVED_OPERATORS(op, base) \
+ template <typename L, typename R> \
+ bool operator op(const nn<L> &l, const R &r) { \
+ return base; \
+ } \
+ template <typename L, typename R> \
+ bool operator op(const L &l, const nn<R> &r) { \
+ return base; \
+ } \
+ template <typename L, typename R> \
+ bool operator op(const nn<L> &l, const nn<R> &r) { \
+ return base; \
+ }
+
+NN_DERIVED_OPERATORS(>, r < l)
+NN_DERIVED_OPERATORS(<=, !(l > r))
+NN_DERIVED_OPERATORS(>=, !(l < r))
+NN_DERIVED_OPERATORS(!=, !(l == r))
+
+#undef NN_DERIVED_OPERATORS
+
+// Convenience typedefs
+template <typename T> using nn_unique_ptr = nn<std::unique_ptr<T>>;
+template <typename T> using nn_shared_ptr = nn<std::shared_ptr<T>>;
+
+template <typename T, typename... Args>
+nn_unique_ptr<T> nn_make_unique(Args &&... args) {
+ return nn_unique_ptr<T>(
+ i_promise_i_checked_for_null,
+ std::unique_ptr<T>(new T(std::forward<Args>(args)...)));
+}
+
+template <typename T, typename... Args>
+nn_shared_ptr<T> nn_make_shared(Args &&... args) {
+ return nn_shared_ptr<T>(i_promise_i_checked_for_null,
+ std::make_shared<T>(std::forward<Args>(args)...));
+}
+
+template <typename T>
+class nn_enable_shared_from_this : public std::enable_shared_from_this<T> {
+public:
+ using std::enable_shared_from_this<T>::enable_shared_from_this;
+ nn_shared_ptr<T> nn_shared_from_this() {
+ return nn_shared_ptr<T>(i_promise_i_checked_for_null,
+ this->shared_from_this());
+ }
+ nn_shared_ptr<const T> nn_shared_from_this() const {
+ return nn_shared_ptr<const T>(i_promise_i_checked_for_null,
+ this->shared_from_this());
+ }
+};
+
+template <typename T> nn<T *> nn_addr(T &object) {
+ return nn<T *>(i_promise_i_checked_for_null, &object);
+}
+
+template <typename T> nn<const T *> nn_addr(const T &object) {
+ return nn<const T *>(i_promise_i_checked_for_null, &object);
+}
+
+/* Non-nullable equivalents of shared_ptr's specialized casting functions.
+ * These convert through a shared_ptr since nn<shared_ptr<T>> lacks the
+ * ref-count-sharing cast
+ * constructor, but thanks to moves there shouldn't be any significant extra
+ * cost. */
+template <typename T, typename U>
+nn_shared_ptr<T> nn_static_pointer_cast(const nn_shared_ptr<U> &org_ptr) {
+ auto raw_ptr =
+ static_cast<typename nn_shared_ptr<T>::element_type *>(org_ptr.get());
+ std::shared_ptr<T> nullable_ptr(org_ptr.as_nullable(), raw_ptr);
+ return nn_shared_ptr<T>(i_promise_i_checked_for_null,
+ std::move(nullable_ptr));
+}
+
+template <typename T, typename U>
+std::shared_ptr<T> nn_dynamic_pointer_cast(const nn_shared_ptr<U> &org_ptr) {
+ auto raw_ptr =
+ dynamic_cast<typename std::shared_ptr<T>::element_type *>(org_ptr.get());
+ if (!raw_ptr) {
+ return nullptr;
+ } else {
+ return std::shared_ptr<T>(org_ptr.as_nullable(), raw_ptr);
+ }
+}
+
+template <typename T, typename U>
+nn_shared_ptr<T> nn_const_pointer_cast(const nn_shared_ptr<U> &org_ptr) {
+ auto raw_ptr =
+ const_cast<typename nn_shared_ptr<T>::element_type *>(org_ptr.get());
+ std::shared_ptr<T> nullable_ptr(org_ptr.as_nullable(), raw_ptr);
+ return nn_shared_ptr<T>(i_promise_i_checked_for_null,
+ std::move(nullable_ptr));
+}
+}
+} /* end namespace dropbox::oxygen */
+
+namespace std {
+template <typename T> struct hash<::dropbox::oxygen::nn<T>> {
+ using argument_type = ::dropbox::oxygen::nn<T>;
+ using result_type = size_t;
+ result_type operator()(const argument_type &obj) const {
+ return std::hash<T>{}(obj.as_nullable());
+ }
+};
+}
+
+/* These have to be macros because our internal versions invoke other macros
+ * that use
+ * __FILE__ and __LINE__, which we want to correctly point to the call site.
+ * We're looking
+ * forward to std::source_location :)
+ *
+ * The lambdas ensure that we only evaluate _e once.
+ */
+#include <stdexcept>
+
+// NN_CHECK_ASSERT takes a pointer of type PT (e.g. raw pointer, std::shared_ptr
+// or std::unique_ptr)
+// and returns a non-nullable pointer of type nn<PT>.
+// Triggers an assertion if expression evaluates to null.
+#define NN_CHECK_ASSERT(_e) \
+ (([&](typename std::remove_reference<decltype(_e)>::type p) { \
+ /* note: assert() alone is not sufficient here, because it might be \
+ * compiled out. */ \
+ assert(p &&#_e " must not be null"); \
+ if (!p) \
+ std::abort(); \
+ return dropbox::oxygen::nn< \
+ typename std::remove_reference<decltype(p)>::type>( \
+ dropbox::oxygen::i_promise_i_checked_for_null, std::move(p)); \
+ })(_e))
+
+// NN_CHECK_THROW takes a pointer of type PT (e.g. raw pointer, std::shared_ptr
+// or std::unique_ptr)
+// and returns a non-nullable pointer of type nn<PT>.
+// Throws if expression evaluates to null.
+#define NN_CHECK_THROW(_e) \
+ (([&](typename std::remove_reference<decltype(_e)>::type p) { \
+ if (!p) \
+ throw std::runtime_error(#_e " must not be null"); \
+ return dropbox::oxygen::nn< \
+ typename std::remove_reference<decltype(p)>::type>( \
+ dropbox::oxygen::i_promise_i_checked_for_null, std::move(p)); \
+ })(_e))
diff --git a/include/proj/util.hpp b/include/proj/util.hpp
new file mode 100644
index 00000000..eb7288b2
--- /dev/null
+++ b/include/proj/util.hpp
@@ -0,0 +1,752 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#ifndef UTIL_HH_INCLUDED
+#define UTIL_HH_INCLUDED
+
+#if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
+#error Must have C++11 or newer.
+#endif
+
+#include <exception>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#ifndef NS_PROJ
+/** osgeo namespace */
+namespace osgeo {
+/** osgeo.proj namespace */
+namespace proj {}
+} // namespace osgeo
+#endif
+
+//! @cond Doxygen_Suppress
+
+#ifndef PROJ_DLL
+#ifdef PROJ_MSVC_DLL_EXPORT
+#define PROJ_DLL __declspec(dllexport)
+#elif defined(PROJ_MSVC_DLL_IMPORT)
+#define PROJ_DLL __declspec(dllimport)
+#elif defined(__GNUC__)
+#define PROJ_DLL __attribute__((visibility("default")))
+#else
+#define PROJ_DLL
+#endif
+#endif
+
+#ifndef PROJ_MSVC_DLL
+
+#ifdef PROJ_MSVC_DLL_EXPORT
+#define PROJ_MSVC_DLL PROJ_DLL
+#define PROJ_GCC_DLL
+#define PROJ_INTERNAL
+#elif defined(PROJ_MSVC_DLL_IMPORT)
+#define PROJ_MSVC_DLL PROJ_DLL
+#define PROJ_GCC_DLL
+#define PROJ_INTERNAL
+#elif defined(__GNUC__)
+#define PROJ_MSVC_DLL
+#define PROJ_GCC_DLL PROJ_DLL
+#if !defined(__MINGW32__)
+#define PROJ_INTERNAL __attribute__((visibility("hidden")))
+#else
+#define PROJ_INTERNAL
+#endif
+#else
+#define PROJ_MSVC_DLL
+#define PROJ_GCC_DLL
+#define PROJ_INTERNAL
+#endif
+
+#define PROJ_FOR_TEST PROJ_DLL
+
+#endif
+
+#include "nn.hpp"
+
+/* To allow customizing the base namespace of PROJ */
+#ifndef NS_PROJ
+#define NS_PROJ osgeo::proj
+#define NS_PROJ_START \
+ namespace osgeo { \
+ namespace proj {
+#define NS_PROJ_END \
+ } \
+ }
+#endif
+
+// Private-implementation (Pimpl) pattern
+#define PROJ_OPAQUE_PRIVATE_DATA \
+ private: \
+ struct PROJ_INTERNAL Private; \
+ std::unique_ptr<Private> d; \
+ \
+ protected: \
+ PROJ_INTERNAL Private *getPrivate() noexcept { return d.get(); } \
+ PROJ_INTERNAL const Private *getPrivate() const noexcept { \
+ return d.get(); \
+ } \
+ \
+ private:
+
+// To include in the protected/private section of a class definition,
+// to be able to call make_shared on a protected/private constructor
+#define INLINED_MAKE_SHARED \
+ template <typename T, typename... Args> \
+ static std::shared_ptr<T> make_shared(Args &&... args) { \
+ return std::shared_ptr<T>(new T(std::forward<Args>(args)...)); \
+ } \
+ template <typename T, typename... Args> \
+ static util::nn_shared_ptr<T> nn_make_shared(Args &&... args) { \
+ return util::nn_shared_ptr<T>( \
+ util::i_promise_i_checked_for_null, \
+ std::shared_ptr<T>(new T(std::forward<Args>(args)...))); \
+ }
+
+// To include in the protected/private section of a class definition,
+// to be able to call make_unique on a protected/private constructor
+#define INLINED_MAKE_UNIQUE \
+ template <typename T, typename... Args> \
+ static std::unique_ptr<T> make_unique(Args &&... args) { \
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); \
+ }
+
+#ifdef DOXYGEN_ENABLED
+#define PROJ_FRIEND(mytype)
+#define PROJ_FRIEND_OPTIONAL(mytype)
+#else
+#define PROJ_FRIEND(mytype) friend class mytype
+#define PROJ_FRIEND_OPTIONAL(mytype) friend class util::optional<mytype>
+#endif
+
+#ifndef PROJ_PRIVATE
+#define PROJ_PRIVATE public
+#endif
+
+#if defined(__GNUC__)
+#define PROJ_NO_INLINE __attribute__((noinline))
+#define PROJ_NO_RETURN __attribute__((noreturn))
+// Applies to a function that has no side effect, and its return will not
+// change if the arguments are the same. But is return may change
+// if the object state changes. So this is for getters of mutable objects.
+#define PROJ_PURE_DECL const noexcept __attribute__((pure))
+// Applies to a function that has no side effect, and its return will not
+// change if the arguments are the same, and their pointed value must not
+// be modified. So this is for getters of immutable objets. This is stronger
+// than PROJ_PURE_DECL.
+#if defined(__INTEL_COMPILER)
+// If using __attribute__((const)), ICC on an expression like
+// Angle(x).getSIValue() will create the object, destroy it and then call
+// getSIValue(). Fallback to ((pure)), which is weaker
+#define PROJ_CONST_DECL const noexcept __attribute__((pure))
+#else
+#define PROJ_CONST_DECL const noexcept __attribute__((const))
+#endif
+#else
+#define PROJ_NO_RETURN
+#define PROJ_NO_INLINE
+#define PROJ_PURE_DECL const noexcept
+#define PROJ_CONST_DECL const noexcept
+#endif
+#define PROJ_PURE_DEFN const noexcept
+#define PROJ_CONST_DEFN const noexcept
+
+//! @endcond
+
+NS_PROJ_START
+
+/** osgeo.proj.util namespace.
+ *
+ * \brief A set of base types from ISO 19103, \ref GeoAPI and other PROJ
+ * specific classes.
+ */
+namespace util {
+
+//! @cond Doxygen_Suppress
+// Import a few classes from nn.hpp to expose them under our ::util namespace
+// for conveniency.
+using ::dropbox::oxygen::i_promise_i_checked_for_null;
+using ::dropbox::oxygen::nn;
+using ::dropbox::oxygen::nn_dynamic_pointer_cast;
+using ::dropbox::oxygen::nn_make_shared;
+
+// For return statements, to convert from derived type to base type
+using ::dropbox::oxygen::nn_static_pointer_cast;
+
+template <typename T> using nn_shared_ptr = nn<std::shared_ptr<T>>;
+
+#define NN_NO_CHECK(p) \
+ ::dropbox::oxygen::nn<typename std::remove_const< \
+ typename std::remove_reference<decltype(p)>::type>::type>( \
+ dropbox::oxygen::i_promise_i_checked_for_null, (p))
+
+//! @endcond
+
+// To avoid formatting differences between clang-format 3.8 and 7
+#define PROJ_NOEXCEPT noexcept
+
+/** \brief Loose transposition of [std::optional]
+ * (https://en.cppreference.com/w/cpp/utility/optional) available from C++17. */
+template <class T> class optional {
+ public:
+ //! @cond Doxygen_Suppress
+ inline optional() : hasVal_(false) {}
+ inline explicit optional(const T &val) : hasVal_(true), val_(val) {}
+ inline explicit optional(T &&val)
+ : hasVal_(true), val_(std::forward<T>(val)) {}
+
+ inline optional(const optional &other) = default;
+ inline optional(optional &&other) PROJ_NOEXCEPT
+ : hasVal_(other.hasVal_),
+ // cppcheck-suppress functionStatic
+ val_(std::forward<T>(other.val_)) {
+ other.hasVal_ = false;
+ }
+
+ inline optional &operator=(const T &val) {
+ hasVal_ = true;
+ val_ = val;
+ return *this;
+ }
+ inline optional &operator=(T &&val) noexcept {
+ hasVal_ = true;
+ val_ = std::forward<T>(val);
+ return *this;
+ }
+ inline optional &operator=(const optional &other) = default;
+ inline optional &operator=(optional &&other) noexcept {
+ hasVal_ = other.hasVal_;
+ val_ = std::forward<T>(other.val_);
+ other.hasVal_ = false;
+ return *this;
+ }
+
+ inline T *operator->() { return &val_; }
+ inline T &operator*() { return val_; }
+
+ //! @endcond
+
+ /** Returns a pointer to the contained value. */
+ inline const T *operator->() const { return &val_; }
+
+ /** Returns a reference to the contained value. */
+ inline const T &operator*() const { return val_; }
+
+ /** Return whether the optional has a value */
+ inline explicit operator bool() const noexcept { return hasVal_; }
+
+ /** Return whether the optional has a value */
+ inline bool has_value() const noexcept { return hasVal_; }
+
+ private:
+ bool hasVal_;
+ T val_{};
+};
+
+// ---------------------------------------------------------------------------
+
+class BaseObject;
+/** Shared pointer of BaseObject. */
+using BaseObjectPtr = std::shared_ptr<BaseObject>;
+#if 1
+/** Non-null shared pointer of BaseObject. */
+struct BaseObjectNNPtr : public util::nn<BaseObjectPtr> {
+ // This trick enables to avoid inlining of the destructor.
+ // This is mostly an alias of the base class.
+ //! @cond Doxygen_Suppress
+ template <class T>
+ // cppcheck-suppress noExplicitConstructor
+ BaseObjectNNPtr(const util::nn<std::shared_ptr<T>> &x)
+ : util::nn<BaseObjectPtr>(x) {}
+
+ template <class T>
+ // cppcheck-suppress noExplicitConstructor
+ BaseObjectNNPtr(util::nn<std::shared_ptr<T>> &&x) noexcept
+ : util::nn<BaseObjectPtr>(NN_NO_CHECK(std::move(x.as_nullable()))) {}
+
+ explicit BaseObjectNNPtr(::dropbox::oxygen::i_promise_i_checked_for_null_t,
+ BaseObjectPtr &&arg) noexcept
+ : util::nn<BaseObjectPtr>(i_promise_i_checked_for_null,
+ std::move(arg)) {}
+ BaseObjectNNPtr(const BaseObjectNNPtr &) = default;
+ BaseObjectNNPtr &operator=(const BaseObjectNNPtr &) = default;
+
+ PROJ_DLL ~BaseObjectNNPtr();
+ //! @endcond
+};
+#else
+using BaseObjectNNPtr = util::nn<BaseObjectPtr>;
+#endif
+
+/** \brief Class that can be derived from, to emulate Java's Object behaviour.
+ */
+class PROJ_GCC_DLL BaseObject {
+ public:
+ //! @cond Doxygen_Suppress
+ virtual PROJ_DLL ~BaseObject();
+ //! @endcond
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL BaseObjectNNPtr
+ shared_from_this() const;
+ //! @endcond
+
+ protected:
+ PROJ_INTERNAL BaseObject();
+ PROJ_INTERNAL void assignSelf(const BaseObjectNNPtr &self);
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Interface for an object that can be compared to another.
+ */
+class PROJ_GCC_DLL IComparable {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL virtual ~IComparable();
+ //! @endcond
+
+ /** \brief Comparison criterion. */
+ enum class PROJ_MSVC_DLL Criterion {
+ /** All properties are identical. */
+ STRICT,
+
+ /** The objects are equivalent for the purpose of coordinate
+ * operations. They can differ by the name of their objects,
+ * identifiers, other metadata.
+ * Parameters may be expressed in different units, provided that the
+ * value is (with some tolerance) the same once expressed in a
+ * common unit.
+ */
+ EQUIVALENT,
+
+ /** Same as EQUIVALENT, relaxed with an exception that the axis order
+ * of the base CRS of a DerivedCRS/ProjectedCRS or the axis order of
+ * a GeographicCRS is ignored. Only to be used
+ * with DerivedCRS/ProjectedCRS/GeographicCRS */
+ EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS,
+ };
+
+ PROJ_DLL bool isEquivalentTo(const IComparable *other,
+ Criterion criterion = Criterion::STRICT) const;
+
+ PROJ_PRIVATE :
+
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL virtual bool
+ _isEquivalentTo(const IComparable *other,
+ Criterion criterion = Criterion::STRICT) const = 0;
+ //! @endcond
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Encapsulate standard datatypes in an object.
+ */
+class BoxedValue final : public BaseObject {
+ public:
+ //! @cond Doxygen_Suppress
+ /** Type of data stored in the BoxedValue. */
+ enum class Type {
+ /** a std::string */
+ STRING,
+ /** an integer */
+ INTEGER,
+ /** a boolean */
+ BOOLEAN
+ };
+ //! @endcond
+
+ // cppcheck-suppress noExplicitConstructor
+ PROJ_DLL BoxedValue(const char *stringValueIn); // needed to avoid the bool
+ // constructor to be taken !
+ // cppcheck-suppress noExplicitConstructor
+ PROJ_DLL BoxedValue(const std::string &stringValueIn);
+ // cppcheck-suppress noExplicitConstructor
+ PROJ_DLL BoxedValue(int integerValueIn);
+ // cppcheck-suppress noExplicitConstructor
+ PROJ_DLL BoxedValue(bool booleanValueIn);
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL
+ BoxedValue(const BoxedValue &other);
+
+ PROJ_DLL ~BoxedValue() override;
+
+ PROJ_INTERNAL const Type &type() const;
+ PROJ_INTERNAL const std::string &stringValue() const;
+ PROJ_INTERNAL int integerValue() const;
+ PROJ_INTERNAL bool booleanValue() const;
+ //! @endcond
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ BoxedValue &operator=(const BoxedValue &) = delete;
+
+ PROJ_INTERNAL BoxedValue();
+};
+
+/** Shared pointer of BoxedValue. */
+using BoxedValuePtr = std::shared_ptr<BoxedValue>;
+/** Non-null shared pointer of BoxedValue. */
+using BoxedValueNNPtr = util::nn<BoxedValuePtr>;
+
+// ---------------------------------------------------------------------------
+
+class ArrayOfBaseObject;
+/** Shared pointer of ArrayOfBaseObject. */
+using ArrayOfBaseObjectPtr = std::shared_ptr<ArrayOfBaseObject>;
+/** Non-null shared pointer of ArrayOfBaseObject. */
+using ArrayOfBaseObjectNNPtr = util::nn<ArrayOfBaseObjectPtr>;
+
+/** \brief Array of BaseObject.
+ */
+class ArrayOfBaseObject final : public BaseObject {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~ArrayOfBaseObject() override;
+ //! @endcond
+
+ PROJ_DLL void add(const BaseObjectNNPtr &obj);
+
+ PROJ_DLL static ArrayOfBaseObjectNNPtr create();
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ std::vector<BaseObjectNNPtr>::const_iterator
+ begin() const;
+ std::vector<BaseObjectNNPtr>::const_iterator end() const;
+ bool empty() const;
+ //! @endcond
+
+ protected:
+ ArrayOfBaseObject();
+ INLINED_MAKE_SHARED
+
+ private:
+ ArrayOfBaseObject(const ArrayOfBaseObject &other) = delete;
+ ArrayOfBaseObject &operator=(const ArrayOfBaseObject &other) = delete;
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Wrapper of a std::map<std::string, BaseObjectNNPtr> */
+class PropertyMap {
+ public:
+ PROJ_DLL PropertyMap();
+ //! @cond Doxygen_Suppress
+ PROJ_DLL PropertyMap(const PropertyMap &other);
+ PROJ_DLL ~PropertyMap();
+ //! @endcond
+
+ PROJ_DLL PropertyMap &set(const std::string &key,
+ const BaseObjectNNPtr &val);
+
+ //! @cond Doxygen_Suppress
+ template <class T>
+ inline PropertyMap &set(const std::string &key,
+ const nn_shared_ptr<T> &val) {
+ return set(
+ key, BaseObjectNNPtr(i_promise_i_checked_for_null,
+ BaseObjectPtr(val.as_nullable(), val.get())));
+ }
+ //! @endcond
+
+ // needed to avoid the bool constructor to be taken !
+ PROJ_DLL PropertyMap &set(const std::string &key, const char *val);
+
+ PROJ_DLL PropertyMap &set(const std::string &key, const std::string &val);
+
+ PROJ_DLL PropertyMap &set(const std::string &key, int val);
+
+ PROJ_DLL PropertyMap &set(const std::string &key, bool val);
+
+ PROJ_DLL PropertyMap &set(const std::string &key,
+ const std::vector<std::string> &array);
+
+ PROJ_PRIVATE :
+ //! @cond Doxygen_Suppress
+ std::map<std::string, BaseObjectNNPtr>::iterator
+ find(const std::string &key) const;
+ std::map<std::string, BaseObjectNNPtr>::iterator end() const;
+
+ // throw(InvalidValueTypeException)
+ bool getStringValue(const std::string &key, std::string &outVal) const;
+
+ static PropertyMap createAndSetName(const char *name);
+ static PropertyMap createAndSetName(const std::string &name);
+ //! @endcond
+
+ private:
+ PropertyMap &operator=(const PropertyMap &) = delete;
+
+ PropertyMap &set(const std::string &key, const BoxedValue &val);
+
+ PROJ_OPAQUE_PRIVATE_DATA
+};
+
+// ---------------------------------------------------------------------------
+
+class LocalName;
+/** Shared pointer of LocalName. */
+using LocalNamePtr = std::shared_ptr<LocalName>;
+/** Non-null shared pointer of LocalName. */
+using LocalNameNNPtr = util::nn<LocalNamePtr>;
+
+class NameSpace;
+/** Shared pointer of NameSpace. */
+using NameSpacePtr = std::shared_ptr<NameSpace>;
+/** Non-null shared pointer of NameSpace. */
+using NameSpaceNNPtr = util::nn<NameSpacePtr>;
+
+class GenericName;
+/** Shared pointer of GenericName. */
+using GenericNamePtr = std::shared_ptr<GenericName>;
+/** Non-null shared pointer of GenericName. */
+using GenericNameNNPtr = util::nn<GenericNamePtr>;
+
+// ---------------------------------------------------------------------------
+
+/** \brief A sequence of identifiers rooted within the context of a namespace.
+ *
+ * \remark Simplified version of [GenericName]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/util/GenericName.html) from
+ * \ref GeoAPI
+ */
+class GenericName : public BaseObject {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL virtual ~GenericName() override;
+ //! @endcond
+
+ /** \brief Return the scope of the object, possibly a global one. */
+ PROJ_DLL virtual const NameSpacePtr scope() const = 0;
+
+ /** \brief Return the LocalName as a string. */
+ PROJ_DLL virtual std::string toString() const = 0;
+
+ /** \brief Return a fully qualified name corresponding to the local name.
+ *
+ * The namespace of the resulting name is a global one.
+ */
+ PROJ_DLL virtual GenericNameNNPtr toFullyQualifiedName() const = 0;
+
+ protected:
+ GenericName();
+ GenericName(const GenericName &other);
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ GenericName &operator=(const GenericName &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief A domain in which names given by strings are defined.
+ *
+ * \remark Simplified version of [NameSpace]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/util/NameSpace.html) from \ref
+ * GeoAPI
+ */
+class NameSpace {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~NameSpace();
+ //! @endcond
+
+ PROJ_DLL bool isGlobal() const;
+ PROJ_DLL const GenericNamePtr &name() const;
+
+ protected:
+ PROJ_FRIEND(NameFactory);
+ PROJ_FRIEND(LocalName);
+ explicit NameSpace(const GenericNamePtr &name);
+ NameSpace(const NameSpace &other);
+ NameSpaceNNPtr getGlobalFromThis() const;
+ const std::string &separator() const;
+ static const NameSpaceNNPtr GLOBAL;
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ NameSpace &operator=(const NameSpace &other) = delete;
+
+ static NameSpaceNNPtr createGLOBAL();
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Identifier within a NameSpace for a local object.
+ *
+ * Local names are names which are directly accessible to and maintained by a
+ * NameSpace within which they are local, indicated by the scope.
+ *
+ * \remark Simplified version of [LocalName]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/util/LocalName.html) from \ref
+ * GeoAPI
+ */
+class LocalName : public GenericName {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~LocalName() override;
+ //! @endcond
+
+ PROJ_DLL const NameSpacePtr scope() const override;
+ PROJ_DLL std::string toString() const override;
+ PROJ_DLL GenericNameNNPtr toFullyQualifiedName() const override;
+
+ protected:
+ PROJ_FRIEND(NameFactory);
+ PROJ_FRIEND(NameSpace);
+ explicit LocalName(const std::string &nameIn);
+ LocalName(const LocalName &other);
+ LocalName(const NameSpacePtr &ns, const std::string &name);
+ INLINED_MAKE_SHARED
+
+ private:
+ PROJ_OPAQUE_PRIVATE_DATA
+ LocalName &operator=(const LocalName &other) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Factory for generic names.
+ *
+ * \remark Simplified version of [NameFactory]
+ * (http://www.geoapi.org/3.0/javadoc/org/opengis/util/NameFactory.html) from
+ * \ref GeoAPI
+ */
+class NameFactory {
+ public:
+ PROJ_DLL static NameSpaceNNPtr
+ createNameSpace(const GenericNameNNPtr &name,
+ const PropertyMap &properties);
+ PROJ_DLL static LocalNameNNPtr createLocalName(const NameSpacePtr &scope,
+ const std::string &name);
+ PROJ_DLL static GenericNameNNPtr
+ createGenericName(const NameSpacePtr &scope,
+ const std::vector<std::string> &parsedNames);
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Abstract class to define an enumeration of values.
+ */
+class CodeList {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_DLL ~CodeList();
+ //! @endcond
+
+ /** Return the CodeList item as a string. */
+ // cppcheck-suppress functionStatic
+ inline const std::string &toString() PROJ_CONST_DECL { return name_; }
+
+ /** Return the CodeList item as a string. */
+ inline operator std::string() PROJ_CONST_DECL { return toString(); }
+
+ //! @cond Doxygen_Suppress
+ inline bool operator==(const CodeList &other) PROJ_CONST_DECL {
+ return name_ == other.name_;
+ }
+ inline bool operator!=(const CodeList &other) PROJ_CONST_DECL {
+ return name_ != other.name_;
+ }
+ //! @endcond
+ protected:
+ explicit CodeList(const std::string &nameIn) : name_(nameIn) {}
+ CodeList(const CodeList &other) = default;
+ CodeList &operator=(const CodeList &other);
+
+ private:
+ std::string name_{};
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Root exception class.
+ */
+class PROJ_GCC_DLL Exception : public std::exception {
+ std::string msg_;
+
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL explicit Exception(const char *message);
+ PROJ_INTERNAL explicit Exception(const std::string &message);
+ PROJ_DLL Exception(const Exception &other);
+ PROJ_DLL ~Exception() override;
+ //! @endcond
+ PROJ_DLL virtual const char *what() const noexcept override;
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Exception thrown when an invalid value type is set as the value of
+ * a key of a PropertyMap.
+ */
+class PROJ_GCC_DLL InvalidValueTypeException : public Exception {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL explicit InvalidValueTypeException(const char *message);
+ PROJ_INTERNAL explicit InvalidValueTypeException(
+ const std::string &message);
+ PROJ_DLL InvalidValueTypeException(const InvalidValueTypeException &other);
+ PROJ_DLL ~InvalidValueTypeException() override;
+ //! @endcond
+};
+
+// ---------------------------------------------------------------------------
+
+/** \brief Exception Thrown to indicate that the requested operation is not
+ * supported.
+ */
+class PROJ_GCC_DLL UnsupportedOperationException : public Exception {
+ public:
+ //! @cond Doxygen_Suppress
+ PROJ_INTERNAL explicit UnsupportedOperationException(const char *message);
+ PROJ_INTERNAL explicit UnsupportedOperationException(
+ const std::string &message);
+ PROJ_DLL
+ UnsupportedOperationException(const UnsupportedOperationException &other);
+ PROJ_DLL ~UnsupportedOperationException() override;
+ //! @endcond
+};
+
+} // namespace util
+
+NS_PROJ_END
+
+#endif // UTIL_HH_INCLUDED