Skip to content

Commit

Permalink
Overhaul ellipsoid handling (#682)
Browse files Browse the repository at this point in the history
Improve error messaging for cct and gie, and do some clean ups in the ellipsoid handling - partially to squash bugs, partially to improve naming consistency which, in turn, improves the readability of the ellipsoid handling code.

Renamed functions:

pj_inherit_ellipsoid_defs has been renamed pj_inherit_ellipsoid_def, while pj_calc_ellps_params has been renamed pj_calc_ellipsoid_params.

The code in get_opt (part of pj_init.c), which handles whether or not an ellipsoid definition should be dragged in from proj_def.dat, has been rewritten. I suspect this was buggy beforehand, and at least the new code is easier to follow (although it may be slightly slower, which is not really a problem as it sits in the setup code, and hence is executed only once).
  • Loading branch information
busstoptaktik committed Nov 25, 2017
1 parent a7a2c3d commit bea0c8b
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 109 deletions.
5 changes: 2 additions & 3 deletions src/PJ_deformation.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,8 @@ PJ *TRANSFORMATION(deformation,1) {
if (Q->cart == 0)
return destructor(P, ENOMEM);

/* inherit ellipsoid definition from P to Q->cart (simpler than guessing */
/* how the ellipsoid was specified in original definition) */
pj_inherit_ellipsoid_defs(P, Q->cart);
/* inherit ellipsoid definition from P to Q->cart */
pj_inherit_ellipsoid_def (P, Q->cart);

Q->has_xy_grids = pj_param(P->ctx, P->params, "txy_grids").i;
Q->has_z_grids = pj_param(P->ctx, P->params, "tz_grids").i;
Expand Down
2 changes: 1 addition & 1 deletion src/PJ_healpix.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ PJ *PROJECTION(healpix) {
return destructor(P, ENOMEM);
Q->qp = pj_qsfn(1.0, P->e, P->one_es); /* For auth_lat(). */
P->a = P->a*sqrt(0.5*Q->qp); /* Set P->a to authalic radius. */
pj_calc_ellps_params (P, P->a, P->es); /* Ensure we have a consistent parameter set */
pj_calc_ellipsoid_params (P, P->a, P->es); /* Ensure we have a consistent parameter set */
P->fwd = e_healpix_forward;
P->inv = e_healpix_inverse;
} else {
Expand Down
32 changes: 24 additions & 8 deletions src/PJ_pipeline.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ static char **argv_params (paralist *params, size_t argc) {
/* re-initialize P->geod. */
static void set_ellipsoid(PJ *P) {
paralist *cur, *attachment;
int err = proj_errno_reset (P);

/* Break the linked list after the global args */
attachment = 0;
Expand All @@ -320,13 +321,21 @@ static void set_ellipsoid(PJ *P) {
if (0 != pj_ellipsoid (P)) {
P->a = 6378137.0;
P->es = .00669438002290341575;

/* reset an "unerror": In this special use case, the errno is */
/* not an error signal, but just a reply from pj_ellipsoid, */
/* telling us that "No - there was no ellipsoid definition in */
/* the PJ you provided". */
proj_errno_reset (P);
}

pj_calc_ellps_params(P, P->a, P->es);
pj_calc_ellipsoid_params (P, P->a, P->es);

geod_init(P->geod, P->a, (1 - sqrt (1 - P->es)));

/* Re-attach the dangling list */
cur->next = attachment;
proj_errno_restore (P, err);
}


Expand All @@ -345,7 +354,7 @@ PJ *OPERATION(pipeline,0) {

P->opaque = pj_calloc (1, sizeof(struct pj_opaque));
if (0==P->opaque)
return pj_default_destructor(P, ENOMEM);
return destructor(P, ENOMEM);

argc = (int)argc_params (P->params);
P->opaque->argv = argv = argv_params (P->params, argc);
Expand Down Expand Up @@ -396,6 +405,7 @@ PJ *OPERATION(pipeline,0) {
for (i_current_step = i_first_step, i = 0; i < nsteps; i++) {
int j;
int current_argc = 0;
int err;
PJ *next_step = 0;

/* Build a set of setup args for the current step */
Expand All @@ -415,22 +425,30 @@ PJ *OPERATION(pipeline,0) {
for (j = 1; j < current_argc; j++)
proj_log_trace (P, " %s", current_argv[j]);

next_step = pj_init_ctx (P->ctx, current_argc, current_argv);
err = proj_errno_reset (P);

next_step = proj_create_argv (P->ctx, current_argc, current_argv);
proj_log_trace (P, "Pipeline: Step %d at %p", i, next_step);

if (0==next_step) {
proj_log_error (P, "Pipeline: Bad step definition: %s", current_argv[0]);
return destructor (P, PJD_ERR_MALFORMED_PIPELINE); /* ERROR: bad pipeline def */
/* The step init failed, but possibly without setting errno. If so, we say "malformed" */
int err_to_report = proj_errno(P);
if (0==err_to_report)
err_to_report = PJD_ERR_MALFORMED_PIPELINE;
proj_log_error (P, "Pipeline: Bad step definition: %s (%s)", current_argv[0], pj_strerrno (err_to_report));
return destructor (P, err_to_report); /* ERROR: bad pipeline def */
}

proj_errno_restore (P, err);

/* Is this step inverted? */
for (j = 0; j < current_argc; j++)
if (0==strcmp("inv", current_argv[j]))
next_step->inverted = 1;

P->opaque->pipeline[i+1] = next_step;

proj_log_trace (P, "Pipeline: step done");
proj_log_trace (P, "Pipeline at [%p]: step at [%p] done", P, next_step);
}

proj_log_trace (P, "Pipeline: %d steps built. Determining i/o characteristics", nsteps);
Expand All @@ -440,7 +458,5 @@ PJ *OPERATION(pipeline,0) {

/* Now, correspondingly determine forward output (= reverse input) data type */
P->right = pj_right (P->opaque->pipeline[nsteps]);

return P;
}

12 changes: 9 additions & 3 deletions src/cct.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ int main(int argc, char **argv) {
/* Setup transformation */
P = proj_create_argv (0, o->pargc, o->pargv);
if ((0==P) || (0==o->pargc)) {
fprintf (stderr, "%s: Bad transformation arguments. '%s -h' for help\n", o->progname, o->progname);
fprintf (stderr, "%s: Bad transformation arguments - (%s)\n '%s -h' for help\n",
o->progname, pj_strerrno (proj_errno(P)), o->progname);
free (o);
if (stdout != fout)
fclose (fout);
Expand All @@ -232,6 +233,7 @@ int main(int argc, char **argv) {

/* Loop over all records of all input files */
while (opt_input_loop (o, optargs_file_format_text)) {
int err;
void *ret = fgets (buf, 10000, o->input);
opt_eof_handler (o);
if (0==ret) {
Expand Down Expand Up @@ -259,13 +261,17 @@ int main(int argc, char **argv) {
point.lpzt.lam = proj_torad (point.lpzt.lam);
point.lpzt.phi = proj_torad (point.lpzt.phi);
}
err = proj_errno_reset (P);
point = proj_trans (P, direction, point);

if (HUGE_VAL==point.xyzt.x) {
/* transformation error (TODO provide existing internal errmsg here) */
fprintf (fout, "# Record %d TRANSFORMATION ERROR: %s", (int) o->record_index, buf);
/* transformation error */
fprintf (fout, "# Record %d TRANSFORMATION ERROR: %s (%s)",
(int) o->record_index, buf, pj_strerrno (proj_errno(P)));
proj_errno_restore (P, err);
continue;
}
proj_errno_restore (P, err);

/* Time to print the result */
if (proj_angular_output (P, direction)) {
Expand Down
3 changes: 2 additions & 1 deletion src/gie.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,8 @@ static int expect (char *args) {

if (0==T.P && !expect_failure) {
banner (T.operation);
errmsg(3, "%sInvalid operation definition in line no. %d\n", delim, (int) T.operation_lineno);
errmsg(3, "%sInvalid operation definition in line no. %d: %s\n",
delim, (int) T.operation_lineno, pj_strerrno(proj_errno(T.P)));
return another_failure ();
}

Expand Down

0 comments on commit bea0c8b

Please sign in to comment.