aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-10-06 22:15:31 +0200
committerEven Rouault <even.rouault@spatialys.com>2020-10-08 17:31:56 +0200
commitb5369cc79eccc625419d37bb97a5361731fd8f0f (patch)
tree73bea46ce8b3daf40e65b538f4bc15149ac99756 /src
parentfece8a6c6e2e5eebeac6f9b4fc47ca830f2e3a3a (diff)
downloadPROJ-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.cpp3
-rw-r--r--src/iso19111/factory.cpp74
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.