1 /****************************************************************************** 2 * 3 * Project: PROJ 4 * Purpose: ISO19111:2019 implementation 5 * Author: Even Rouault <even dot rouault at spatialys dot com> 6 * 7 ****************************************************************************** 8 * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com> 9 * 10 * Permission is hereby granted, free of charge, to any person obtaining a 11 * copy of this software and associated documentation files (the "Software"), 12 * to deal in the Software without restriction, including without limitation 13 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 * and/or sell copies of the Software, and to permit persons to whom the 15 * Software is furnished to do so, subject to the following conditions: 16 * 17 * The above copyright notice and this permission notice shall be included 18 * in all copies or substantial portions of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 ****************************************************************************/ 28 29 #ifndef COMMON_HH_INCLUDED 30 #define COMMON_HH_INCLUDED 31 32 #include <memory> 33 #include <string> 34 #include <vector> 35 36 #include "io.hpp" 37 #include "metadata.hpp" 38 #include "util.hpp" 39 40 NS_PROJ_START 41 42 /** osgeo.proj.common namespace 43 * 44 * \brief Common classes. 45 */ 46 namespace common { 47 48 // --------------------------------------------------------------------------- 49 50 class UnitOfMeasure; 51 /** Shared pointer of UnitOfMeasure. */ 52 using UnitOfMeasurePtr = std::shared_ptr<UnitOfMeasure>; 53 /** Non-null shared pointer of UnitOfMeasure. */ 54 using UnitOfMeasureNNPtr = util::nn<UnitOfMeasurePtr>; 55 56 /** \brief Unit of measure. 57 * 58 * This is a mutable object. 59 */ 60 class PROJ_GCC_DLL UnitOfMeasure : public util::BaseObject { 61 public: 62 /** \brief Type of unit of measure. */ 63 enum class PROJ_MSVC_DLL Type { 64 /** Unknown unit of measure */ 65 UNKNOWN, 66 /** No unit of measure */ 67 NONE, 68 /** Angular unit of measure */ 69 ANGULAR, 70 /** Linear unit of measure */ 71 LINEAR, 72 /** Scale unit of measure */ 73 SCALE, 74 /** Time unit of measure */ 75 TIME, 76 /** Parametric unit of measure */ 77 PARAMETRIC, 78 }; 79 80 PROJ_DLL UnitOfMeasure(const std::string &nameIn = std::string(), 81 double toSIIn = 1.0, Type typeIn = Type::UNKNOWN, 82 const std::string &codeSpaceIn = std::string(), 83 const std::string &codeIn = std::string()); 84 85 //! @cond Doxygen_Suppress 86 PROJ_DLL UnitOfMeasure(const UnitOfMeasure &other); 87 PROJ_DLL ~UnitOfMeasure() override; 88 PROJ_DLL UnitOfMeasure &operator=(const UnitOfMeasure &other); 89 PROJ_INTERNAL static UnitOfMeasureNNPtr create(const UnitOfMeasure &other); 90 //! @endcond 91 92 PROJ_DLL const std::string &name() PROJ_PURE_DECL; 93 PROJ_DLL double conversionToSI() PROJ_PURE_DECL; 94 PROJ_DLL Type type() PROJ_PURE_DECL; 95 96 PROJ_DLL const std::string &codeSpace() PROJ_PURE_DECL; 97 PROJ_DLL const std::string &code() PROJ_PURE_DECL; 98 99 PROJ_DLL bool operator==(const UnitOfMeasure &other) PROJ_PURE_DECL; 100 PROJ_DLL bool operator!=(const UnitOfMeasure &other) PROJ_PURE_DECL; 101 102 //! @cond Doxygen_Suppress 103 PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter, 104 const std::string &unitType = std::string()) 105 const; // throw(io::FormattingException) 106 107 PROJ_INTERNAL void _exportToJSON( 108 io::JSONFormatter *formatter) const; // throw(io::FormattingException) 109 110 PROJ_INTERNAL std::string exportToPROJString() const; 111 112 PROJ_INTERNAL bool 113 _isEquivalentTo(const UnitOfMeasure &other, 114 util::IComparable::Criterion criterion = 115 util::IComparable::Criterion::STRICT) const; 116 117 //! @endcond 118 119 PROJ_DLL static const UnitOfMeasure NONE; 120 121 PROJ_DLL static const UnitOfMeasure SCALE_UNITY; 122 PROJ_DLL static const UnitOfMeasure PARTS_PER_MILLION; 123 PROJ_DLL static const UnitOfMeasure PPM_PER_YEAR; 124 125 PROJ_DLL static const UnitOfMeasure METRE; 126 PROJ_DLL static const UnitOfMeasure METRE_PER_YEAR; 127 128 PROJ_DLL static const UnitOfMeasure RADIAN; 129 PROJ_DLL static const UnitOfMeasure MICRORADIAN; 130 PROJ_DLL static const UnitOfMeasure DEGREE; 131 PROJ_DLL static const UnitOfMeasure ARC_SECOND; 132 PROJ_DLL static const UnitOfMeasure GRAD; 133 PROJ_DLL static const UnitOfMeasure ARC_SECOND_PER_YEAR; 134 135 PROJ_DLL static const UnitOfMeasure SECOND; 136 PROJ_DLL static const UnitOfMeasure YEAR; 137 138 private: 139 PROJ_OPAQUE_PRIVATE_DATA 140 }; 141 142 // --------------------------------------------------------------------------- 143 144 /** \brief Numeric value associated with a UnitOfMeasure. */ 145 class Measure : public util::BaseObject { 146 public: 147 PROJ_DLL Measure(double valueIn = 0.0, 148 const UnitOfMeasure &unitIn = UnitOfMeasure()); 149 150 //! @cond Doxygen_Suppress 151 PROJ_DLL Measure(const Measure &other); 152 PROJ_DLL ~Measure(); 153 //! @endcond 154 155 PROJ_DLL const UnitOfMeasure &unit() PROJ_PURE_DECL; 156 PROJ_DLL double getSIValue() PROJ_PURE_DECL; 157 PROJ_DLL double value() PROJ_PURE_DECL; 158 159 PROJ_DLL double 160 convertToUnit(const UnitOfMeasure &otherUnit) PROJ_PURE_DECL; 161 162 PROJ_DLL bool operator==(const Measure &other) PROJ_PURE_DECL; 163 164 /** Default maximum resulative error. */ 165 static constexpr double DEFAULT_MAX_REL_ERROR = 1e-10; 166 167 PROJ_INTERNAL bool 168 _isEquivalentTo(const Measure &other, 169 util::IComparable::Criterion criterion = 170 util::IComparable::Criterion::STRICT, 171 double maxRelativeError = DEFAULT_MAX_REL_ERROR) const; 172 173 private: 174 PROJ_OPAQUE_PRIVATE_DATA 175 Measure &operator=(const Measure &) = delete; 176 }; 177 178 // --------------------------------------------------------------------------- 179 180 /** \brief Numeric value, without a physical unit of measure. */ 181 class Scale : public Measure { 182 public: 183 PROJ_DLL explicit Scale(double valueIn = 0.0); 184 PROJ_DLL explicit Scale(double valueIn, const UnitOfMeasure &unitIn); 185 186 //! @cond Doxygen_Suppress Scale(const Measure & other)187 explicit Scale(const Measure &other) : Scale(other.value(), other.unit()) {} 188 PROJ_DLL Scale(const Scale &other); 189 PROJ_DLL ~Scale() override; 190 //! @endcond 191 192 protected: 193 PROJ_FRIEND_OPTIONAL(Scale); 194 Scale &operator=(const Scale &) = delete; 195 }; 196 197 // --------------------------------------------------------------------------- 198 199 /** \brief Numeric value, with a angular unit of measure. */ 200 class Angle : public Measure { 201 public: 202 PROJ_DLL explicit Angle(double valueIn = 0.0); 203 PROJ_DLL Angle(double valueIn, const UnitOfMeasure &unitIn); 204 205 //! @cond Doxygen_Suppress Angle(const Measure & other)206 explicit Angle(const Measure &other) : Angle(other.value(), other.unit()) {} 207 PROJ_DLL Angle(const Angle &other); 208 PROJ_DLL ~Angle() override; 209 //! @endcond 210 211 protected: 212 PROJ_FRIEND_OPTIONAL(Angle); 213 Angle &operator=(const Angle &) = delete; 214 }; 215 216 // --------------------------------------------------------------------------- 217 218 /** \brief Numeric value, with a linear unit of measure. */ 219 class Length : public Measure { 220 public: 221 PROJ_DLL explicit Length(double valueIn = 0.0); 222 PROJ_DLL Length(double valueIn, const UnitOfMeasure &unitIn); 223 224 //! @cond Doxygen_Suppress Length(const Measure & other)225 explicit Length(const Measure &other) 226 : Length(other.value(), other.unit()) {} 227 PROJ_DLL Length(const Length &other); 228 PROJ_DLL ~Length() override; 229 //! @endcond 230 231 protected: 232 PROJ_FRIEND_OPTIONAL(Length); 233 Length &operator=(const Length &) = delete; 234 }; 235 236 // --------------------------------------------------------------------------- 237 238 /** \brief Date-time value, as a ISO:8601 encoded string, or other string 239 * encoding */ 240 class DateTime { 241 public: 242 //! @cond Doxygen_Suppress 243 PROJ_DLL DateTime(const DateTime &other); 244 PROJ_DLL ~DateTime(); 245 //! @endcond 246 247 PROJ_DLL bool isISO_8601() const; 248 PROJ_DLL std::string toString() const; 249 250 PROJ_DLL static DateTime 251 create(const std::string &str); // may throw Exception 252 253 protected: 254 DateTime(); 255 PROJ_FRIEND_OPTIONAL(DateTime); 256 DateTime &operator=(const DateTime &other); 257 258 private: 259 explicit DateTime(const std::string &str); 260 261 PROJ_OPAQUE_PRIVATE_DATA 262 }; 263 264 // --------------------------------------------------------------------------- 265 266 /** \brief Data epoch */ 267 class DataEpoch { 268 public: 269 //! @cond Doxygen_Suppress 270 PROJ_DLL explicit DataEpoch(const Measure &coordinateEpochIn); 271 PROJ_DLL DataEpoch(const DataEpoch &other); 272 PROJ_DLL ~DataEpoch(); 273 //! @endcond 274 275 PROJ_DLL const Measure &coordinateEpoch() const; 276 277 protected: 278 DataEpoch(); 279 PROJ_FRIEND_OPTIONAL(DataEpoch); 280 281 private: 282 DataEpoch &operator=(const DataEpoch &other) = delete; 283 PROJ_OPAQUE_PRIVATE_DATA 284 }; 285 286 // --------------------------------------------------------------------------- 287 288 class IdentifiedObject; 289 /** Shared pointer of IdentifiedObject. */ 290 using IdentifiedObjectPtr = std::shared_ptr<IdentifiedObject>; 291 /** Non-null shared pointer of IdentifiedObject. */ 292 using IdentifiedObjectNNPtr = util::nn<IdentifiedObjectPtr>; 293 294 /** \brief Abstract class representating a CRS-related object that has an 295 * identification. 296 * 297 * \remark Implements IdentifiedObject from \ref ISO_19111_2019 298 */ 299 class PROJ_GCC_DLL IdentifiedObject : public util::BaseObject, 300 public util::IComparable, 301 public io::IWKTExportable { 302 public: 303 //! @cond Doxygen_Suppress 304 PROJ_DLL ~IdentifiedObject() override; 305 //! @endcond 306 307 PROJ_DLL static const std::string NAME_KEY; 308 PROJ_DLL static const std::string IDENTIFIERS_KEY; 309 PROJ_DLL static const std::string ALIAS_KEY; 310 PROJ_DLL static const std::string REMARKS_KEY; 311 PROJ_DLL static const std::string DEPRECATED_KEY; 312 313 // in practice only name().description() is used 314 PROJ_DLL const metadata::IdentifierNNPtr &name() PROJ_PURE_DECL; 315 PROJ_DLL const std::string &nameStr() PROJ_PURE_DECL; 316 PROJ_DLL const std::vector<metadata::IdentifierNNPtr> & 317 identifiers() PROJ_PURE_DECL; 318 PROJ_DLL const std::vector<util::GenericNameNNPtr> & 319 aliases() PROJ_PURE_DECL; 320 PROJ_DLL const std::string &remarks() PROJ_PURE_DECL; 321 322 // from Apache SIS AbstractIdentifiedObject 323 PROJ_DLL bool isDeprecated() PROJ_PURE_DECL; 324 325 // Non-standard 326 PROJ_DLL std::string alias() PROJ_PURE_DECL; 327 PROJ_DLL int getEPSGCode() PROJ_PURE_DECL; 328 329 PROJ_PRIVATE : 330 //! @cond Doxygen_Suppress 331 void 332 formatID(io::WKTFormatter *formatter) const; 333 334 PROJ_INTERNAL void formatID(io::JSONFormatter *formatter) const; 335 336 PROJ_INTERNAL void formatRemarks(io::WKTFormatter *formatter) const; 337 338 PROJ_INTERNAL void formatRemarks(io::JSONFormatter *formatter) const; 339 340 PROJ_INTERNAL bool _isEquivalentTo( 341 const util::IComparable *other, 342 util::IComparable::Criterion criterion = 343 util::IComparable::Criterion::STRICT, 344 const io::DatabaseContextPtr &dbContext = nullptr) const override; 345 346 PROJ_INTERNAL bool _isEquivalentTo( 347 const IdentifiedObject *other, util::IComparable::Criterion criterion = 348 util::IComparable::Criterion::STRICT, 349 const io::DatabaseContextPtr &dbContext = nullptr) PROJ_PURE_DECL; 350 //! @endcond 351 352 protected: 353 PROJ_FRIEND_OPTIONAL(IdentifiedObject); 354 INLINED_MAKE_SHARED 355 IdentifiedObject(); 356 IdentifiedObject(const IdentifiedObject &other); 357 358 void setProperties(const util::PropertyMap 359 &properties); // throw(InvalidValueTypeException) 360 361 virtual bool hasEquivalentNameToUsingAlias( 362 const IdentifiedObject *other, 363 const io::DatabaseContextPtr &dbContext) const; 364 365 private: 366 PROJ_OPAQUE_PRIVATE_DATA 367 IdentifiedObject &operator=(const IdentifiedObject &other) = delete; 368 }; 369 370 // --------------------------------------------------------------------------- 371 372 class ObjectDomain; 373 /** Shared pointer of ObjectDomain. */ 374 using ObjectDomainPtr = std::shared_ptr<ObjectDomain>; 375 /** Non-null shared pointer of ObjectDomain. */ 376 using ObjectDomainNNPtr = util::nn<ObjectDomainPtr>; 377 378 /** \brief The scope and validity of a CRS-related object. 379 * 380 * \remark Implements ObjectDomain from \ref ISO_19111_2019 381 */ 382 class PROJ_GCC_DLL ObjectDomain : public util::BaseObject, 383 public util::IComparable { 384 public: 385 //! @cond Doxygen_Suppress 386 PROJ_DLL ~ObjectDomain() override; 387 //! @endcond 388 389 // In ISO_19111:2018, scope and domain are compulsory, but in WKT2:2015, 390 // they 391 // are not necessarily both specified 392 PROJ_DLL const util::optional<std::string> &scope() PROJ_PURE_DECL; 393 PROJ_DLL const metadata::ExtentPtr &domainOfValidity() PROJ_PURE_DECL; 394 395 PROJ_DLL static ObjectDomainNNPtr 396 create(const util::optional<std::string> &scopeIn, 397 const metadata::ExtentPtr &extent); 398 399 PROJ_PRIVATE : 400 //! @cond Doxygen_Suppress 401 void 402 _exportToWKT(io::WKTFormatter *formatter) 403 const; // throw(io::FormattingException) 404 405 PROJ_INTERNAL void _exportToJSON( 406 io::JSONFormatter *formatter) const; // throw(FormattingException) 407 408 bool _isEquivalentTo( 409 const util::IComparable *other, 410 util::IComparable::Criterion criterion = 411 util::IComparable::Criterion::STRICT, 412 const io::DatabaseContextPtr &dbContext = nullptr) const override; 413 //! @endcond 414 415 protected: 416 //! @cond Doxygen_Suppress 417 ObjectDomain(const util::optional<std::string> &scopeIn, 418 const metadata::ExtentPtr &extent); 419 //! @endcond 420 421 ObjectDomain(const ObjectDomain &other); 422 INLINED_MAKE_SHARED 423 424 private: 425 PROJ_OPAQUE_PRIVATE_DATA 426 ObjectDomain &operator=(const ObjectDomain &other) = delete; 427 }; 428 429 // --------------------------------------------------------------------------- 430 431 class ObjectUsage; 432 /** Shared pointer of ObjectUsage. */ 433 using ObjectUsagePtr = std::shared_ptr<ObjectUsage>; 434 /** Non-null shared pointer of ObjectUsage. */ 435 using ObjectUsageNNPtr = util::nn<ObjectUsagePtr>; 436 437 /** \brief Abstract class of a CRS-related object that has usages. 438 * 439 * \remark Implements ObjectUsage from \ref ISO_19111_2019 440 */ 441 class PROJ_GCC_DLL ObjectUsage : public IdentifiedObject { 442 public: 443 //! @cond Doxygen_Suppress 444 PROJ_DLL ~ObjectUsage() override; 445 //! @endcond 446 447 PROJ_DLL const std::vector<ObjectDomainNNPtr> &domains() PROJ_PURE_DECL; 448 449 PROJ_DLL static const std::string SCOPE_KEY; 450 PROJ_DLL static const std::string DOMAIN_OF_VALIDITY_KEY; 451 452 PROJ_DLL static const std::string OBJECT_DOMAIN_KEY; 453 454 //! @cond Doxygen_Suppress 455 bool _isEquivalentTo( 456 const util::IComparable *other, 457 util::IComparable::Criterion criterion = 458 util::IComparable::Criterion::STRICT, 459 const io::DatabaseContextPtr &dbContext = nullptr) const override; 460 //! @endcond 461 462 protected: 463 ObjectUsage(); 464 ObjectUsage(const ObjectUsage &other); 465 void setProperties(const util::PropertyMap 466 &properties); // throw(InvalidValueTypeException) 467 468 void baseExportToWKT( 469 io::WKTFormatter *formatter) const; // throw(io::FormattingException) 470 471 void baseExportToJSON( 472 io::JSONFormatter *formatter) const; // throw(io::FormattingException) 473 474 private: 475 PROJ_OPAQUE_PRIVATE_DATA 476 ObjectUsage &operator=(const ObjectUsage &other) = delete; 477 }; 478 479 } // namespace common 480 481 NS_PROJ_END 482 483 #endif // COMMON_HH_INCLUDED 484