diff options
| -rw-r--r-- | src/iso19111/io.cpp | 13 | ||||
| -rw-r--r-- | src/pipeline.cpp | 57 | ||||
| -rw-r--r-- | test/gie/4D-API_cs2cs-style.gie | 49 |
3 files changed, 107 insertions, 12 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 678c5d98..d994277b 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -6284,6 +6284,15 @@ struct Step { }; std::vector<KeyValue> paramValues{}; + + bool hasKey(const char *keyName) const { + for (const auto &kv : paramValues) { + if (kv.key == keyName) { + return true; + } + } + return false; + } }; Step::KeyValue::KeyValue(const char *keyIn, const std::string &valueIn) @@ -6813,7 +6822,9 @@ const std::string &PROJStringFormatter::toString() const { if (d->steps_.size() > 1 || (d->steps_.size() == 1 && - (d->steps_.front().inverted || !d->globalParamValues_.empty()))) { + (d->steps_.front().inverted || d->steps_.front().hasKey("omit_inv") || + d->steps_.front().hasKey("omit_fwd") || + !d->globalParamValues_.empty()))) { d->appendToResult("+proj=pipeline"); for (const auto ¶mValue : d->globalParamValues_) { diff --git a/src/pipeline.cpp b/src/pipeline.cpp index bc6708b0..99b2bdfb 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -116,9 +116,14 @@ namespace { // anonymous namespace struct Step { PJ* pj = nullptr; - - Step(PJ* pjIn): pj(pjIn) {} - Step(Step&& other): pj(std::move(other.pj)) { other.pj = nullptr; } + bool omit_fwd = false; + bool omit_inv = false; + + Step(PJ* pjIn, bool omitFwdIn, bool omitInvIn): + pj(pjIn), omit_fwd(omitFwdIn), omit_inv(omitInvIn) {} + Step(Step&& other): pj(std::move(other.pj)), + omit_fwd(other.omit_fwd), + omit_inv(other.omit_inv) { other.pj = nullptr; } Step(const Step&) = delete; Step& operator=(const Step&) = delete; @@ -161,7 +166,12 @@ void pj_pipeline_assign_context_to_steps( PJ* P, PJ_CONTEXT* ctx ) static PJ_COORD pipeline_forward_4d (PJ_COORD point, PJ *P) { auto opaque = static_cast<struct pj_opaque*>(P->opaque); for( auto& step: opaque->steps ) - point = proj_trans (step.pj, PJ_FWD, point); + { + if( !step.omit_fwd ) + { + point = proj_trans (step.pj, PJ_FWD, point); + } + } return point; } @@ -171,7 +181,11 @@ static PJ_COORD pipeline_reverse_4d (PJ_COORD point, PJ *P) { auto opaque = static_cast<struct pj_opaque*>(P->opaque); for( auto it = opaque->steps.rbegin(); it != opaque->steps.rend(); ++it ) { - point = proj_trans (it->pj, PJ_INV, point); + const auto& step = *it; + if( !step.omit_inv ) + { + point = proj_trans (step.pj, PJ_INV, point); + } } return point; @@ -185,7 +199,12 @@ static PJ_XYZ pipeline_forward_3d (PJ_LPZ lpz, PJ *P) { point.lpz = lpz; auto opaque = static_cast<struct pj_opaque*>(P->opaque); for( auto& step: opaque->steps ) - point = pj_approx_3D_trans (step.pj, PJ_FWD, point); + { + if( !step.omit_fwd ) + { + point = pj_approx_3D_trans (step.pj, PJ_FWD, point); + } + } return point.xyz; } @@ -197,7 +216,11 @@ static PJ_LPZ pipeline_reverse_3d (PJ_XYZ xyz, PJ *P) { auto opaque = static_cast<struct pj_opaque*>(P->opaque); for( auto it = opaque->steps.rbegin(); it != opaque->steps.rend(); ++it ) { - point = proj_trans (it->pj, PJ_INV, point); + const auto& step = *it; + if( !step.omit_inv ) + { + point = proj_trans (step.pj, PJ_INV, point); + } } return point.lpz; @@ -211,7 +234,12 @@ static PJ_XY pipeline_forward (PJ_LP lp, PJ *P) { point.lp = lp; auto opaque = static_cast<struct pj_opaque*>(P->opaque); for( auto& step: opaque->steps ) - point = pj_approx_2D_trans (step.pj, PJ_FWD, point); + { + if( !step.omit_fwd ) + { + point = pj_approx_2D_trans (step.pj, PJ_FWD, point); + } + } return point.xy; } @@ -223,7 +251,11 @@ static PJ_LP pipeline_reverse (PJ_XY xy, PJ *P) { auto opaque = static_cast<struct pj_opaque*>(P->opaque); for( auto it = opaque->steps.rbegin(); it != opaque->steps.rend(); ++it ) { - point = pj_approx_2D_trans (it->pj, PJ_INV, point); + const auto& step = *it; + if( !step.omit_inv ) + { + point = pj_approx_2D_trans (step.pj, PJ_INV, point); + } } return point.lp; @@ -476,13 +508,16 @@ PJ *OPERATION(pipeline,0) { proj_errno_restore (P, err); /* Is this step inverted? */ - for (j = 0; j < current_argc; j++) + for (j = 0; j < current_argc; j++) { if (0==strcmp("inv", current_argv[j])) { /* if +inv exists in both global and local args the forward operation should be used */ next_step->inverted = next_step->inverted == 0 ? 1 : 0; } + } - opaque->steps.emplace_back(next_step); + bool omit_fwd = pj_param(P->ctx, next_step->params, "bomit_fwd").i != 0; + bool omit_inv = pj_param(P->ctx, next_step->params, "bomit_inv").i != 0; + opaque->steps.emplace_back(next_step, omit_fwd, omit_inv); proj_log_trace (P, "Pipeline at [%p]: step at [%p] (%s) done", P, next_step, current_argv[0]); } diff --git a/test/gie/4D-API_cs2cs-style.gie b/test/gie/4D-API_cs2cs-style.gie index 19b3ad96..e5722b5e 100644 --- a/test/gie/4D-API_cs2cs-style.gie +++ b/test/gie/4D-API_cs2cs-style.gie @@ -386,6 +386,55 @@ operation +proj=pop +v_3 accept 12 56 0 0 expect 12 56 0 0 +------------------------------------------------------------------------------- +Test Pipeline +omit_inv +------------------------------------------------------------------------------- + +operation +proj=pipeline + +step +proj=affine +xoff=1 +yoff=1 +omit_inv + +accept 2 49 0 0 +expect 3 50 0 0 + +direction inverse +accept 2 49 0 0 +expect 2 49 0 0 + + +operation +proj=pipeline + +step +inv +proj=affine +xoff=1 +yoff=1 +omit_inv + +accept 2 49 0 0 +expect 1 48 0 0 + +direction inverse +accept 2 49 0 0 +expect 2 49 0 0 + +------------------------------------------------------------------------------- +Test Pipeline +omit_fwd +------------------------------------------------------------------------------- + +operation +proj=pipeline + +step +proj=affine +xoff=1 +yoff=1 +omit_fwd + +accept 2 49 0 0 +expect 2 49 0 0 + +direction inverse +accept 2 49 0 0 +expect 1 48 0 0 + + +operation +proj=pipeline + +step +inv +proj=affine +xoff=1 +yoff=1 +omit_fwd + +accept 2 49 0 0 +expect 2 49 0 0 + +direction inverse +accept 2 49 0 0 +expect 3 50 0 0 ------------------------------------------------------------------------------- Test bugfix of https://github.com/OSGeo/proj.4/issues/1002 |
