diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-10-06 22:15:31 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2020-10-08 17:31:56 +0200 |
| commit | b5369cc79eccc625419d37bb97a5361731fd8f0f (patch) | |
| tree | 73bea46ce8b3daf40e65b538f4bc15149ac99756 /src | |
| parent | fece8a6c6e2e5eebeac6f9b4fc47ca830f2e3a3a (diff) | |
| download | PROJ-b5369cc79eccc625419d37bb97a5361731fd8f0f.tar.gz PROJ-b5369cc79eccc625419d37bb97a5361731fd8f0f.zip | |
Add a AuthorityFactory::createDatumEnsemble() method, and make it inherit from ObjectUsage
as mandated by ISO 19111:2019
Diffstat (limited to 'src')
| -rw-r--r-- | src/iso19111/datum.cpp | 3 | ||||
| -rw-r--r-- | src/iso19111/factory.cpp | 74 |
2 files changed, 71 insertions, 6 deletions
diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 83f615e9..d94d729c 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -1574,8 +1574,7 @@ DatumEnsemble::DatumEnsemble(const std::vector<DatumNNPtr> &datumsIn, #ifdef notdef DatumEnsemble::DatumEnsemble(const DatumEnsemble &other) - : common::IdentifiedObject(other), - d(internal::make_unique<Private>(*other.d)) {} + : common::ObjectUsage(other), d(internal::make_unique<Private>(*other.d)) {} #endif // --------------------------------------------------------------------------- diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 46657431..3895edb2 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -1604,9 +1604,9 @@ AuthorityFactory::CRSInfo::CRSInfo() util::BaseObjectNNPtr AuthorityFactory::createObject(const std::string &code) const { - auto res = d->runWithCodeParam( - "SELECT table_name FROM object_view WHERE auth_name = ? AND code = ?", - code); + auto res = d->runWithCodeParam("SELECT table_name, type FROM object_view " + "WHERE auth_name = ? AND code = ?", + code); if (res.empty()) { throw NoSuchAuthorityCodeException("not found", d->authority(), code); } @@ -1622,7 +1622,9 @@ AuthorityFactory::createObject(const std::string &code) const { } throw FactoryException(msg); } - const auto &table_name = res.front()[0]; + const auto &first_row = res.front(); + const auto &table_name = first_row[0]; + const auto &type = first_row[1]; if (table_name == "extent") { return util::nn_static_pointer_cast<util::BaseObject>( createExtent(code)); @@ -1640,10 +1642,18 @@ AuthorityFactory::createObject(const std::string &code) const { createEllipsoid(code)); } if (table_name == "geodetic_datum") { + if (type == "ensemble") { + return util::nn_static_pointer_cast<util::BaseObject>( + createDatumEnsemble(code, table_name)); + } return util::nn_static_pointer_cast<util::BaseObject>( createGeodeticDatum(code)); } if (table_name == "vertical_datum") { + if (type == "ensemble") { + return util::nn_static_pointer_cast<util::BaseObject>( + createDatumEnsemble(code, table_name)); + } return util::nn_static_pointer_cast<util::BaseObject>( createVerticalDatum(code)); } @@ -2093,6 +2103,62 @@ AuthorityFactory::createVerticalDatum(const std::string &code) const { // --------------------------------------------------------------------------- +/** \brief Returns a datum::DatumEnsemble from the specified code. + * + * @param code Object code allocated by authority. + * @param type "geodetic_datum", "vertical_datum" or empty string if unknown + * @return object. + * @throw NoSuchAuthorityCodeException + * @throw FactoryException + */ + +datum::DatumEnsembleNNPtr +AuthorityFactory::createDatumEnsemble(const std::string &code, + const std::string &type) const { + auto res = d->run( + "SELECT 'geodetic_datum', name, ensemble_accuracy, deprecated FROM " + "geodetic_datum WHERE " + "auth_name = ? AND code = ? AND ensemble_accuracy IS NOT NULL " + "UNION ALL " + "SELECT 'vertical_datum', name, ensemble_accuracy, deprecated FROM " + "vertical_datum WHERE " + "auth_name = ? AND code = ? AND ensemble_accuracy IS NOT NULL", + {d->authority(), code, d->authority(), code}); + if (res.empty()) { + throw NoSuchAuthorityCodeException("datum ensemble not found", + d->authority(), code); + } + for (const auto &row : res) { + const std::string &gotType = row[0]; + const std::string &name = row[1]; + const std::string &ensembleAccuracy = row[2]; + const bool deprecated = row[3] == "1"; + if (type.empty() || type == gotType) { + auto resMembers = + d->run("SELECT member_auth_name, member_code FROM " + gotType + + "_ensemble_member WHERE " + "ensemble_auth_name = ? AND ensemble_code = ? " + "ORDER BY sequence", + {d->authority(), code}); + + std::vector<datum::DatumNNPtr> members; + for (const auto &memberRow : resMembers) { + members.push_back( + d->createFactory(memberRow[0])->createDatum(memberRow[1])); + } + auto props = d->createPropertiesSearchUsages(gotType, code, name, + deprecated); + return datum::DatumEnsemble::create( + props, std::move(members), + metadata::PositionalAccuracy::create(ensembleAccuracy)); + } + } + throw NoSuchAuthorityCodeException("datum ensemble not found", + d->authority(), code); +} + +// --------------------------------------------------------------------------- + /** \brief Returns a datum::Datum from the specified code. * * @param code Object code allocated by authority. |
