diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index b73543e1c8..f693c4985b 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -9495,7 +9495,6 @@ const std::string &PROJStringFormatter::toString() const { } if (curStep.name == "helmert" && prevStep.name == "helmert" && - !curStep.inverted && !prevStep.inverted && curStepParamCount == 3 && curStepParamCount == prevStepParamCount) { std::map leftParamsMap; @@ -9520,12 +9519,18 @@ const std::string &PROJStringFormatter::toString() const { rightParamsMap.find(y) != rightParamsMap.end() && rightParamsMap.find(z) != rightParamsMap.end()) { - const double xSum = leftParamsMap[x] + rightParamsMap[x]; - const double ySum = leftParamsMap[y] + rightParamsMap[y]; - const double zSum = leftParamsMap[z] + rightParamsMap[z]; + const double signLeft = prevStep.inverted ? -1 : 1; + const double signRight = curStep.inverted ? -1 : 1; + const double xSum = signLeft * leftParamsMap[x] + + signRight * rightParamsMap[x]; + const double ySum = signLeft * leftParamsMap[y] + + signRight * rightParamsMap[y]; + const double zSum = signLeft * leftParamsMap[z] + + signRight * rightParamsMap[z]; if (xSum == 0.0 && ySum == 0.0 && zSum == 0.0) { deletePrevAndCurIter(); } else { + prevStep.inverted = false; prevStep.paramValues[0] = Step::KeyValue("x", internal::toString(xSum)); prevStep.paramValues[1] = @@ -9542,7 +9547,7 @@ const std::string &PROJStringFormatter::toString() const { // Helmert followed by its inverse is a no-op if (curStep.name == "helmert" && prevStep.name == "helmert" && - !curStep.inverted && !prevStep.inverted && + (curStep.inverted == prevStep.inverted) && curStepParamCount == prevStepParamCount) { std::set leftParamsSet; std::set rightParamsSet; diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index ab239dbaaf..0eaf68cf0d 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -10201,31 +10201,137 @@ TEST(io, projstringformatter_helmert_7_param_noop) { // --------------------------------------------------------------------------- TEST(io, projstringformatter_merge_consecutive_helmert_3_param) { - auto fmt = PROJStringFormatter::create(); - fmt->addStep("helmert"); - fmt->addParam("x", 10); - fmt->addParam("y", 20); - fmt->addParam("z", 30); - fmt->addStep("helmert"); - fmt->addParam("x", -1); - fmt->addParam("y", -2); - fmt->addParam("z", -3); - EXPECT_EQ(fmt->toString(), "+proj=helmert +x=9 +y=18 +z=27"); + { + auto fmt = PROJStringFormatter::create(); + fmt->addStep("helmert"); + fmt->addParam("x", 10); + fmt->addParam("y", 20); + fmt->addParam("z", 30); + + fmt->addStep("helmert"); + fmt->addParam("x", -1); + fmt->addParam("y", -2); + fmt->addParam("z", -3); + EXPECT_EQ(fmt->toString(), "+proj=helmert +x=9 +y=18 +z=27"); + } + + { + auto fmt = PROJStringFormatter::create(); + fmt->addStep("helmert"); + fmt->addParam("x", 10); + fmt->addParam("y", 20); + fmt->addParam("z", 30); + + fmt->addStep("helmert"); + fmt->setCurrentStepInverted(true); + fmt->addParam("x", -10); + fmt->addParam("y", -20); + fmt->addParam("z", -30); + EXPECT_EQ(fmt->toString(), "+proj=helmert +x=20 +y=40 +z=60"); + } + + { + auto fmt = PROJStringFormatter::create(); + fmt->addStep("helmert"); + fmt->setCurrentStepInverted(true); + fmt->addParam("x", 10); + fmt->addParam("y", 20); + fmt->addParam("z", 30); + + fmt->addStep("helmert"); + fmt->addParam("x", -10); + fmt->addParam("y", -20); + fmt->addParam("z", -30); + EXPECT_EQ(fmt->toString(), "+proj=helmert +x=-20 +y=-40 +z=-60"); + } } // --------------------------------------------------------------------------- TEST(io, projstringformatter_merge_consecutive_helmert_3_param_noop) { - auto fmt = PROJStringFormatter::create(); - fmt->addStep("helmert"); - fmt->addParam("x", 10); - fmt->addParam("y", 20); - fmt->addParam("z", 30); - fmt->addStep("helmert"); - fmt->addParam("x", -10); - fmt->addParam("y", -20); - fmt->addParam("z", -30); - EXPECT_EQ(fmt->toString(), "+proj=noop"); + { + auto fmt = PROJStringFormatter::create(); + fmt->addStep("helmert"); + fmt->addParam("x", 10); + fmt->addParam("y", 20); + fmt->addParam("z", 30); + + fmt->addStep("helmert"); + fmt->addParam("x", -10); + fmt->addParam("y", -20); + fmt->addParam("z", -30); + EXPECT_EQ(fmt->toString(), "+proj=noop"); + } + + { + auto fmt = PROJStringFormatter::create(); + fmt->addStep("helmert"); + fmt->setCurrentStepInverted(true); + fmt->addParam("x", 10); + fmt->addParam("y", 20); + fmt->addParam("z", 30); + + fmt->addStep("helmert"); + fmt->setCurrentStepInverted(true); + fmt->addParam("x", -10); + fmt->addParam("y", -20); + fmt->addParam("z", -30); + EXPECT_EQ(fmt->toString(), "+proj=noop"); + } +} + +// --------------------------------------------------------------------------- + +TEST(io, projstringformatter_merge_consecutive_helmert_7_param_noop) { + { + auto fmt = PROJStringFormatter::create(); + fmt->addStep("helmert"); + fmt->addParam("x", 10); + fmt->addParam("y", 20); + fmt->addParam("z", 30); + fmt->addParam("rx", 1); + fmt->addParam("ry", 2); + fmt->addParam("rz", 3); + fmt->addParam("s", 4); + fmt->addParam("convention", "position_vector"); + + fmt->addStep("helmert"); + fmt->addParam("x", -10); + fmt->addParam("y", -20); + fmt->addParam("z", -30); + fmt->addParam("rx", -1); + fmt->addParam("ry", -2); + fmt->addParam("rz", -3); + fmt->addParam("s", -4); + fmt->addParam("convention", "position_vector"); + EXPECT_EQ(fmt->toString(), "+proj=noop"); + } + + { + auto fmt = PROJStringFormatter::create(); + fmt->addStep("helmert"); + fmt->setCurrentStepInverted(true); + fmt->addParam("x", 10); + fmt->addParam("y", 20); + fmt->addParam("z", 30); + fmt->addParam("rx", 1); + fmt->addParam("ry", 2); + fmt->addParam("rz", 3); + fmt->addParam("s", 4); + fmt->addParam("convention", "position_vector"); + + fmt->addStep("helmert"); + fmt->setCurrentStepInverted(true); + fmt->addParam("x", -10); + fmt->addParam("y", -20); + fmt->addParam("z", -30); + fmt->addParam("rx", -1); + fmt->addParam("ry", -2); + fmt->addParam("rz", -3); + fmt->addParam("s", -4); + fmt->addParam("convention", "position_vector"); + EXPECT_EQ(fmt->toString(), "+proj=noop"); + } } // --------------------------------------------------------------------------- @@ -10242,11 +10348,37 @@ TEST(io, projstringformatter_merge_inverted_helmert_with_opposite_conventions) { fmt->addParam("rz", 3); fmt->addParam("s", 4); fmt->addParam("convention", "position_vector"); + + fmt->addStep("helmert"); + fmt->setCurrentStepInverted(true); + fmt->addParam("x", 10); + fmt->addParam("y", 20); + fmt->addParam("z", 30); + fmt->addParam("rx", -1); + fmt->addParam("ry", -2); + fmt->addParam("rz", -3); + fmt->addParam("s", 4); + fmt->addParam("convention", "coordinate_frame"); + EXPECT_EQ(fmt->toString(), "+proj=noop"); + } + + { + auto fmt = PROJStringFormatter::create(); fmt->addStep("helmert"); fmt->setCurrentStepInverted(true); fmt->addParam("x", 10); fmt->addParam("y", 20); fmt->addParam("z", 30); + fmt->addParam("rx", 1); + fmt->addParam("ry", 2); + fmt->addParam("rz", 3); + fmt->addParam("s", 4); + fmt->addParam("convention", "position_vector"); + + fmt->addStep("helmert"); + fmt->addParam("x", 10); + fmt->addParam("y", 20); + fmt->addParam("z", 30); fmt->addParam("rx", -1); fmt->addParam("ry", -2); fmt->addParam("rz", -3); @@ -10267,6 +10399,7 @@ TEST(io, projstringformatter_merge_inverted_helmert_with_opposite_conventions) { fmt->addParam("rz", 3); fmt->addParam("s", 4); fmt->addParam("convention", "coordinate_frame"); + fmt->addStep("helmert"); fmt->addParam("x", 10); fmt->addParam("y", 20); @@ -10291,6 +10424,7 @@ TEST(io, projstringformatter_merge_inverted_helmert_with_opposite_conventions) { fmt->addParam("rz", 3); fmt->addParam("s", 4); fmt->addParam("convention", "position_vector"); + fmt->addStep("helmert"); // fmt->setCurrentStepInverted(true); <== CAUSE fmt->addParam("x", 10); @@ -10316,6 +10450,7 @@ TEST(io, projstringformatter_merge_inverted_helmert_with_opposite_conventions) { fmt->addParam("rz", 3); fmt->addParam("s", 4); fmt->addParam("convention", "position_vector"); + fmt->addStep("helmert"); fmt->setCurrentStepInverted(true); fmt->addParam("x", 10); @@ -10341,6 +10476,7 @@ TEST(io, projstringformatter_merge_inverted_helmert_with_opposite_conventions) { fmt->addParam("rz", 3); fmt->addParam("s", 4); fmt->addParam("convention", "position_vector"); + fmt->addStep("helmert"); fmt->setCurrentStepInverted(true); fmt->addParam("x", -10); // <== CAUSE @@ -10366,6 +10502,7 @@ TEST(io, projstringformatter_merge_inverted_helmert_with_opposite_conventions) { fmt->addParam("rz", 2); fmt->addParam("s", 4); fmt->addParam("convention", "position_vector"); + fmt->addStep("helmert"); fmt->setCurrentStepInverted(true); fmt->addParam("x", 10);