Skip to content

Commit

Permalink
Merge pull request #4034 from rouault/projstringformatter_krovak
Browse files Browse the repository at this point in the history
PROJString formatter optimizer: simplify pipelines doing [Modified]Krovak (South West) <--> [Modified]Krovak (East North)…
  • Loading branch information
rouault committed Feb 5, 2024
2 parents a3b225f + d24bd04 commit af8a4ed
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
45 changes: 45 additions & 0 deletions src/iso19111/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9241,6 +9241,51 @@ const std::string &PROJStringFormatter::toString() const {
}
}

// Optimize patterns like Krovak (South West) to Krovak East North
// (also applies to Modified Krovak)
// +step +inv +proj=krovak +axis=swu +lat_0=49.5
// +lon_0=24.8333333333333
// +alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel
// +step +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333
// +alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel
// as:
// +step +proj=axisswap +order=-2,-1
// Also applies for the symmetrical case where +axis=swu is on the
// second step.
if (curStep.inverted != prevStep.inverted &&
curStep.name == prevStep.name &&
((curStepParamCount + 1 == prevStepParamCount &&
prevStep.paramValues[0].equals("axis", "swu")) ||
(prevStepParamCount + 1 == curStepParamCount &&
curStep.paramValues[0].equals("axis", "swu")))) {
const auto &swStep = (curStepParamCount < prevStepParamCount)
? prevStep
: curStep;
const auto &enStep = (curStepParamCount < prevStepParamCount)
? curStep
: prevStep;
// Check if all remaining parameters (except leading axis=swu
// in swStep) are identical.
bool allSame = true;
for (size_t j = 0;
j < std::min(curStepParamCount, prevStepParamCount); j++) {
if (enStep.paramValues[j] != swStep.paramValues[j + 1]) {
allSame = false;
break;
}
}
if (allSame) {
iterCur->inverted = false;
iterCur->name = "axisswap";
iterCur->paramValues.clear();
iterCur->paramValues.emplace_back(
Step::KeyValue("order", "-2,-1"));

deletePrevIter();
continue;
}
}

// detect a step and its inverse
if (curStep.inverted != prevStep.inverted &&
curStep.name == prevStep.name &&
Expand Down
87 changes: 87 additions & 0 deletions test/unit/test_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10015,6 +10015,93 @@ TEST(io, projstringformatter_optim_as_uc_vgridshift_uc_as_push_as_uc) {

// ---------------------------------------------------------------------------

TEST(io, projstringformatter_krovak_to_krovak_east_north) {
// Working case
{
auto fmt = PROJStringFormatter::create();
fmt->ingestPROJString(
"+proj=pipeline "
"+step +inv +proj=krovak +axis=swu +lat_0=49.5 "
"+lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel "
"+step +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel");
EXPECT_EQ(fmt->toString(), "+proj=axisswap +order=-2,-1");
}

// Missing parameter
{
auto fmt = PROJStringFormatter::create();
fmt->ingestPROJString(
"+proj=pipeline "
"+step +inv +proj=krovak +axis=swu +lat_0=49.5 "
"+lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel "
"+step +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 ");
// Not equal
EXPECT_NE(fmt->toString(), "+proj=axisswap +order=-2,-1");
}

// Different parameter values
{
auto fmt = PROJStringFormatter::create();
fmt->ingestPROJString(
"+proj=pipeline "
"+step +inv +proj=krovak +axis=swu +lat_0=49.5 "
"+lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel "
"+step +proj=krovak +lat_0=FOO +lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel");
// Not equal
EXPECT_NE(fmt->toString(), "+proj=axisswap +order=-2,-1");
}
}

// ---------------------------------------------------------------------------

TEST(io, projstringformatter_krovak_east_north_to_krovak) {
// Working case
{
auto fmt = PROJStringFormatter::create();
fmt->ingestPROJString(
"+proj=pipeline "
"+step +inv +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel "
"+step +proj=krovak +axis=swu +lat_0=49.5 +lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel");
EXPECT_EQ(fmt->toString(), "+proj=axisswap +order=-2,-1");
}

// Missing parameter
{
auto fmt = PROJStringFormatter::create();
fmt->ingestPROJString(
"+proj=pipeline "
"+step +inv +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel "
"+step +proj=krovak +axis=swu +lat_0=FOO +lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0");
// Not equal
EXPECT_NE(fmt->toString(), "+proj=axisswap +order=-2,-1");
}

// Different parameter values
{
auto fmt = PROJStringFormatter::create();
fmt->ingestPROJString(
"+proj=pipeline "
"+step +inv +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel "
"+step +proj=krovak +axis=swu +lat_0=FOO +lon_0=24.8333333333333 "
"+alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel");
// Not equal
EXPECT_NE(fmt->toString(), "+proj=axisswap +order=-2,-1");
}
}

// ---------------------------------------------------------------------------

TEST(io, projparse_longlat) {

auto expected = "GEODCRS[\"unknown\",\n"
Expand Down

0 comments on commit af8a4ed

Please sign in to comment.