diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-10-06 23:48:46 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2020-10-08 17:31:56 +0200 |
| commit | 9dc3bf503b0455526a4d180930f8414621ea6187 (patch) | |
| tree | 853db7b562f76ba86a17ef627f7b7edacab24146 | |
| parent | b5369cc79eccc625419d37bb97a5361731fd8f0f (diff) | |
| download | PROJ-9dc3bf503b0455526a4d180930f8414621ea6187.tar.gz PROJ-9dc3bf503b0455526a4d180930f8414621ea6187.zip | |
Add DatumEnsemble::asDatum() and use it in exportToWkt()
to allow exporting DatumEnsemble to WKT < 2019.
| -rw-r--r-- | include/proj/datum.hpp | 5 | ||||
| -rw-r--r-- | scripts/reference_exported_symbols.txt | 1 | ||||
| -rw-r--r-- | src/iso19111/datum.cpp | 75 | ||||
| -rw-r--r-- | test/unit/test_datum.cpp | 11 | ||||
| -rw-r--r-- | test/unit/test_factory.cpp | 34 |
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())); + } } // --------------------------------------------------------------------------- |
