From 17a218964e8cb06f289d04b9698fa62cb8f31f22 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 28 Sep 2021 14:47:07 +0200 Subject: Database reading: implement reading a GeodeticCRS with a Spherical CS --- src/iso19111/factory.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/iso19111/factory.cpp') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index d5b0a22a..a898af6d 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -104,6 +104,7 @@ namespace io { #define GEOG_2D "geographic 2D" #define GEOG_3D "geographic 3D" #define GEOCENTRIC "geocentric" +#define OTHER "other" #define PROJECTED "projected" #define VERTICAL "vertical" #define COMPOUND "compound" @@ -4716,6 +4717,17 @@ AuthorityFactory::createCoordinateSystem(const std::string &code) const { } throw FactoryException("invalid number of axis for CartesianCS"); } + if (csType == "spherical") { + if (axisList.size() == 2) { + return cacheAndRet( + cs::SphericalCS::create(props, axisList[0], axisList[1])); + } + if (axisList.size() == 3) { + return cacheAndRet(cs::SphericalCS::create( + props, axisList[0], axisList[1], axisList[2])); + } + throw FactoryException("invalid number of axis for SphericalCS"); + } if (csType == "vertical") { if (axisList.size() == 1) { return cacheAndRet(cs::VerticalCS::create(props, axisList[0])); @@ -4869,6 +4881,7 @@ AuthorityFactory::createGeodeticCRS(const std::string &code, d->context()->d->cache(cacheKey, crsRet); return crsRet; } + auto geocentricCS = util::nn_dynamic_pointer_cast(cs); if (type == GEOCENTRIC && geocentricCS) { auto crsRet = crs::GeodeticCRS::create(props, datum, datumEnsemble, @@ -4876,6 +4889,15 @@ AuthorityFactory::createGeodeticCRS(const std::string &code, d->context()->d->cache(cacheKey, crsRet); return crsRet; } + + auto sphericalCS = util::nn_dynamic_pointer_cast(cs); + if (type == OTHER && sphericalCS) { + auto crsRet = crs::GeodeticCRS::create(props, datum, datumEnsemble, + NN_NO_CHECK(sphericalCS)); + d->context()->d->cache(cacheKey, crsRet); + return crsRet; + } + throw FactoryException("unsupported (type, CS type) for geodeticCRS: " + type + ", " + cs->getWKT2Type(true)); } catch (const std::exception &ex) { @@ -5354,7 +5376,8 @@ AuthorityFactory::createCoordinateReferenceSystem(const std::string &code, code); } const auto &type = res.front()[0]; - if (type == GEOG_2D || type == GEOG_3D || type == GEOCENTRIC) { + if (type == GEOG_2D || type == GEOG_3D || type == GEOCENTRIC || + type == OTHER) { return createGeodeticCRS(code); } if (type == VERTICAL) { -- cgit v1.2.3 From f386e22e3604b6268989a04a4749b5bc24b3a632 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 28 Sep 2021 14:47:07 +0200 Subject: AuthorityFactory::createGeodeticCRS(): use description column for remarks --- src/iso19111/factory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/iso19111/factory.cpp') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index a898af6d..6c81b5ff 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -4809,8 +4809,7 @@ AuthorityFactory::createGeodeticCRS(const std::string &code, } std::string sql("SELECT name, type, coordinate_system_auth_name, " "coordinate_system_code, datum_auth_name, datum_code, " - "text_definition, " - "deprecated FROM " + "text_definition, deprecated, description FROM " "geodetic_crs WHERE auth_name = ? AND code = ?"); if (geographicOnly) { sql += " AND type in (" GEOG_2D_SINGLE_QUOTED "," GEOG_3D_SINGLE_QUOTED @@ -4831,9 +4830,10 @@ AuthorityFactory::createGeodeticCRS(const std::string &code, const auto &datum_code = row[5]; const auto &text_definition = row[6]; const bool deprecated = row[7] == "1"; + const auto &remarks = row[8]; auto props = d->createPropertiesSearchUsages("geodetic_crs", code, name, - deprecated); + deprecated, remarks); if (!text_definition.empty()) { DatabaseContext::Private::RecursionDetector detector(d->context()); -- cgit v1.2.3 From f982d9d3104731727c445930bf14008d1c572d0a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 28 Sep 2021 14:47:08 +0200 Subject: Database: add IAU_2015 CRS --- src/iso19111/factory.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/iso19111/factory.cpp') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 6c81b5ff..94c2de2c 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -4209,7 +4209,11 @@ AuthorityFactory::identifyBodyFromSemiMajorAxis(double semi_major_axis, throw FactoryException("no match found"); } if (res.size() > 1) { - throw FactoryException("more than one match found"); + for (const auto &row : res) { + if (row[0] != res.front()[0]) { + throw FactoryException("more than one match found"); + } + } } return res.front()[0]; } -- cgit v1.2.3 From e6e6e4ca345e774910afa5bbe485c3d9f7851cd4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 28 Sep 2021 14:47:09 +0200 Subject: Add a mapping for versioned authorities, so that one can use IAU:xxxx or IAU_2015:xxxx transparently --- src/iso19111/factory.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) (limited to 'src/iso19111/factory.cpp') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 94c2de2c..f08e32b9 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -754,6 +754,14 @@ struct DatabaseContext::Private { // cppcheck-suppress functionStatic void cache(const std::string &code, const GridInfoCache &info); + struct VersionedAuthName { + std::string versionedAuthName{}; + std::string authName{}; + std::string version{}; + int priority = 0; + }; + const std::vector &getCacheAuthNameWithVersion(); + private: friend class DatabaseContext; @@ -795,6 +803,8 @@ struct DatabaseContext::Private { lru11::Cache> cacheAliasNames_{ CACHE_SIZE}; + std::vector cacheAuthNameWithVersion_{}; + static void insertIntoCache(LRUCacheOfObjects &cache, const std::string &code, const util::BaseObjectPtr &obj); @@ -3558,6 +3568,87 @@ DatabaseContext::getNonDeprecated(const std::string &tableName, // --------------------------------------------------------------------------- +const std::vector & +DatabaseContext::Private::getCacheAuthNameWithVersion() { + if (cacheAuthNameWithVersion_.empty()) { + const auto sqlRes = + run("SELECT versioned_auth_name, auth_name, version, priority " + "FROM versioned_auth_name_mapping"); + for (const auto &row : sqlRes) { + VersionedAuthName van; + van.versionedAuthName = row[0]; + van.authName = row[1]; + van.version = row[2]; + van.priority = atoi(row[3].c_str()); + cacheAuthNameWithVersion_.emplace_back(std::move(van)); + } + } + return cacheAuthNameWithVersion_; +} + +// --------------------------------------------------------------------------- + +// From IAU_2015 returns (IAU,2015) +bool DatabaseContext::getAuthorityAndVersion( + const std::string &versionedAuthName, std::string &authNameOut, + std::string &versionOut) { + + for (const auto &van : d->getCacheAuthNameWithVersion()) { + if (van.versionedAuthName == versionedAuthName) { + authNameOut = van.authName; + versionOut = van.version; + return true; + } + } + return false; +} + +// --------------------------------------------------------------------------- + +// From IAU and 2015, returns IAU_2015 +bool DatabaseContext::getVersionedAuthority(const std::string &authName, + const std::string &version, + std::string &versionedAuthNameOut) { + + for (const auto &van : d->getCacheAuthNameWithVersion()) { + if (van.authName == authName && van.version == version) { + versionedAuthNameOut = van.versionedAuthName; + return true; + } + } + return false; +} + +// --------------------------------------------------------------------------- + +// From IAU returns IAU_latest, ... IAU_2015 +std::vector +DatabaseContext::getVersionedAuthoritiesFromName(const std::string &authName) { + + typedef std::pair VersionedAuthNamePriority; + std::vector tmp; + for (const auto &van : d->getCacheAuthNameWithVersion()) { + if (van.authName == authName) { + tmp.emplace_back( + VersionedAuthNamePriority(van.versionedAuthName, van.priority)); + } + } + std::vector res; + if (!tmp.empty()) { + // Sort by decreasing priority + std::sort(tmp.begin(), tmp.end(), + [](const VersionedAuthNamePriority &a, + const VersionedAuthNamePriority &b) { + return b.second > a.second; + }); + for (const auto &pair : tmp) + res.emplace_back(pair.first); + } + return res; +} + +// --------------------------------------------------------------------------- + std::vector DatabaseContext::getTransformationsForGridName( const DatabaseContextNNPtr &databaseContext, const std::string &gridName) { -- cgit v1.2.3