aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-11-30 18:37:12 +0100
committerEven Rouault <even.rouault@spatialys.com>2018-12-01 17:36:29 +0100
commit9d19d5578705e06990fb716adcb9e6a1529424aa (patch)
treee2bba1f4f1f07d61ea1b18638bd07e02c9b3b996
parentb6a5c445e202e61c64b0986679a6e0a83724c322 (diff)
downloadPROJ-9d19d5578705e06990fb716adcb9e6a1529424aa.tar.gz
PROJ-9d19d5578705e06990fb716adcb9e6a1529424aa.zip
importFromWKT: morph GDAL_WKT1 datum names into their EPSG spelling
-rw-r--r--src/c_api.cpp48
-rw-r--r--src/io.cpp31
-rw-r--r--test/unit/test_c_api.cpp57
-rw-r--r--test/unit/test_io.cpp27
4 files changed, 156 insertions, 7 deletions
diff --git a/src/c_api.cpp b/src/c_api.cpp
index a0dbecc2..30365297 100644
--- a/src/c_api.cpp
+++ b/src/c_api.cpp
@@ -409,8 +409,13 @@ PJ_OBJ *proj_obj_create_from_wkt(PJ_CONTEXT *ctx, const char *wkt,
assert(wkt);
(void)options;
try {
+ WKTParser parser;
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
+ if (dbContext) {
+ parser.attachDatabaseContext(NN_NO_CHECK(dbContext));
+ }
auto identifiedObject = nn_dynamic_pointer_cast<IdentifiedObject>(
- WKTParser().createFromWKT(wkt));
+ parser.createFromWKT(wkt));
if (identifiedObject) {
return PJ_OBJ::create(NN_NO_CHECK(identifiedObject));
}
@@ -442,8 +447,13 @@ PJ_OBJ *proj_obj_create_from_proj_string(PJ_CONTEXT *ctx,
(void)options;
assert(proj_string);
try {
+ PROJStringParser parser;
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
+ if (dbContext) {
+ parser.attachDatabaseContext(NN_NO_CHECK(dbContext));
+ }
auto identifiedObject = nn_dynamic_pointer_cast<IdentifiedObject>(
- PROJStringParser().createFromPROJString(proj_string));
+ parser.createFromPROJString(proj_string));
if (identifiedObject) {
return PJ_OBJ::create(NN_NO_CHECK(identifiedObject));
}
@@ -961,7 +971,8 @@ const char *proj_obj_as_wkt(PJ_CONTEXT *ctx, const PJ_OBJ *obj,
const WKTFormatter::Convention convention =
static_cast<WKTFormatter::Convention>(type);
try {
- auto formatter = WKTFormatter::create(convention);
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
+ auto formatter = WKTFormatter::create(convention, dbContext);
for (auto iter = options; iter && iter[0]; ++iter) {
const char *value;
if ((value = getOptionValue(*iter, "MULTILINE="))) {
@@ -1827,7 +1838,7 @@ static GeodeticReferenceFrameNNPtr createGeodeticReferenceFrame(
const char *angular_units, double angular_units_conv) {
const UnitOfMeasure angUnit(
createAngularUnit(angular_units, angular_units_conv));
- auto dbContext = getDBcontext(ctx);
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
auto body = Ellipsoid::guessBodyName(dbContext, semi_major_metre);
auto ellpsName = createPropertyMapName(ellps_name);
auto ellps = inv_flattening != 0.0
@@ -1847,9 +1858,32 @@ static GeodeticReferenceFrameNNPtr createGeodeticReferenceFrame(
: "Reference meridian")
: "unnamed"),
Angle(prime_meridian_offset, angUnit));
- return GeodeticReferenceFrame::create(createPropertyMapName(datum_name),
- ellps, util::optional<std::string>(),
- pm);
+
+ std::string datumName(datum_name ? datum_name : "unnamed");
+ if (datumName == "WGS_1984") {
+ datumName = GeodeticReferenceFrame::EPSG_6326->nameStr();
+ } else if (datumName.find('_') != std::string::npos) {
+ // Likely coming from WKT1
+ if (dbContext) {
+ auto authFactory =
+ AuthorityFactory::create(NN_NO_CHECK(dbContext), std::string());
+ auto res = authFactory->createObjectsFromName(
+ datumName,
+ {AuthorityFactory::ObjectType::GEODETIC_REFERENCE_FRAME}, true,
+ 1);
+ if (!res.empty()) {
+ const auto &refDatum = res.front();
+ if (metadata::Identifier::isEquivalentName(
+ datumName.c_str(), refDatum->nameStr().c_str())) {
+ datumName = refDatum->nameStr();
+ }
+ }
+ }
+ }
+
+ return GeodeticReferenceFrame::create(
+ createPropertyMapName(datumName.c_str()), ellps,
+ util::optional<std::string>(), pm);
}
//! @endcond
diff --git a/src/io.cpp b/src/io.cpp
index 3a980993..29417c73 100644
--- a/src/io.cpp
+++ b/src/io.cpp
@@ -1925,6 +1925,37 @@ GeodeticReferenceFrameNNPtr WKTParser::Private::buildGeodeticReferenceFrame(
.set(Identifier::AUTHORITY_KEY, authNameFromAlias)));
properties.set(IdentifiedObject::IDENTIFIERS_KEY, identifiers);
}
+ } else if (name.find('_') != std::string::npos) {
+ // Likely coming from WKT1
+ if (dbContext_) {
+ auto authFactory = AuthorityFactory::create(NN_NO_CHECK(dbContext_),
+ std::string());
+ auto res = authFactory->createObjectsFromName(
+ name, {AuthorityFactory::ObjectType::GEODETIC_REFERENCE_FRAME},
+ true, 1);
+ if (!res.empty()) {
+ const auto &refDatum = res.front();
+ if (metadata::Identifier::isEquivalentName(
+ name.c_str(), refDatum->nameStr().c_str())) {
+ properties.set(IdentifiedObject::NAME_KEY,
+ refDatum->nameStr());
+ if (properties.find(Identifier::CODESPACE_KEY) ==
+ properties.end() &&
+ refDatum->identifiers().size() == 1) {
+ const auto &id = refDatum->identifiers()[0];
+ auto identifiers = ArrayOfBaseObject::create();
+ identifiers->add(Identifier::create(
+ id->code(), PropertyMap()
+ .set(Identifier::CODESPACE_KEY,
+ *id->codeSpace())
+ .set(Identifier::AUTHORITY_KEY,
+ *id->codeSpace())));
+ properties.set(IdentifiedObject::IDENTIFIERS_KEY,
+ identifiers);
+ }
+ }
+ }
+ }
}
auto ellipsoid = buildEllipsoid(ellipsoidNode);
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index 59ba12ca..855ebf36 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -292,6 +292,25 @@ TEST_F(CApi, proj_obj_as_wkt) {
// ---------------------------------------------------------------------------
+TEST_F(CApi, proj_obj_as_wkt_check_db_use) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, "GEOGCS[\"AGD66\",DATUM[\"Australian_Geodetic_Datum_1966\","
+ "SPHEROID[\"Australian National Spheroid\",6378160,298.25]],"
+ "PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]]",
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT1_ESRI, nullptr);
+ EXPECT_EQ(std::string(wkt),
+ "GEOGCS[\"GCS_Australian_1966\",DATUM[\"D_Australian_1966\","
+ "SPHEROID[\"Australian\",6378160.0,298.25]],"
+ "PRIMEM[\"Greenwich\",0.0],"
+ "UNIT[\"Degree\",0.0174532925199433]]");
+}
+
+// ---------------------------------------------------------------------------
+
TEST_F(CApi, proj_obj_as_wkt_incompatible_WKT1) {
auto obj = proj_obj_create_from_wkt(
m_ctxt,
@@ -1547,6 +1566,44 @@ TEST_F(CApi, proj_obj_create_geographic_crs) {
ObjectKeeper keeper(obj);
ASSERT_NE(obj, nullptr);
}
+
+ // Datum with GDAL_WKT1 spelling: special case of WGS_1984
+ {
+ auto obj = proj_obj_create_geographic_crs(
+ m_ctxt, "WGS 84", "WGS_1984", "WGS 84", 6378137, 298.257223563,
+ "Greenwich", 0.0, "Degree", 0.0174532925199433, cs);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto objRef = proj_obj_create_from_user_input(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeperobjRef(objRef);
+ EXPECT_NE(objRef, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(obj, objRef, PJ_COMP_EQUIVALENT));
+ }
+
+ // Datum with GDAL_WKT1 spelling: database query
+ {
+ auto obj = proj_obj_create_geographic_crs(
+ m_ctxt, "NAD83", "North_American_Datum_1983", "GRS 1980", 6378137,
+ 298.257222101, "Greenwich", 0.0, "Degree", 0.0174532925199433, cs);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto objRef = proj_obj_create_from_user_input(
+ m_ctxt,
+ GeographicCRS::EPSG_4269->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeperobjRef(objRef);
+ EXPECT_NE(objRef, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(obj, objRef, PJ_COMP_EQUIVALENT));
+ }
}
// ---------------------------------------------------------------------------
diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp
index 0cf36766..6a2de028 100644
--- a/test/unit/test_io.cpp
+++ b/test/unit/test_io.cpp
@@ -401,6 +401,33 @@ TEST(wkt_parse, wkt1_EPSG_4326) {
// ---------------------------------------------------------------------------
+TEST(wkt_parse, wkt1_EPSG_4267) {
+ auto obj =
+ WKTParser()
+ .attachDatabaseContext(DatabaseContext::create())
+ .createFromWKT(
+ "GEOGCS[\"NAD27\","
+ " DATUM[\"North_American_Datum_1927\","
+ " SPHEROID[\"Clarke 1866\",6378206.4,294.978698213898,"
+ " AUTHORITY[\"EPSG\",\"7008\"]],"
+ " AUTHORITY[\"EPSG\",\"6267\"]],"
+ " PRIMEM[\"Greenwich\",0,"
+ " AUTHORITY[\"EPSG\",\"8901\"]],"
+ " UNIT[\"degree\",0.0174532925199433,"
+ " AUTHORITY[\"EPSG\",\"9122\"]],"
+ " AUTHORITY[\"EPSG\",\"4267\"]]");
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ auto datum = crs->datum();
+ ASSERT_EQ(datum->identifiers().size(), 1);
+ EXPECT_EQ(datum->identifiers()[0]->code(), "6267");
+ EXPECT_EQ(*(datum->identifiers()[0]->codeSpace()), "EPSG");
+ EXPECT_EQ(datum->nameStr(), "North American Datum 1927");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(wkt_parse, wkt1_EPSG_4807_grad_mess) {
auto obj = WKTParser().createFromWKT(
"GEOGCS[\"NTF (Paris)\",\n"