aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/PJ_axisswap.c97
-rw-r--r--test/gie/axisswap.gie27
2 files changed, 90 insertions, 34 deletions
diff --git a/src/PJ_axisswap.c b/src/PJ_axisswap.c
index 62a9fba3..bb22f41e 100644
--- a/src/PJ_axisswap.c
+++ b/src/PJ_axisswap.c
@@ -159,53 +159,70 @@ static PJ_COORD reverse_4d(PJ_COORD coo, PJ *P) {
PJ *CONVERSION(axisswap,0) {
/***********************************************************************/
struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
- char *order, *s;
- unsigned int i, j, n;
+ char *s;
+ unsigned int i, j, n = 0;
if (0==Q)
return pj_default_destructor (P, ENOMEM);
P->opaque = (void *) Q;
- /* read axis order */
- if (pj_param (P->ctx, P->params, "torder").i) {
- order = pj_param(P->ctx, P->params, "sorder").s;
- } else {
- return pj_default_destructor(P, PJD_ERR_MISSING_ARGS);
- }
-
- /* Preparation and finalization steps are skipped, since the raison */
- /* d'etre of axisswap is to bring input coordinates in line with the */
- /* the internally expected order (ENU), such that handling of offsets */
- /* etc. can be done correctly in a later step of a pipeline */
- P->skip_fwd_prepare = 1;
- P->skip_fwd_finalize = 1;
- P->skip_inv_prepare = 1;
- P->skip_inv_finalize = 1;
+ /* +order and +axis are mutually exclusive */
+ if ( !pj_param_exists(P->params, "order") == !pj_param_exists(P->params, "axis") )
+ return pj_default_destructor(P, PJD_ERR_AXIS);
/* fill axis list with indices from 4-7 to simplify duplicate search further down */
- for (i=0; i<4; i++)
+ for (i=0; i<4; i++) {
Q->axis[i] = i+4;
+ Q->sign[i] = 1;
+ }
+
+ /* if the "order" parameter is used */
+ if ( pj_param_exists(P->params, "order") ) {
+ /* read axis order */
+ char *order = pj_param(P->ctx, P->params, "sorder").s;
+
+ /* check that all characters are valid */
+ for (i=0; i<strlen(order); i++)
+ if (strchr("1234-,", order[i]) == 0) {
+ proj_log_error(P, "axisswap: unknown axis '%c'", order[i]);
+ return pj_default_destructor(P, PJD_ERR_AXIS);
+ }
- /* check that all characters are valid */
- for (i=0; i<strlen(order); i++)
- if (strchr("1234-,", order[i]) == 0) {
- proj_log_error(P, "axisswap: unknown axis '%c'", order[i]);
- return pj_default_destructor(P, PJD_ERR_AXIS);
+ /* read axes numbers and signs */
+ for ( s = order, n = 0; *s != '\0' && n < 4; ) {
+ Q->axis[n] = abs(atoi(s))-1;
+ Q->sign[n++] = sign(atoi(s));
+ while ( *s != '\0' && *s != ',' )
+ s++;
+ if ( *s == ',' )
+ s++;
}
+ }
- /* read axes numbers and signs */
- for ( s = order, n = 0; *s != '\0' && n < 4; ) {
- Q->axis[n] = abs(atoi(s))-1;
- if (Q->axis[n] >= 4) {
- proj_log_error(P, "swapaxis: invalid axis '%s'", s);
- return pj_default_destructor(P, PJD_ERR_AXIS);
+ /* if the "axis" parameter is used */
+ if ( pj_param_exists(P->params, "axis") ) {
+ /* parse the classic PROJ.4 enu axis specification */
+ for (i=0; i < 3; i++) {
+ switch(P->axis[i]) {
+ case 'w':
+ Q->sign[i] = -1;
+ case 'e':
+ Q->axis[i] = 0;
+ break;
+ case 's':
+ Q->sign[i] = -1;
+ case 'n':
+ Q->axis[i] = 1;
+ break;
+ case 'd':
+ Q->sign[i] = -1;
+ case 'u':
+ Q->axis[i] = 2;
+ break;
+ }
}
- Q->sign[n++] = sign(atoi(s));
- while ( *s != '\0' && *s != ',' )
- s++;
- if ( *s == ',' )
- s++;
+ n = 3;
}
/* check for duplicate axes */
@@ -219,6 +236,7 @@ PJ *CONVERSION(axisswap,0) {
}
}
+
/* only map fwd/inv functions that are possible with the given axis setup */
if (n == 4) {
P->fwd4d = forward_4d;
@@ -233,6 +251,7 @@ PJ *CONVERSION(axisswap,0) {
P->inv = reverse_2d;
}
+
if (P->fwd4d == NULL && P->fwd3d == NULL && P->fwd == NULL) {
proj_log_error(P, "swapaxis: bad axis order");
return pj_default_destructor(P, PJD_ERR_AXIS);
@@ -246,5 +265,15 @@ PJ *CONVERSION(axisswap,0) {
P->right = PJ_IO_UNITS_PROJECTED;
}
+
+ /* Preparation and finalization steps are skipped, since the raison */
+ /* d'etre of axisswap is to bring input coordinates in line with the */
+ /* the internally expected order (ENU), such that handling of offsets */
+ /* etc. can be done correctly in a later step of a pipeline */
+ P->skip_fwd_prepare = 1;
+ P->skip_fwd_finalize = 1;
+ P->skip_inv_prepare = 1;
+ P->skip_inv_finalize = 1;
+
return P;
}
diff --git a/test/gie/axisswap.gie b/test/gie/axisswap.gie
index 7f0c366c..ac148a92 100644
--- a/test/gie/axisswap.gie
+++ b/test/gie/axisswap.gie
@@ -52,6 +52,15 @@ accept 1 2 3 4
expect 3 -2 1 4
roundtrip 100
+operation proj=axisswap axis=neu
+tolerance 0.000001 m
+accept 1 2 3 4
+expect 2 1 3 4
+
+operation proj=axisswap axis=swd
+tolerance 0.000001 m
+accept 1 2 3 4
+expect -2 -1 -3 4
operation proj=pipeline
step proj=latlong
@@ -73,4 +82,22 @@ tolerance 0.00001 m
accept 12 55 0 0
expect -55 -12 0 0
+operation proj=axisswap order=1,2,3,4 axis=enu
+expect failure pjd_err_axis
+
+operation proj=axisswap
+expect failure pjd_err_axis
+
+operation proj=axisswap order=1,2,1,4
+expect failure pjd_err_axis
+
+operation proj=axisswap order=2,3
+expect failure pjd_err_axis
+
+operation proj=axisswap order=2,3,4
+expect failure pjd_err_axis
+
+operation proj=axisswap order=1,2,3,5
+expect failure pjd_err_axis
+
</gie>