/****************************************************************************** * * Project: PROJ * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** * Copyright (c) 2018, Even Rouault * * 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 #include #include #include #include #include #include "proj.h" #include "util.hpp" NS_PROJ_START class CPLJSonStreamingWriter; namespace common { class UnitOfMeasure; using UnitOfMeasurePtr = std::shared_ptr; using UnitOfMeasureNNPtr = util::nn; class IdentifiedObject; using IdentifiedObjectPtr = std::shared_ptr; using IdentifiedObjectNNPtr = util::nn; } // namespace common namespace cs { class CoordinateSystem; using CoordinateSystemPtr = std::shared_ptr; using CoordinateSystemNNPtr = util::nn; } // namespace cs namespace metadata { class Extent; using ExtentPtr = std::shared_ptr; using ExtentNNPtr = util::nn; } // namespace metadata namespace datum { class Datum; using DatumPtr = std::shared_ptr; using DatumNNPtr = util::nn; class DatumEnsemble; using DatumEnsemblePtr = std::shared_ptr; using DatumEnsembleNNPtr = util::nn; class Ellipsoid; using EllipsoidPtr = std::shared_ptr; using EllipsoidNNPtr = util::nn; class PrimeMeridian; using PrimeMeridianPtr = std::shared_ptr; using PrimeMeridianNNPtr = util::nn; class GeodeticReferenceFrame; using GeodeticReferenceFramePtr = std::shared_ptr; using GeodeticReferenceFrameNNPtr = util::nn; class VerticalReferenceFrame; using VerticalReferenceFramePtr = std::shared_ptr; using VerticalReferenceFrameNNPtr = util::nn; } // namespace datum namespace crs { class CRS; using CRSPtr = std::shared_ptr; using CRSNNPtr = util::nn; class GeodeticCRS; using GeodeticCRSPtr = std::shared_ptr; using GeodeticCRSNNPtr = util::nn; class GeographicCRS; using GeographicCRSPtr = std::shared_ptr; using GeographicCRSNNPtr = util::nn; class VerticalCRS; using VerticalCRSPtr = std::shared_ptr; using VerticalCRSNNPtr = util::nn; class ProjectedCRS; using ProjectedCRSPtr = std::shared_ptr; using ProjectedCRSNNPtr = util::nn; class CompoundCRS; using CompoundCRSPtr = std::shared_ptr; using CompoundCRSNNPtr = util::nn; } // namespace crs namespace operation { class Conversion; using ConversionPtr = std::shared_ptr; using ConversionNNPtr = util::nn; class CoordinateOperation; using CoordinateOperationPtr = std::shared_ptr; using CoordinateOperationNNPtr = util::nn; } // namespace operation /** osgeo.proj.io namespace. * * \brief I/O classes */ namespace io { class DatabaseContext; /** Shared pointer of DatabaseContext. */ using DatabaseContextPtr = std::shared_ptr; /** Non-null shared pointer of DatabaseContext. */ using DatabaseContextNNPtr = util::nn; // --------------------------------------------------------------------------- class WKTNode; /** Unique pointer of WKTNode. */ using WKTNodePtr = std::unique_ptr; /** Non-null unique pointer of WKTNode. */ using WKTNodeNNPtr = util::nn; // --------------------------------------------------------------------------- class WKTFormatter; /** WKTFormatter unique pointer. */ using WKTFormatterPtr = std::unique_ptr; /** Non-null WKTFormatter unique pointer. */ using WKTFormatterNNPtr = util::nn; /** \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: *
    *
  • UNIT keyword used.
  • *
  • ID node only on top element.
  • *
  • No ORDER element in AXIS element.
  • *
  • PRIMEM node omitted if it is Greenwich.
  • *
  • ELLIPSOID.UNIT node omitted if it is * UnitOfMeasure::METRE.
  • *
  • PARAMETER.UNIT / PRIMEM.UNIT omitted if same as AXIS.
  • *
  • AXIS.UNIT omitted and replaced by a common GEODCRS.UNIT if * they are all the same on all axis.
  • *
*/ WKT2_SIMPLIFIED, WKT2_2015_SIMPLIFIED = WKT2_SIMPLIFIED, /** Full WKT2 string, conforming to ISO 19162:2019 / OGC 18-010, with * (\ref WKT2_2019) all possible nodes and new keyword names. * Non-normative list of differences: *
    *
  • WKT2_2019 uses GEOGCRS / BASEGEOGCRS keywords for * GeographicCRS.
  • *
*/ WKT2_2019, /** Deprecated alias for WKT2_2019 */ WKT2_2018 = WKT2_2019, /** WKT2_2019 with the simplification rule of WKT2_SIMPLIFIED */ WKT2_2019_SIMPLIFIED, /** Deprecated alias for WKT2_2019_SIMPLIFIED */ WKT2_2018_SIMPLIFIED = WKT2_2019_SIMPLIFIED, /** WKT1 as traditionally output by GDAL, deriving from OGC 01-009. A notable departure 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; /** Rule for output AXIS nodes */ enum class OutputAxisRule { /** Always include AXIS nodes */ YES, /** Never include AXIS nodes */ NO, /** Includes them only on PROJCS node if it uses Easting/Northing *ordering. Typically used for WKT1_GDAL */ WKT1_GDAL_EPSG_STYLE, }; PROJ_DLL WKTFormatter &setOutputAxis(OutputAxisRule 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_INTERNAL bool isAtTopLevel() const; 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 pushHasId(bool hasId); PROJ_INTERNAL void popHasId(); PROJ_INTERNAL void pushDisableUsage(); PROJ_INTERNAL void popDisableUsage(); PROJ_INTERNAL bool outputUsage() 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 ¶ms); PROJ_INTERNAL const std::vector &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 OutputAxisRule 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; PROJ_INTERNAL bool idOnTopLevelOnly() const; PROJ_INTERNAL bool topLevelHasId() const; /** WKT version. */ enum class Version { /** WKT1 */ WKT1, /** WKT2 / ISO 19162 */ WKT2 }; PROJ_INTERNAL Version version() const; PROJ_INTERNAL bool use2019Keywords() const; PROJ_INTERNAL bool useESRIDialect() const; PROJ_INTERNAL const DatabaseContextPtr &databaseContext() const; PROJ_INTERNAL void ingestWKTNode(const WKTNodeNNPtr &node); PROJ_INTERNAL WKTFormatter & setAllowEllipsoidalHeightAsVerticalCRS(bool allow) noexcept; PROJ_INTERNAL bool isAllowedEllipsoidalHeightAsVerticalCRS() const noexcept; //! @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; /** Non-null PROJStringFormatter unique pointer. */ using PROJStringFormatterNNPtr = util::nn; /** \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 PROJStringFormatter &setMultiLine(bool multiLine) noexcept; PROJ_DLL PROJStringFormatter &setIndentationWidth(int width) noexcept; PROJ_DLL PROJStringFormatter &setMaxLineLength(int maxLineLength) noexcept; PROJ_DLL void setUseApproxTMerc(bool flag); PROJ_DLL const std::string &toString() const; PROJ_PRIVATE : //! @cond Doxygen_Suppress PROJ_DLL void setCRSExport(bool b); PROJ_INTERNAL bool getCRSExport() const; PROJ_DLL void startInversion(); PROJ_DLL void stopInversion(); PROJ_INTERNAL bool isInverted() const; PROJ_INTERNAL bool getUseApproxTMerc() const; PROJ_INTERNAL void setCoordinateOperationOptimizations(bool enable); 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 ¶mName); PROJ_DLL void addParam(const char *paramName, double val); PROJ_DLL void addParam(const std::string ¶mName, double val); PROJ_DLL void addParam(const char *paramName, int val); PROJ_DLL void addParam(const std::string ¶mName, 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 ¶mName, const char *val); PROJ_DLL void addParam(const std::string ¶mName, const std::string &val); PROJ_DLL void addParam(const char *paramName, const std::vector &vals); PROJ_INTERNAL bool hasParam(const char *paramName) const; PROJ_INTERNAL void addNoDefs(bool b); PROJ_INTERNAL bool getAddNoDefs() const; PROJ_INTERNAL std::set getUsedGridNames() const; PROJ_INTERNAL void setTOWGS84Parameters(const std::vector ¶ms); PROJ_INTERNAL const std::vector &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 pushOmitZUnitConversion(); PROJ_INTERNAL void popOmitZUnitConversion(); PROJ_INTERNAL bool omitZUnitConversion() const; PROJ_INTERNAL void pushOmitHorizontalConversionInVertTransformation(); PROJ_INTERNAL void popOmitHorizontalConversionInVertTransformation(); PROJ_INTERNAL bool omitHorizontalConversionInVertTransformation() const; PROJ_INTERNAL void setLegacyCRSToCRSContext(bool legacyContext); PROJ_INTERNAL bool getLegacyCRSToCRSContext() 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 }; // --------------------------------------------------------------------------- class JSONFormatter; /** JSONFormatter unique pointer. */ using JSONFormatterPtr = std::unique_ptr; /** Non-null JSONFormatter unique pointer. */ using JSONFormatterNNPtr = util::nn; /** \brief Formatter to JSON strings. * * An instance of this class can only be used by a single * thread at a time. */ class PROJ_GCC_DLL JSONFormatter { public: PROJ_DLL static JSONFormatterNNPtr create(DatabaseContextPtr dbContext = nullptr); //! @cond Doxygen_Suppress PROJ_DLL ~JSONFormatter(); //! @endcond PROJ_DLL JSONFormatter &setMultiLine(bool multiLine) noexcept; PROJ_DLL JSONFormatter &setIndentationWidth(int width) noexcept; PROJ_DLL JSONFormatter &setSchema(const std::string &schema) noexcept; PROJ_DLL const std::string &toString() const; PROJ_PRIVATE : //! @cond Doxygen_Suppress PROJ_INTERNAL CPLJSonStreamingWriter * writer() const; struct ObjectContext { JSONFormatter &m_formatter; ObjectContext(const ObjectContext &) = delete; ObjectContext(ObjectContext &&) = default; explicit ObjectContext(JSONFormatter &formatter, const char *objectType, bool hasId); ~ObjectContext(); }; PROJ_INTERNAL inline ObjectContext MakeObjectContext(const char *objectType, bool hasId) { return ObjectContext(*this, objectType, hasId); } PROJ_INTERNAL void setAllowIDInImmediateChild(); PROJ_INTERNAL void setOmitTypeInImmediateChild(); PROJ_INTERNAL void setAbridgedTransformation(bool abriged); PROJ_INTERNAL bool abridgedTransformation() const; // cppcheck-suppress functionStatic PROJ_INTERNAL bool outputId() const; PROJ_INTERNAL bool outputUsage() const; //! @endcond protected: //! @cond Doxygen_Suppress PROJ_INTERNAL explicit JSONFormatter(); JSONFormatter(const JSONFormatter &other) = delete; INLINED_MAKE_UNIQUE //! @endcond private: PROJ_OPAQUE_PRIVATE_DATA }; // --------------------------------------------------------------------------- /** \brief Interface for an object that can be exported to JSON. */ class PROJ_GCC_DLL IJSONExportable { public: //! @cond Doxygen_Suppress PROJ_DLL virtual ~IJSONExportable(); //! @endcond /** Builds a JSON representation. May throw a FormattingException */ PROJ_DLL std::string exportToJSON(JSONFormatter *formatter) const; // throw(FormattingException) PROJ_PRIVATE : //! @cond Doxygen_Suppress PROJ_INTERNAL virtual void _exportToJSON( JSONFormatter *formatter) const = 0; // throw(FormattingException) //! @endcond }; // --------------------------------------------------------------------------- /** \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; /** Non-null shared pointer of IPROJStringExportable. */ using IPROJStringExportableNNPtr = util::nn; /** \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. * *
    *
  • For PROJStringFormatter::Convention::PROJ_5 (the default), *
      *
    • For a crs::CRS, returns the same as * PROJStringFormatter::Convention::PROJ_4. It should be noted that the * export of a CRS as a PROJ string may cause loss of many important aspects * of a CRS definition. Consequently it is discouraged to use it for * interoperability in newer projects. The choice of a WKT representation * will be a better option.
    • *
    • For operation::CoordinateOperation, returns a PROJ * pipeline.
    • *
    * *
  • For PROJStringFormatter::Convention::PROJ_4, format a string * compatible with the OGRSpatialReference::exportToProj4() of GDAL * <=2.3. It is only compatible of a few CRS objects. The PROJ string * will also contain a +type=crs parameter to disambiguish the nature of * the string from a CoordinateOperation. *
      *
    • For a crs::GeographicCRS, returns a proj=longlat string, with * ellipsoid / datum / prime meridian information, ignoring axis order * and unit information.
    • *
    • For a geocentric crs::GeodeticCRS, returns the transformation from * geographic coordinates into geocentric coordinates.
    • *
    • For a crs::ProjectedCRS, returns the projection method, ignoring * axis order.
    • *
    • 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.
    • *
    *
  • * *
* * @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 }; // --------------------------------------------------------------------------- /** \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 &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, bool usePROJ4InitRules = false); PROJ_DLL util::BaseObjectNNPtr createFromUserInput(const std::string &text, PJ_CONTEXT *ctx); // --------------------------------------------------------------------------- /** \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::list warningList() const; PROJ_DLL util::BaseObjectNNPtr createFromWKT(const std::string &wkt); // throw(ParsingException) /** Guessed WKT "dialect" */ enum class PROJ_MSVC_DLL WKTGuessedDialect { /** \ref WKT2_2019 */ WKT2_2019, /** Deprecated alias for WKT2_2019 */ WKT2_2018 = WKT2_2019, /** \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 PROJStringParser &setUsePROJ4InitRules(bool enable); PROJ_DLL std::vector warningList() const; PROJ_DLL util::BaseObjectNNPtr createFromPROJString( const std::string &projString); // throw(ParsingException) PROJ_PRIVATE : //! @cond Doxygen_Suppress PROJStringParser & attachContext(PJ_CONTEXT *ctx); //! @endcond 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(const std::string &databasePath = std::string(), const std::vector &auxiliaryDatabasePaths = std::vector(), PJ_CONTEXT *ctx = nullptr); PROJ_DLL const std::string &getPath() const; PROJ_DLL const char *getMetadata(const char *key) const; PROJ_DLL std::set getAuthorities() const; PROJ_DLL std::vector getDatabaseStructure() const; PROJ_PRIVATE : //! @cond Doxygen_Suppress PROJ_DLL void * getSqliteHandle() const; PROJ_DLL static DatabaseContextNNPtr create(void *sqlite_handle); 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, bool considerKnownGridsAsAvailable, std::string &fullFilename, std::string &packageName, std::string &url, bool &directDownload, bool &openLicense, bool &gridAvailable) const; PROJ_INTERNAL std::string getProjGridName(const std::string &oldProjGridName); PROJ_INTERNAL std::string getOldProjGridName(const std::string &gridName); PROJ_INTERNAL std::string getAliasFromOfficialName(const std::string &officialName, const std::string &tableName, const std::string &source) const; PROJ_INTERNAL std::list getAliases(const std::string &authName, const std::string &code, 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; PROJ_INTERNAL std::string getTextDefinition(const std::string &tableName, const std::string &authName, const std::string &code) const; PROJ_INTERNAL std::vector getAllowedAuthorities(const std::string &sourceAuthName, const std::string &targetAuthName) const; PROJ_INTERNAL std::list> getNonDeprecated(const std::string &tableName, const std::string &authName, const std::string &code) const; PROJ_INTERNAL static std::vector getTransformationsForGridName(const DatabaseContextNNPtr &databaseContext, const std::string &gridName); //! @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; /** Non-null shared pointer of AuthorityFactory. */ using AuthorityFactoryNNPtr = util::nn; /** \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::DatumEnsembleNNPtr createDatumEnsemble(const std::string &code, const std::string &type = std::string()) 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 createFromCoordinateReferenceSystemCodes( const std::string &sourceCRSCode, const std::string &targetCRSCode) const; PROJ_DLL const std::string &getAuthority() PROJ_PURE_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, /** Object of type datum::DynamicGeodeticReferenceFrame */ DYNAMIC_GEODETIC_REFERENCE_FRAME, /** Object of type datum::DynamicVerticalReferenceFrame */ DYNAMIC_VERTICAL_REFERENCE_FRAME, }; PROJ_DLL std::set getAuthorityCodes(const ObjectType &type, bool allowDeprecated = true) const; PROJ_DLL std::string getDescriptionText(const std::string &code) const; // non-standard /** CRS information */ struct CRSInfo { /** Authority name */ std::string authName; /** Code */ std::string code; /** Name */ std::string name; /** Type */ ObjectType type; /** Whether the object is deprecated */ bool deprecated; /** Whereas the west_lon_degree, south_lat_degree, east_lon_degree and * north_lat_degree fields are valid. */ bool bbox_valid; /** Western-most longitude of the area of use, in degrees. */ double west_lon_degree; /** Southern-most latitude of the area of use, in degrees. */ double south_lat_degree; /** Eastern-most longitude of the area of use, in degrees. */ double east_lon_degree; /** Northern-most latitude of the area of use, in degrees. */ double north_lat_degree; /** Name of the area of use. */ std::string areaName; /** Name of the projection method for a projected CRS. Might be empty * even for projected CRS in some cases. */ std::string projectionMethodName; //! @cond Doxygen_Suppress CRSInfo(); //! @endcond }; PROJ_DLL std::list getCRSInfoList() const; /** Unit information */ struct UnitInfo { /** Authority name */ std::string authName; /** Code */ std::string code; /** Name */ std::string name; /** Category: one of "linear", "linear_per_time", "angular", * "angular_per_time", "scale", "scale_per_time" or "time" */ std::string category; /** Conversion factor to the SI unit. * It might be 0 in some cases to indicate no known conversion factor. */ double convFactor; /** PROJ short name (may be empty) */ std::string projShortName; /** Whether the object is deprecated */ bool deprecated; //! @cond Doxygen_Suppress UnitInfo(); //! @endcond }; PROJ_DLL std::list getUnitList() const; PROJ_DLL static AuthorityFactoryNNPtr create(const DatabaseContextNNPtr &context, const std::string &authorityName); PROJ_DLL const DatabaseContextNNPtr &databaseContext() const; PROJ_DLL std::vector createFromCoordinateReferenceSystemCodes( const std::string &sourceCRSAuthName, const std::string &sourceCRSCode, const std::string &targetCRSAuthName, const std::string &targetCRSCode, bool usePROJAlternativeGridNames, bool discardIfMissingGrid, bool considerKnownGridsAsAvailable, bool discardSuperseded, bool tryReverseOrder = false, bool reportOnlyIntersectingTransformations = false, const metadata::ExtentPtr &intersectingExtent1 = nullptr, const metadata::ExtentPtr &intersectingExtent2 = nullptr) const; PROJ_DLL std::vector createFromCRSCodesWithIntermediates( const std::string &sourceCRSAuthName, const std::string &sourceCRSCode, const std::string &targetCRSAuthName, const std::string &targetCRSCode, bool usePROJAlternativeGridNames, bool discardIfMissingGrid, bool considerKnownGridsAsAvailable, bool discardSuperseded, const std::vector> &intermediateCRSAuthCodes, ObjectType allowedIntermediateObjectType = ObjectType::CRS, const std::vector &allowedAuthorities = std::vector(), const metadata::ExtentPtr &intersectingExtent1 = nullptr, const metadata::ExtentPtr &intersectingExtent2 = nullptr) const; PROJ_DLL std::string getOfficialNameFromAlias( const std::string &aliasedName, const std::string &tableName, const std::string &source, bool tryEquivalentNameSpelling, std::string &outTableName, std::string &outAuthName, std::string &outCode) const; PROJ_DLL std::list createObjectsFromName(const std::string &name, const std::vector &allowedObjectTypes = std::vector(), bool approximateMatch = true, size_t limitResultCount = 0) const; PROJ_DLL std::list> listAreaOfUseFromName(const std::string &name, bool approximateMatch) const; PROJ_PRIVATE : //! @cond Doxygen_Suppress PROJ_INTERNAL std::list createEllipsoidFromExisting( const datum::EllipsoidNNPtr &ellipsoid) const; PROJ_INTERNAL std::list createGeodeticCRSFromDatum(const std::string &datum_auth_name, const std::string &datum_code, const std::string &geodetic_crs_type) const; PROJ_INTERNAL std::list createVerticalCRSFromDatum(const std::string &datum_auth_name, const std::string &datum_code) const; PROJ_INTERNAL std::list createGeodeticCRSFromEllipsoid(const std::string &ellipsoid_auth_name, const std::string &ellipsoid_code, const std::string &geodetic_crs_type) const; PROJ_INTERNAL std::list createProjectedCRSFromExisting(const crs::ProjectedCRSNNPtr &crs) const; PROJ_INTERNAL std::list createCompoundCRSFromExisting(const crs::CompoundCRSNNPtr &crs) const; PROJ_INTERNAL crs::CRSNNPtr createCoordinateReferenceSystem(const std::string &code, bool allowCompound) const; PROJ_INTERNAL std::vector getTransformationsForGeoid(const std::string &geoidName, bool usePROJAlternativeGridNames) const; PROJ_INTERNAL std::vector createBetweenGeodeticCRSWithDatumBasedIntermediates( const crs::CRSNNPtr &sourceCRS, const std::string &sourceCRSAuthName, const std::string &sourceCRSCode, const crs::CRSNNPtr &targetCRS, const std::string &targetCRSAuthName, const std::string &targetCRSCode, bool usePROJAlternativeGridNames, bool discardIfMissingGrid, bool considerKnownGridsAsAvailable, bool discardSuperseded, const std::vector &allowedAuthorities, const metadata::ExtentPtr &intersectingExtent1, const metadata::ExtentPtr &intersectingExtent2) const; typedef std::pair PairObjectName; PROJ_INTERNAL std::list createObjectsFromNameEx(const std::string &name, const std::vector &allowedObjectTypes = std::vector(), bool approximateMatch = true, size_t limitResultCount = 0) const; //! @endcond protected: PROJ_INTERNAL AuthorityFactory(const DatabaseContextNNPtr &context, const std::string &authorityName); 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 std::string &type) 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