diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-11-18 19:43:24 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-11-18 19:43:24 +0100 |
| commit | 70aae0fe4262686d61289c3b710a4877c43e6c13 (patch) | |
| tree | 494e74785876827c41c5872997509c338db2e8c6 | |
| parent | 7553b219dce6a7d2a0381abfef171b5b4f15c29e (diff) | |
| download | PROJ-70aae0fe4262686d61289c3b710a4877c43e6c13.tar.gz PROJ-70aae0fe4262686d61289c3b710a4877c43e6c13.zip | |
createOperations(): geocentric to geocentric operation synthetization: distinguish null transform from ballpark transform
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 40 | ||||
| -rw-r--r-- | test/unit/test_operation.cpp | 30 |
2 files changed, 61 insertions, 9 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 937ba34f..8ac94a8e 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -115,6 +115,7 @@ static const std::string INVERSE_OF = "Inverse of "; static const char *BALLPARK_GEOCENTRIC_TRANSLATION = "Ballpark geocentric translation"; static const char *NULL_GEOGRAPHIC_OFFSET = "Null geographic offset"; +static const char *NULL_GEOCENTRIC_TRANSLATION = "Null geocentric translation"; static const char *BALLPARK_GEOGRAPHIC_OFFSET = "Ballpark geographic offset"; static const char *BALLPARK_VERTICAL_TRANSFORMATION_PREFIX = " (ballpark vertical transformation"; @@ -7587,6 +7588,8 @@ createPropertiesForInverse(const CoordinateOperation *op, bool derivedFrom, opType = BALLPARK_GEOGRAPHIC_OFFSET; } else if (starts_with(forwardName, NULL_GEOGRAPHIC_OFFSET)) { opType = NULL_GEOGRAPHIC_OFFSET; + } else if (starts_with(forwardName, NULL_GEOCENTRIC_TRANSLATION)) { + opType = NULL_GEOCENTRIC_TRANSLATION; } else if (dynamic_cast<const Transformation *>(op) || starts_with(forwardName, "Transformation from ")) { opType = "Transformation"; @@ -11049,6 +11052,8 @@ struct FilterResults { std::string::npos || op->nameStr().find(NULL_GEOGRAPHIC_OFFSET) != std::string::npos || + op->nameStr().find(NULL_GEOCENTRIC_TRANSLATION) != + std::string::npos || op->nameStr().find(BALLPARK_GEOCENTRIC_TRANSLATION) != std::string::npos; @@ -11114,6 +11119,7 @@ struct FilterResults { const std::string &name = res.back()->nameStr(); if (name.find(BALLPARK_GEOGRAPHIC_OFFSET) != std::string::npos || name.find(NULL_GEOGRAPHIC_OFFSET) != std::string::npos || + name.find(NULL_GEOCENTRIC_TRANSLATION) != std::string::npos || name.find(BALLPARK_GEOCENTRIC_TRANSLATION) != std::string::npos) { std::vector<CoordinateOperationNNPtr> resTemp; @@ -12224,7 +12230,8 @@ static bool isNullTransformation(const std::string &name) { return starts_with(name, BALLPARK_GEOCENTRIC_TRANSLATION) || starts_with(name, BALLPARK_GEOGRAPHIC_OFFSET) || - starts_with(name, NULL_GEOGRAPHIC_OFFSET); + starts_with(name, NULL_GEOGRAPHIC_OFFSET) || + starts_with(name, NULL_GEOCENTRIC_TRANSLATION); } // --------------------------------------------------------------------------- @@ -13170,15 +13177,40 @@ void CoordinateOperationFactory::Private::createOperationsGeodToGeod( res.emplace_back(ConcatenatedOperation::createComputeMetadata( {opFirst, opSecond}, !allowEmptyIntersection)); } else { - res = applyInverse(createOperations(targetCRS, sourceCRS, context)); + // Apply previous case in reverse way + std::vector<CoordinateOperationNNPtr> resTmp; + createOperationsGeodToGeod(targetCRS, sourceCRS, context, geodDst, + geodSrc, resTmp); + assert(resTmp.size() == 1); + res.emplace_back(resTmp.front()->inverse()); } return; } if (isSrcGeocentric && isTargetGeocentric) { - res.emplace_back( - createBallparkGeocentricTranslation(sourceCRS, targetCRS)); + if (sourceCRS->_isEquivalentTo( + targetCRS.get(), util::IComparable::Criterion::EQUIVALENT) || + (geodSrc->datum() != nullptr && geodDst->datum() != nullptr && + geodSrc->datum()->_isEquivalentTo( + geodDst->datum().get(), + util::IComparable::Criterion::EQUIVALENT))) { + std::string name(NULL_GEOCENTRIC_TRANSLATION); + name += " from "; + name += sourceCRS->nameStr(); + name += " to "; + name += targetCRS->nameStr(); + res.emplace_back(Transformation::createGeocentricTranslations( + util::PropertyMap() + .set(common::IdentifiedObject::NAME_KEY, name) + .set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY, + metadata::Extent::WORLD), + sourceCRS, targetCRS, 0.0, 0.0, 0.0, + {metadata::PositionalAccuracy::create("0")})); + } else { + res.emplace_back( + createBallparkGeocentricTranslation(sourceCRS, targetCRS)); + } return; } diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index ce01f967..73f5dbdc 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -592,9 +592,7 @@ static GeodeticCRSNNPtr createGeocentricDatumWGS84() { static GeodeticCRSNNPtr createGeocentricKM() { PropertyMap propertiesCRS; - propertiesCRS.set(Identifier::CODESPACE_KEY, "EPSG") - .set(Identifier::CODE_KEY, 4328) - .set(IdentifiedObject::NAME_KEY, "WGS 84"); + propertiesCRS.set(IdentifiedObject::NAME_KEY, "Based on WGS 84"); return GeodeticCRS::create( propertiesCRS, GeodeticReferenceFrame::EPSG_6326, CartesianCS::createGeocentric( @@ -5077,13 +5075,13 @@ TEST(operation, geogCRS_to_geocentricCRS_different_datum) { // --------------------------------------------------------------------------- -TEST(operation, geocentricCRS_to_geocentricCRS_noop) { +TEST(operation, geocentricCRS_to_geocentricCRS_same_noop) { auto op = CoordinateOperationFactory::create()->createOperation( createGeocentricDatumWGS84(), createGeocentricDatumWGS84()); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->nameStr(), - "Ballpark geocentric translation from WGS 84 to WGS 84"); + "Null geocentric translation from WGS 84 to WGS 84"); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=noop"); EXPECT_EQ(op->inverse()->nameStr(), op->nameStr()); @@ -5091,6 +5089,28 @@ TEST(operation, geocentricCRS_to_geocentricCRS_noop) { // --------------------------------------------------------------------------- +TEST(operation, geocentricCRS_to_geocentricCRS_different_ballpark) { + + PropertyMap propertiesCRS; + propertiesCRS.set(Identifier::CODESPACE_KEY, "EPSG") + .set(Identifier::CODE_KEY, 4328) + .set(IdentifiedObject::NAME_KEY, "unknown"); + auto otherGeocentricCRS = GeodeticCRS::create( + propertiesCRS, GeodeticReferenceFrame::EPSG_6269, + CartesianCS::createGeocentric(UnitOfMeasure::METRE)); + + auto op = CoordinateOperationFactory::create()->createOperation( + createGeocentricKM(), otherGeocentricCRS); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ( + op->nameStr(), + "Ballpark geocentric translation from Based on WGS 84 to unknown"); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=unitconvert +xy_in=km +z_in=km +xy_out=m +z_out=m"); +} + +// --------------------------------------------------------------------------- + TEST(operation, geocentricCRS_to_geogCRS_same_datum_context) { auto authFactory = AuthorityFactory::create(DatabaseContext::create(), "EPSG"); |
