aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-10-11 20:01:29 +0200
committerEven Rouault <even.rouault@spatialys.com>2020-10-11 20:01:29 +0200
commitd1a0d95da549f7d32bcd8be408afe1fca62a6fb2 (patch)
treeaaaffe1812578ec5479c5fc413d47793cd1d5bcb
parentad80dc88a70032e1d96812b574b2d4d22e223394 (diff)
downloadPROJ-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.hpp4
-rw-r--r--src/iso19111/c_api.cpp12
-rw-r--r--src/iso19111/factory.cpp53
-rw-r--r--test/unit/test_c_api.cpp26
-rw-r--r--test/unit/test_factory.cpp40
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,