aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/proj/datum.hpp5
-rw-r--r--scripts/reference_exported_symbols.txt1
-rw-r--r--src/iso19111/datum.cpp75
-rw-r--r--test/unit/test_datum.cpp11
-rw-r--r--test/unit/test_factory.cpp34
5 files changed, 119 insertions, 7 deletions
diff --git a/include/proj/datum.hpp b/include/proj/datum.hpp
index 35b8576e..bf3dbcb7 100644
--- a/include/proj/datum.hpp
+++ b/include/proj/datum.hpp
@@ -147,7 +147,10 @@ class PROJ_GCC_DLL DatumEnsemble final : public common::ObjectUsage,
PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
const override; // throw(io::FormattingException)
- //! @endcond
+
+ PROJ_FOR_TEST DatumNNPtr
+ asDatum(const io::DatabaseContextPtr &dbContext) const;
+ //! @endcond
protected:
#ifdef DOXYGEN_ENABLED
diff --git a/scripts/reference_exported_symbols.txt b/scripts/reference_exported_symbols.txt
index d864030a..f37dde16 100644
--- a/scripts/reference_exported_symbols.txt
+++ b/scripts/reference_exported_symbols.txt
@@ -234,6 +234,7 @@ osgeo::proj::cs::VerticalCS::~VerticalCS()
osgeo::proj::datum::Datum::anchorDefinition() const
osgeo::proj::datum::Datum::conventionalRS() const
osgeo::proj::datum::Datum::~Datum()
+osgeo::proj::datum::DatumEnsemble::asDatum(std::shared_ptr<osgeo::proj::io::DatabaseContext> const&) const
osgeo::proj::datum::DatumEnsemble::create(osgeo::proj::util::PropertyMap const&, std::vector<dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::datum::Datum> >, std::allocator<dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::datum::Datum> > > > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::metadata::PositionalAccuracy> > const&)
osgeo::proj::datum::DatumEnsemble::~DatumEnsemble()
osgeo::proj::datum::DatumEnsemble::datums() const
diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp
index d94d729c..9ec9fb62 100644
--- a/src/iso19111/datum.cpp
+++ b/src/iso19111/datum.cpp
@@ -1613,16 +1613,83 @@ DatumEnsemble::positionalAccuracy() const {
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+DatumNNPtr
+DatumEnsemble::asDatum(const io::DatabaseContextPtr &dbContext) const {
+
+ const auto &l_datums = datums();
+ auto *grf = dynamic_cast<const GeodeticReferenceFrame *>(l_datums[0].get());
+
+ const auto &l_identifiers = identifiers();
+ if (dbContext) {
+ if (!l_identifiers.empty()) {
+ const auto &id = l_identifiers[0];
+ try {
+ auto factory = io::AuthorityFactory::create(
+ NN_NO_CHECK(dbContext), *(id->codeSpace()));
+ if (grf) {
+ return factory->createGeodeticDatum(id->code());
+ } else {
+ return factory->createVerticalDatum(id->code());
+ }
+ } catch (const std::exception &) {
+ }
+ }
+ }
+
+ std::string l_name(nameStr());
+ if (grf) {
+ // Remap to traditional datum names
+ if (l_name == "World Geodetic System 1984 ensemble") {
+ l_name = "World Geodetic System 1984";
+ } else if (l_name ==
+ "European Terrestrial Reference System 1989 ensemble") {
+ l_name = "European Terrestrial Reference System 1989";
+ }
+ }
+ auto props =
+ util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, l_name);
+ if (isDeprecated()) {
+ props.set(common::IdentifiedObject::DEPRECATED_KEY, true);
+ }
+ if (!l_identifiers.empty()) {
+ const auto &id = l_identifiers[0];
+ props.set(metadata::Identifier::CODESPACE_KEY, *(id->codeSpace()))
+ .set(metadata::Identifier::CODE_KEY, id->code());
+ }
+ const auto &l_usages = domains();
+ if (!l_usages.empty()) {
+
+ auto array(util::ArrayOfBaseObject::create());
+ for (const auto &usage : l_usages) {
+ array->add(usage);
+ }
+ props.set(common::ObjectUsage::OBJECT_DOMAIN_KEY,
+ util::nn_static_pointer_cast<util::BaseObject>(array));
+ }
+ const auto anchor = util::optional<std::string>();
+
+ if (grf) {
+ return GeodeticReferenceFrame::create(props, grf->ellipsoid(), anchor,
+ grf->primeMeridian());
+ } else {
+ assert(dynamic_cast<VerticalReferenceFrame *>(l_datums[0].get()));
+ return datum::VerticalReferenceFrame::create(props, anchor);
+ }
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
void DatumEnsemble::_exportToWKT(
io::WKTFormatter *formatter) const // throw(FormattingException)
{
const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2;
if (!isWKT2 || !formatter->use2019Keywords()) {
- throw io::FormattingException(
- "DatumEnsemble can only be exported to WKT2:2019");
+ return asDatum(formatter->databaseContext())->_exportToWKT(formatter);
}
- auto l_datums = datums();
+ const auto &l_datums = datums();
assert(!l_datums.empty());
formatter->startNode(io::WKTConstants::ENSEMBLE, false);
@@ -1679,7 +1746,7 @@ void DatumEnsemble::_exportToJSON(
writer->Add(l_name);
}
- auto l_datums = datums();
+ const auto &l_datums = datums();
writer->AddObjKey("members");
{
auto membersContext(writer->MakeArrayContext(false));
diff --git a/test/unit/test_datum.cpp b/test/unit/test_datum.cpp
index adf0ae4b..26098d5c 100644
--- a/test/unit/test_datum.cpp
+++ b/test/unit/test_datum.cpp
@@ -409,8 +409,7 @@ TEST(datum, datum_ensemble) {
PositionalAccuracy::create("100"));
EXPECT_EQ(ensemble->datums().size(), 2U);
EXPECT_EQ(ensemble->positionalAccuracy()->value(), "100");
- EXPECT_THROW(ensemble->exportToWKT(WKTFormatter::create().get()),
- FormattingException);
+
EXPECT_EQ(
ensemble->exportToWKT(
WKTFormatter::create(WKTFormatter::Convention::WKT2_2019).get()),
@@ -422,6 +421,14 @@ TEST(datum, datum_ensemble) {
" LENGTHUNIT[\"metre\",1],\n"
" ID[\"EPSG\",7030]],\n"
" ENSEMBLEACCURACY[100]]");
+
+ EXPECT_EQ(
+ ensemble->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT2_2015).get()),
+ "DATUM[\"test\",\n"
+ " ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n"
+ " LENGTHUNIT[\"metre\",1],\n"
+ " ID[\"EPSG\",7030]]]");
}
// ---------------------------------------------------------------------------
diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp
index 6b87fba6..b17a3077 100644
--- a/test/unit/test_factory.cpp
+++ b/test/unit/test_factory.cpp
@@ -334,6 +334,24 @@ TEST(factory, AuthorityFactory_createDatumEnsembleGeodetic) {
auto extent = domain->domainOfValidity();
ASSERT_TRUE(extent != nullptr);
EXPECT_TRUE(extent->isEquivalentTo(factory->createExtent("1262").get()));
+
+ {
+ // Without using db
+ auto datum = ensemble->asDatum(nullptr);
+ EXPECT_EQ(datum->nameStr(), "World Geodetic System 1984");
+ auto grf = dynamic_cast<GeodeticReferenceFrame *>(datum.get());
+ ASSERT_TRUE(grf != nullptr);
+ EXPECT_TRUE(grf->isEquivalentTo(factory->createDatum("6326").get()));
+ }
+
+ {
+ // Using db
+ auto datum = ensemble->asDatum(DatabaseContext::create());
+ EXPECT_EQ(datum->nameStr(), "World Geodetic System 1984");
+ auto grf = dynamic_cast<GeodeticReferenceFrame *>(datum.get());
+ ASSERT_TRUE(grf != nullptr);
+ EXPECT_TRUE(grf->isEquivalentTo(factory->createDatum("6326").get()));
+ }
}
// ---------------------------------------------------------------------------
@@ -354,6 +372,22 @@ TEST(factory, AuthorityFactory_createDatumEnsembleVertical) {
auto extent = domain->domainOfValidity();
ASSERT_TRUE(extent != nullptr);
EXPECT_TRUE(extent->isEquivalentTo(factory->createExtent("4606").get()));
+
+ {
+ // Without using db
+ auto datum = ensemble->asDatum(nullptr);
+ auto vrf = dynamic_cast<VerticalReferenceFrame *>(datum.get());
+ ASSERT_TRUE(vrf != nullptr);
+ EXPECT_TRUE(vrf->isEquivalentTo(factory->createDatum("1288").get()));
+ }
+
+ {
+ // Using db
+ auto datum = ensemble->asDatum(DatabaseContext::create());
+ auto vrf = dynamic_cast<VerticalReferenceFrame *>(datum.get());
+ ASSERT_TRUE(vrf != nullptr);
+ EXPECT_TRUE(vrf->isEquivalentTo(factory->createDatum("1288").get()));
+ }
}
// ---------------------------------------------------------------------------