diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-10-11 20:01:29 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2020-10-11 20:01:29 +0200 |
| commit | d1a0d95da549f7d32bcd8be408afe1fca62a6fb2 (patch) | |
| tree | aaaffe1812578ec5479c5fc413d47793cd1d5bcb | |
| parent | ad80dc88a70032e1d96812b574b2d4d22e223394 (diff) | |
| download | PROJ-d1a0d95da549f7d32bcd8be408afe1fca62a6fb2.tar.gz PROJ-d1a0d95da549f7d32bcd8be408afe1fca62a6fb2.zip | |
Database query: add AuthorityFactory::ObjectType::DYNAMIC_GEODETIC_REFERENCE_FRAME and DYNAMIC_VERTICAL_REFERENCE_FRAME, and make corresponding C API work
| -rw-r--r-- | include/proj/io.hpp | 4 | ||||
| -rw-r--r-- | src/iso19111/c_api.cpp | 12 | ||||
| -rw-r--r-- | src/iso19111/factory.cpp | 53 | ||||
| -rw-r--r-- | test/unit/test_c_api.cpp | 26 | ||||
| -rw-r--r-- | test/unit/test_factory.cpp | 40 |
5 files changed, 119 insertions, 16 deletions
diff --git a/include/proj/io.hpp b/include/proj/io.hpp index b4db0ef7..2b3c11b8 100644 --- a/include/proj/io.hpp +++ b/include/proj/io.hpp @@ -1022,6 +1022,10 @@ class PROJ_GCC_DLL AuthorityFactory { /** Object of type operation::ConcatenatedOperation (and derived classes) */ CONCATENATED_OPERATION, + /** Object of type datum::DynamicGeodeticReferenceFrame */ + DYNAMIC_GEODETIC_REFERENCE_FRAME, + /** Object of type datum::DynamicVerticalReferenceFrame */ + DYNAMIC_VERTICAL_REFERENCE_FRAME, }; PROJ_DLL std::set<std::string> diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index fb0a3af7..c152df88 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -898,15 +898,23 @@ convertPJObjectTypeToObjectType(PJ_TYPE type, bool &valid) { break; case PJ_TYPE_GEODETIC_REFERENCE_FRAME: - case PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME: cppType = AuthorityFactory::ObjectType::GEODETIC_REFERENCE_FRAME; break; + case PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME: + cppType = + AuthorityFactory::ObjectType::DYNAMIC_GEODETIC_REFERENCE_FRAME; + break; + case PJ_TYPE_VERTICAL_REFERENCE_FRAME: - case PJ_TYPE_DYNAMIC_VERTICAL_REFERENCE_FRAME: cppType = AuthorityFactory::ObjectType::VERTICAL_REFERENCE_FRAME; break; + case PJ_TYPE_DYNAMIC_VERTICAL_REFERENCE_FRAME: + cppType = + AuthorityFactory::ObjectType::DYNAMIC_VERTICAL_REFERENCE_FRAME; + break; + case PJ_TYPE_DATUM_ENSEMBLE: cppType = AuthorityFactory::ObjectType::DATUM; break; diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 473aa254..ef5c6e02 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -2101,14 +2101,15 @@ AuthorityFactory::createVerticalDatum(const std::string &code) const { props.set("PUBLICATION_DATE", publication_date); } auto anchor = util::optional<std::string>(); - return frame_reference_epoch.empty() - ? datum::VerticalReferenceFrame::create(props, anchor) - : datum::DynamicVerticalReferenceFrame::create( - props, anchor, - util::optional<datum::RealizationMethod>(), - common::Measure(c_locale_stod(frame_reference_epoch), - common::UnitOfMeasure::YEAR), - util::optional<std::string>()); + if (frame_reference_epoch.empty()) { + return datum::VerticalReferenceFrame::create(props, anchor); + } else { + return datum::DynamicVerticalReferenceFrame::create( + props, anchor, util::optional<datum::RealizationMethod>(), + common::Measure(c_locale_stod(frame_reference_epoch), + common::UnitOfMeasure::YEAR), + util::optional<std::string>()); + } } catch (const std::exception &ex) { throw buildFactoryException("vertical reference frame", code, ex); } @@ -5260,9 +5261,17 @@ AuthorityFactory::getAuthorityCodes(const ObjectType &type, case ObjectType::GEODETIC_REFERENCE_FRAME: sql = "SELECT code FROM geodetic_datum WHERE "; break; + case ObjectType::DYNAMIC_GEODETIC_REFERENCE_FRAME: + sql = "SELECT code FROM geodetic_datum WHERE " + "frame_reference_epoch IS NOT NULL AND "; + break; case ObjectType::VERTICAL_REFERENCE_FRAME: sql = "SELECT code FROM vertical_datum WHERE "; break; + case ObjectType::DYNAMIC_VERTICAL_REFERENCE_FRAME: + sql = "SELECT code FROM vertical_datum WHERE " + "frame_reference_epoch IS NOT NULL AND "; + break; case ObjectType::CRS: sql = "SELECT code FROM crs_view WHERE "; break; @@ -5742,10 +5751,18 @@ AuthorityFactory::createObjectsFromNameEx( res.emplace_back( TableType("geodetic_datum", std::string())); break; + case ObjectType::DYNAMIC_GEODETIC_REFERENCE_FRAME: + res.emplace_back( + TableType("geodetic_datum", "frame_reference_epoch")); + break; case ObjectType::VERTICAL_REFERENCE_FRAME: res.emplace_back( TableType("vertical_datum", std::string())); break; + case ObjectType::DYNAMIC_VERTICAL_REFERENCE_FRAME: + res.emplace_back( + TableType("vertical_datum", "frame_reference_epoch")); + break; case ObjectType::CRS: res.emplace_back(TableType("geodetic_crs", std::string())); res.emplace_back(TableType("projected_crs", std::string())); @@ -5824,9 +5841,13 @@ AuthorityFactory::createObjectsFromNameEx( sql += tableNameTypePair.first; sql += " WHERE 1 = 1 "; if (!tableNameTypePair.second.empty()) { - sql += "AND type = '"; - sql += tableNameTypePair.second; - sql += "' "; + if (tableNameTypePair.second == "frame_reference_epoch") { + sql += "AND frame_reference_epoch IS NOT NULL "; + } else { + sql += "AND type = '"; + sql += tableNameTypePair.second; + sql += "' "; + } } if (deprecated) { sql += "AND deprecated = 1 "; @@ -5854,9 +5875,13 @@ AuthorityFactory::createObjectsFromNameEx( sql += tableNameTypePair.first; sql += "' "; if (!tableNameTypePair.second.empty()) { - sql += "AND ov.type = '"; - sql += tableNameTypePair.second; - sql += "' "; + if (tableNameTypePair.second == "frame_reference_epoch") { + sql += "AND ov.frame_reference_epoch IS NOT NULL "; + } else { + sql += "AND ov.type = '"; + sql += tableNameTypePair.second; + sql += "' "; + } } if (deprecated) { sql += "AND ov.deprecated = 1 "; diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index bd59e2bf..c7053291 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -845,6 +845,24 @@ TEST_F(CApi, proj_create_from_database) { EXPECT_EQ(proj_get_type(datum), PJ_TYPE_GEODETIC_REFERENCE_FRAME); } { + // International Terrestrial Reference Frame 2008 + auto datum = proj_create_from_database( + m_ctxt, "EPSG", "1061", PJ_CATEGORY_DATUM, false, nullptr); + ASSERT_NE(datum, nullptr); + ObjectKeeper keeper(datum); + EXPECT_EQ(proj_get_type(datum), + PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME); + } + { + // Norway Normal Null 2000 + auto datum = proj_create_from_database( + m_ctxt, "EPSG", "1096", PJ_CATEGORY_DATUM, false, nullptr); + ASSERT_NE(datum, nullptr); + ObjectKeeper keeper(datum); + EXPECT_EQ(proj_get_type(datum), + PJ_TYPE_DYNAMIC_VERTICAL_REFERENCE_FRAME); + } + { auto op = proj_create_from_database(m_ctxt, "EPSG", "16031", PJ_CATEGORY_COORDINATE_OPERATION, false, nullptr); @@ -1197,6 +1215,14 @@ TEST_F(CApi, proj_get_codes_from_database) { } else { ASSERT_NE(list, nullptr) << type; ASSERT_NE(list[0], nullptr) << type; + if (type == PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME || + type == PJ_TYPE_DYNAMIC_VERTICAL_REFERENCE_FRAME) { + auto obj = proj_create_from_database( + m_ctxt, "EPSG", list[0], PJ_CATEGORY_DATUM, false, nullptr); + ASSERT_NE(obj, nullptr); + ObjectKeeper keeper(obj); + EXPECT_EQ(proj_get_type(obj), type) << type << " " << list[0]; + } } } } diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index 366e3d9b..2a9d2bd2 100644 --- a/test/unit/test_factory.cpp +++ b/test/unit/test_factory.cpp @@ -1337,11 +1337,29 @@ TEST(factory, AuthorityFactory_getAuthorityCodes) { ASSERT_TRUE(!setGeodeticDatum.empty()); factory->createGeodeticDatum(*(setGeodeticDatum.begin())); + auto setDynamicGeodeticDatum = factory->getAuthorityCodes( + AuthorityFactory::ObjectType::DYNAMIC_GEODETIC_REFERENCE_FRAME); + ASSERT_TRUE(!setDynamicGeodeticDatum.empty()); + auto dgrf = + factory->createGeodeticDatum(*(setDynamicGeodeticDatum.begin())); + EXPECT_TRUE(dynamic_cast<DynamicGeodeticReferenceFrame *>(dgrf.get()) != + nullptr); + EXPECT_LT(setDynamicGeodeticDatum.size(), setGeodeticDatum.size()); + auto setVerticalDatum = factory->getAuthorityCodes( AuthorityFactory::ObjectType::VERTICAL_REFERENCE_FRAME); ASSERT_TRUE(!setVerticalDatum.empty()); factory->createVerticalDatum(*(setVerticalDatum.begin())); + auto setDynamicVerticalDatum = factory->getAuthorityCodes( + AuthorityFactory::ObjectType::DYNAMIC_VERTICAL_REFERENCE_FRAME); + ASSERT_TRUE(!setDynamicVerticalDatum.empty()); + auto dvrf = + factory->createVerticalDatum(*(setDynamicVerticalDatum.begin())); + EXPECT_TRUE(dynamic_cast<DynamicVerticalReferenceFrame *>(dvrf.get()) != + nullptr); + EXPECT_LT(setDynamicVerticalDatum.size(), setVerticalDatum.size()); + std::set<std::string> setMerged; for (const auto &v : setGeodeticDatum) { setMerged.insert(v); @@ -3128,12 +3146,34 @@ TEST(factory, createObjectsFromName) { .size(), 1U); + // Dynamic Geodetic datum + EXPECT_EQ(factoryEPSG + ->createObjectsFromName( + "International Terrestrial Reference Frame 2008", + {AuthorityFactory::ObjectType:: + DYNAMIC_GEODETIC_REFERENCE_FRAME}, + false, 2) + .size(), + 1U); + + // Dynamic Vertical datum + EXPECT_EQ( + factoryEPSG + ->createObjectsFromName("Norway Normal Null 2000", + {AuthorityFactory::ObjectType:: + DYNAMIC_VERTICAL_REFERENCE_FRAME}, + false, 2) + .size(), + 1U); + const auto types = std::vector<AuthorityFactory::ObjectType>{ AuthorityFactory::ObjectType::PRIME_MERIDIAN, AuthorityFactory::ObjectType::ELLIPSOID, AuthorityFactory::ObjectType::DATUM, AuthorityFactory::ObjectType::GEODETIC_REFERENCE_FRAME, + AuthorityFactory::ObjectType::DYNAMIC_GEODETIC_REFERENCE_FRAME, AuthorityFactory::ObjectType::VERTICAL_REFERENCE_FRAME, + AuthorityFactory::ObjectType::DYNAMIC_VERTICAL_REFERENCE_FRAME, AuthorityFactory::ObjectType::CRS, AuthorityFactory::ObjectType::GEODETIC_CRS, AuthorityFactory::ObjectType::GEOCENTRIC_CRS, |
