Skip to content

Commit

Permalink
PROJString formatter optimizer: simplify pipelines doing [Modified]Kr…
Browse files Browse the repository at this point in the history
…ovak (South West) <--> [Modified]Krovak (East North) by just doing an axis swap
  • Loading branch information
rouault committed Feb 3, 2024
1 parent a3b225f commit 9a13a42
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/iso19111/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9241,6 +9241,68 @@ 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
if (curStep.inverted != prevStep.inverted &&
curStep.name == prevStep.name &&
curStepParamCount + 1 == prevStepParamCount &&
prevStep.paramValues[0].equals("axis", "swu")) {
bool allSame = true; // skipping prevStep[0] (axis=swu)
for (size_t j = 0; j < curStepParamCount; j++) {
if (curStep.paramValues[j] != prevStep.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;
}
}
// and the symmetrical situation:
// +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
// as:
// +step +proj=axisswap +order=-2,-1
else if (curStep.inverted != prevStep.inverted &&
curStep.name == prevStep.name &&
curStepParamCount == prevStepParamCount + 1 &&
curStep.paramValues[0].equals("axis", "swu")) {
bool allSame = true; // skipping curStep[0] (axis=swu)
for (size_t j = 0; j < prevStepParamCount; j++) {
if (curStep.paramValues[j + 1] != prevStep.paramValues[j]) {
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 9a13a42

Please sign in to comment.