diff options
| author | Kristian Evers <kristianevers@gmail.com> | 2018-01-17 16:10:34 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-01-17 16:10:34 +0100 |
| commit | 33a7216aea7bacf8cff72a5e6bb59b25e7d931f7 (patch) | |
| tree | ff2eafe33befd8fe38f63a83a0b8562f1304a8f2 | |
| parent | 53b30f10c6e8d74a79b5d0763a53c5e1732e34b7 (diff) | |
| parent | 046ce54719f3224b1b9299ee8d370cc92b0929af (diff) | |
| download | PROJ-33a7216aea7bacf8cff72a5e6bb59b25e7d931f7.tar.gz PROJ-33a7216aea7bacf8cff72a5e6bb59b25e7d931f7.zip | |
Merge pull request #739 from kbevers/pipeline-inverse
Pipeline and cct inverse fixes
| -rw-r--r-- | src/PJ_pipeline.c | 32 | ||||
| -rw-r--r-- | src/cct.c | 10 | ||||
| -rw-r--r-- | test/gie/more_builtins.gie | 61 |
3 files changed, 97 insertions, 6 deletions
diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index af9c5394..befc8557 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -429,14 +429,42 @@ PJ *OPERATION(pipeline,0) { /* Is this step inverted? */ for (j = 0; j < current_argc; j++) - if (0==strcmp("inv", current_argv[j])) - next_step->inverted = 1; + 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; + } P->opaque->pipeline[i+1] = next_step; proj_log_trace (P, "Pipeline at [%p]: step at [%p] done", P, next_step); } + /* Require a forward path through the pipeline */ + for (i = 1; i <= nsteps; i++) { + PJ *Q = P->opaque->pipeline[i]; + if ( ( Q->inverted && (Q->inv || Q->inv3d || Q->fwd4d) ) || + (!Q->inverted && (Q->fwd || Q->fwd3d || Q->fwd4d) ) ) { + continue; + } else { + proj_log_error (P, "Pipeline: A forward operation couldn't be constructed"); + return destructor (P, PJD_ERR_MALFORMED_PIPELINE); + } + } + + /* determine if an inverse operation is possible */ + for (i = 1; i <= nsteps; i++) { + PJ *Q = P->opaque->pipeline[i]; + if ( ( Q->inverted && (Q->fwd || Q->fwd3d || Q->fwd4d) ) || + ( Q->inv || Q->inv3d || Q->inv4d) ) { + continue; + } else { + P->inv = 0; + P->inv3d = 0; + P->inv4d = 0; + break; + } + } + proj_log_trace (P, "Pipeline: %d steps built. Determining i/o characteristics", nsteps); /* Determine forward input (= reverse output) data type */ @@ -217,9 +217,15 @@ int main(int argc, char **argv) { return 1; } - /* We have no API call for inverting an operation, so we brute force it. */ - if (direction==-1) + if (direction==-1) { + /* fail if an inverse operation is not available */ + if (!proj_pj_info(P).has_inverse) { + fprintf (stderr, "Inverse operation not available\n"); + return 1; + } + /* We have no API call for inverting an operation, so we brute force it. */ P->inverted = !(P->inverted); + } direction = 1; /* Allocate input buffer */ diff --git a/test/gie/more_builtins.gie b/test/gie/more_builtins.gie index 099934a7..20bffbd9 100644 --- a/test/gie/more_builtins.gie +++ b/test/gie/more_builtins.gie @@ -65,7 +65,7 @@ roundtrip 100 1 m ------------------------------------------------------------------------------- Some tests from PJ_pipeline.c ------------------------------------------------------------------------------- -Forward-reverse geo->utm->geo +Forward-reverse geo->utm->geo (4D functions) ------------------------------------------------------------------------------- operation proj=pipeline zone=32 step proj=utm ellps=GRS80 step @@ -81,7 +81,7 @@ Now the inverse direction (still same result: the pipeline is symmetrical) direction inverse expect 12 55 0 0 ------------------------------------------------------------------------------- -And now the back-to-back situation utm->geo->utm +And now the back-to-back situation utm->geo->utm (4D functions) ------------------------------------------------------------------------------- operation proj=pipeline zone=32 ellps=GRS80 step proj=utm inv step @@ -92,6 +92,33 @@ expect 691875.63214 6098907.82501 0 0 direction inverse expect 691875.63214 6098907.82501 0 0 ------------------------------------------------------------------------------- +Forward-reverse geo->utm->geo (3D functions) +------------------------------------------------------------------------------- +operation proj=pipeline zone=32 step + proj=utm ellps=GRS80 step + proj=utm ellps=GRS80 inv +------------------------------------------------------------------------------- +tolerance 0.1 mm + +accept 12 55 0 +expect 12 55 0 + +Now the inverse direction (still same result: the pipeline is symmetrical) + +direction inverse +expect 12 55 0 +------------------------------------------------------------------------------- +And now the back-to-back situation utm->geo->utm (3D functions) +------------------------------------------------------------------------------- +operation proj=pipeline zone=32 ellps=GRS80 step + proj=utm inv step + proj=utm +------------------------------------------------------------------------------- +accept 691875.63214 6098907.82501 0 +expect 691875.63214 6098907.82501 0 +direction inverse +expect 691875.63214 6098907.82501 0 +------------------------------------------------------------------------------- Test a corner case: A rather pointless one-step pipeline geo->utm ------------------------------------------------------------------------------- operation proj=pipeline step proj=utm zone=32 ellps=GRS80 @@ -115,9 +142,39 @@ expect 691875.63214 6098907.82501 0 0 direction inverse accept 12 55 0 0 expect 12 55 0 0 +------------------------------------------------------------------------------- +Test a few inversion scenarios (urm5 has no inverse operation) +------------------------------------------------------------------------------- +operation proj=pipeline step + proj=urm5 n=0.5 inv +expect failure pjd_err_malformed_pipeline + +operation proj=pipeline inv step + proj=urm5 n=0.5 +expect failure pjd_err_malformed_pipeline +operation proj=pipeline inv step + proj=urm5 n=0.5 inv +accept 12 56 +expect 1215663.2814182492 5452209.5424045017 + +operation proj=pipeline step + proj=urm5 n=0.5 +accept 12 56 +expect 1215663.2814182492 5452209.5424045017 +------------------------------------------------------------------------------- +Test various failing scenarios. +------------------------------------------------------------------------------- +operation proj=pipeline step + proj=pipeline step + proj=merc +expect failure pjd_err_malformed_pipeline +operation step proj=pipeline step proj=merc +expect failure pjd_err_malformed_pipeline +operation proj=pipeline +expect failure pjd_err_malformed_pipeline ------------------------------------------------------------------------------- |
