diff options
| author | Thomas Knudsen <busstoptaktik@users.noreply.github.com> | 2017-11-25 01:40:37 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-11-25 01:40:37 +0100 |
| commit | bea0c8b0c015ef0a5c136b904d63ad7f4a4427bf (patch) | |
| tree | 6ba55090efcbb1f0f3223e9eede71016b13d65c0 /src | |
| parent | a7a2c3d62570cf78c95650586ce36b522128892b (diff) | |
| download | PROJ-bea0c8b0c015ef0a5c136b904d63ad7f4a4427bf.tar.gz PROJ-bea0c8b0c015ef0a5c136b904d63ad7f4a4427bf.zip | |
Overhaul ellipsoid handling (#682)
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).
Diffstat (limited to 'src')
| -rw-r--r-- | src/PJ_deformation.c | 5 | ||||
| -rw-r--r-- | src/PJ_healpix.c | 2 | ||||
| -rw-r--r-- | src/PJ_pipeline.c | 32 | ||||
| -rw-r--r-- | src/cct.c | 12 | ||||
| -rw-r--r-- | src/gie.c | 3 | ||||
| -rw-r--r-- | src/pj_ell_set.c | 182 | ||||
| -rw-r--r-- | src/pj_init.c | 42 | ||||
| -rw-r--r-- | src/proj.def | 2 | ||||
| -rw-r--r-- | src/proj_internal.h | 6 |
9 files changed, 177 insertions, 109 deletions
diff --git a/src/PJ_deformation.c b/src/PJ_deformation.c index 81dd602d..09692ccb 100644 --- a/src/PJ_deformation.c +++ b/src/PJ_deformation.c @@ -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; diff --git a/src/PJ_healpix.c b/src/PJ_healpix.c index 5becfd74..41f62ee4 100644 --- a/src/PJ_healpix.c +++ b/src/PJ_healpix.c @@ -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 { diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index 19b8e18d..35f79213 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -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; @@ -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); } @@ -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); @@ -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 */ @@ -415,14 +425,22 @@ 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])) @@ -430,7 +448,7 @@ PJ *OPERATION(pipeline,0) { 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); @@ -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; } - @@ -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); @@ -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) { @@ -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)) { @@ -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 (); } diff --git a/src/pj_ell_set.c b/src/pj_ell_set.c index 18beb875..d21122e3 100644 --- a/src/pj_ell_set.c +++ b/src/pj_ell_set.c @@ -5,18 +5,12 @@ #include "proj_internal.h" #include "projects.h" -/* series coefficients for calculating ellipsoid-equivalent spheres */ -#define SIXTH .1666666666666666667 /* 1/6 */ -#define RA4 .04722222222222222222 /* 17/360 */ -#define RA6 .02215608465608465608 /* 67/3024 */ -#define RV4 .06944444444444444444 /* 5/72 */ -#define RV6 .04243827160493827160 /* 55/1296 */ /* Prototypes of the pj_ellipsoid helper functions */ -static int pj_ellps_handler (PJ *P); -static int pj_size (PJ *P); -static int pj_shape (PJ *P); -static int pj_spherification (PJ *P); +static int ellps_ellps (PJ *P); +static int ellps_size (PJ *P); +static int ellps_shape (PJ *P); +static int ellps_spherification (PJ *P); static paralist *pj_get_param (paralist *list, char *key); static char *pj_param_value (paralist *list); @@ -69,7 +63,7 @@ int pj_ellipsoid (PJ *P) { If R is given as size parameter, any shape and spherification parameters given are ignored. - If size and shape is given as ellps=xxx, later shape and size parameters + If size and shape are given as ellps=xxx, later shape and size parameters are are taken into account as modifiers for the built in ellipsoid definition. While this may seem strange, it is in accordance with historical PROJ @@ -77,110 +71,123 @@ int pj_ellipsoid (PJ *P) { scaled to unit semimajor axis by specifying "+ellps=xxx +a=1" ****************************************************************************************/ - int last_errno; - - last_errno = proj_errno_reset (P); + int err = proj_errno_reset (P); + char *empty = {""}; P->def_size = P->def_shape = P->def_spherification = P->def_ellps = 0; + /* Specifying R overrules everything */ + if (pj_get_param (P->params, "R")) { + ellps_size (P); + pj_calc_ellipsoid_params (P, P->a, 0); + if (proj_errno (P)) + return 1; + return proj_errno_restore (P, err); + } + + /* If an ellps argument is specified, start by using that */ - if (0 != pj_ellps_handler (P)) - return proj_errno (P); + if (0 != ellps_ellps (P)) + return 1; /* We may overwrite the size */ - if (0 != pj_size (P)) - return proj_errno (P); + if (0 != ellps_size (P)) + return 2; /* We may also overwrite the shape */ - if (0 != pj_shape (P)) - return proj_errno (P); + if (0 != ellps_shape (P)) + return 3; /* When we're done with it, we compute all related ellipsoid parameters */ - pj_calc_ellps_params (P, P->a, P->es); + pj_calc_ellipsoid_params (P, P->a, P->es); /* And finally, we may turn it into a sphere */ - if (0 != pj_spherification (P)) - return proj_errno (P); + if (0 != ellps_spherification (P)) + return 4; + + proj_log_debug (P, "pj_ellipsoid - final: a=%.3f f=1/%7.3f, errno=%d", + P->a, P->f!=0? 1/P->f: 0, proj_errno (P)); + proj_log_debug (P, "pj_ellipsoid - final: %s %s %s %s", + P->def_size? P->def_size: empty, + P->def_shape? P->def_shape: empty, + P->def_spherification? P->def_spherification: empty, + P->def_ellps? P->def_ellps: empty ); if (proj_errno (P)) - return proj_errno (P); + return 5; - /* success - restore previous error status */ - return proj_errno_restore (P, last_errno); + /* success */ + return proj_errno_restore (P, err); } /***************************************************************************************/ -static int pj_ellps_handler (PJ *P) { +static int ellps_ellps (PJ *P) { /***************************************************************************************/ PJ B; PJ_ELLPS *ellps; paralist *par = 0; - char *def, *name; + char *name; + int err; - /* ellps specified? */ + /* Sail home if ellps=xxx is not specified */ par = pj_get_param (P->params, "ellps"); if (0==par) return 0; - /* This amounts to zeroing all ellipsoidal parameters in P */ - memset (&B, 0, sizeof (B)); - pj_inherit_ellipsoid_defs(&B, P); + /* Otherwise produce a fake PJ to make ellps_size/ellps_shape do the hard work for us */ - /* move B into P's context */ + /* First move B into P's context to get error messages onto the right channel */ B.ctx = P->ctx; - /* Store definition */ - P->def_ellps = def = par->param; - par->used = 1; - - if (strlen (def) < 7) + /* Then look up the right size and shape parameters from the builtin list */ + if (strlen (par->param) < 7) return proj_errno_set (P, PJD_ERR_INVALID_ARG); - name = def + 6; + name = par->param + 6; ellps = pj_find_ellps (name); if (0==ellps) return proj_errno_set (P, PJD_ERR_UNKNOWN_ELLP_PARAM); - /* Now, we have the right size and shape parameters and can produce */ - /* a fake PJ to make pj_shape do the hard work for us */ + /* Now, get things ready for ellps_size/ellps_shape, make them do their thing, and clean up */ + err = proj_errno_reset (P); B = *P; + pj_erase_ellipsoid_def (&B); B.params = pj_mkparam (ellps->major); B.params->next = pj_mkparam (ellps->ell); - pj_size (&B); - pj_shape (&B); - - P->a = B.a; - P->b = B.b; - P->f = B.f; - P->e = B.e; - P->es = B.es; + ellps_size (&B); + ellps_shape (&B); pj_dealloc (B.params->next); pj_dealloc (B.params); if (proj_errno (&B)) return proj_errno (&B); - return 0; + + /* Finally update P and sail home */ + pj_inherit_ellipsoid_def (&B, P); + P->def_ellps = par->param; + par->used = 1; + + return proj_errno_restore (P, err); } /***************************************************************************************/ -static int pj_size (PJ *P) { +static int ellps_size (PJ *P) { /***************************************************************************************/ - char *keys[] = {"R", "a"}; paralist *par = 0; - size_t i, len; - len = sizeof (keys) / sizeof (char *); - /* Check which size key is specified */ - for (i = 0; i < len; i++) { - par = pj_get_param (P->params, keys[i]); - if (par) - break; - } + int a_was_set = 0; /* A size parameter *must* be given, but may have been given as ellps prior */ + if (P->a != 0) + a_was_set = 1; + + /* Check which size key is specified */ + par = pj_get_param (P->params, "R"); + if (0==par) + par = pj_get_param (P->params, "a"); if (0==par) - return 0!=P->a? 0: proj_errno_set (P, PJD_ERR_MAJOR_AXIS_NOT_GIVEN); + return a_was_set? 0: proj_errno_set (P, PJD_ERR_MAJOR_AXIS_NOT_GIVEN); P->def_size = par->param; par->used = 1; @@ -199,7 +206,7 @@ static int pj_size (PJ *P) { /***************************************************************************************/ -static int pj_shape (PJ *P) { +static int ellps_shape (PJ *P) { /***************************************************************************************/ char *keys[] = {"rf", "f", "es", "e", "b"}; paralist *par = 0; @@ -282,6 +289,8 @@ static int pj_shape (PJ *P) { return proj_errno_set (P, PJD_ERR_INVALID_ARG); if (0==P->b) return proj_errno_set (P, PJD_ERR_ECCENTRICITY_IS_ONE); + if (P->b==P->a) + break; P->f = (P->a - P->b) / P->a; P->es = 2*P->f - P->f*P->f; break; @@ -289,14 +298,22 @@ static int pj_shape (PJ *P) { return PJD_ERR_INVALID_ARG; } + if (P->es < 0) return proj_errno_set (P, PJD_ERR_ES_LESS_THAN_ZERO); return 0; } +/* series coefficients for calculating ellipsoid-equivalent spheres */ +static const double SIXTH = 1/6.; +static const double RA4 = 17/360.; +static const double RA6 = 67/3024.; +static const double RV4 = 5/72.; +static const double RV6 = 55/1296.; + /***************************************************************************************/ -static int pj_spherification (PJ *P) { +static int ellps_spherification (PJ *P) { /***************************************************************************************/ char *keys[] = {"R_A", "R_V", "R_a", "R_g", "R_h", "R_lat_a", "R_lat_g"}; size_t len, i; @@ -371,17 +388,15 @@ static int pj_spherification (PJ *P) { } /* Clean up the ellipsoidal parameters to reflect the sphere */ - P->es = P->e = P->rf = P->f = 0; + P->es = P->e = P->f = 0; + P->rf = HUGE_VAL; P->b = P->a; - pj_calc_ellps_params (P, P->a, 0); + pj_calc_ellipsoid_params (P, P->a, 0); return 0; } - - - /* locate parameter in list */ static paralist *pj_get_param (paralist *list, char *key) { size_t l = strlen(key); @@ -418,11 +433,28 @@ static PJ_ELLPS *pj_find_ellps (char *name) { } +/**************************************************************************************/ +void pj_erase_ellipsoid_def (PJ *P) { +/*************************************************************************************** + Erase all ellipsoidal parameters in P +***************************************************************************************/ + PJ B; + + /* Make a blank PJ to copy from */ + memset (&B, 0, sizeof (B)); + /* And use it to overwrite all existing ellipsoid defs */ + pj_inherit_ellipsoid_def (&B, P); +} -/* copy ellipsoidal parameters from src to dst */ -void pj_inherit_ellipsoid_defs(const PJ *src, PJ *dst) { +/**************************************************************************************/ +void pj_inherit_ellipsoid_def (const PJ *src, PJ *dst) { +/*************************************************************************************** + Brute force copy the ellipsoidal parameters from src to dst. This code was + written before the actual ellipsoid setup parameters were kept available in + the PJ->def_xxx elements. +***************************************************************************************/ /* The linear parameters */ dst->a = src->a; @@ -459,7 +491,7 @@ void pj_inherit_ellipsoid_defs(const PJ *src, PJ *dst) { /***************************************************************************************/ -int pj_calc_ellps_params(PJ *P, double a, double es) { +int pj_calc_ellipsoid_params (PJ *P, double a, double es) { /**************************************************************************************** Calculate a large number of ancillary ellipsoidal parameters, in addition to the two traditional PROJ defining parameters: Semimajor axis, a, and the @@ -535,7 +567,12 @@ int pj_calc_ellps_params(PJ *P, double a, double es) { #ifndef KEEP_ORIGINAL_PJ_ELL_SET -int pj_ell_set(projCtx ctx, paralist *pl, double *a, double *es) { +/**************************************************************************************/ +int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) { +/*************************************************************************************** + Initialize ellipsoidal parameters by emulating the original ellipsoid setup + function by Gerald Evenden, through a call to pj_ellipsoid +***************************************************************************************/ PJ B; int ret; @@ -554,7 +591,6 @@ int pj_ell_set(projCtx ctx, paralist *pl, double *a, double *es) { #else - /**************************************************************************************/ int pj_ell_set (projCtx ctx, paralist *pl, double *a, double *es) { /*************************************************************************************** diff --git a/src/pj_init.c b/src/pj_init.c index 62dea1f2..f8492650 100644 --- a/src/pj_init.c +++ b/src/pj_init.c @@ -219,23 +219,30 @@ get_opt(projCtx ctx, paralist **start, PAFile fid, char *name, paralist *next, strncpy(sword+1, start_of_word, word_len); sword[word_len+1] = '\0'; - /* do not override existing parameter value of same name - unless in pipeline definition */ + /* do not override existing parameter value of same name */ if (!pj_param(ctx, *start, sword).i) { - /* don't default ellipse if datum, ellps or any earth model - information is set. */ - if( strncmp(sword+1,"ellps=",6) != 0 - || (!pj_param(ctx, *start, "tdatum").i - && !pj_param(ctx, *start, "tellps").i - && !pj_param(ctx, *start, "ta").i - && !pj_param(ctx, *start, "tb").i - && !pj_param(ctx, *start, "trf").i - && !pj_param(ctx, *start, "tf").i) ) - { - next = next->next = pj_mkparam(sword+1); + + /* don't default ellipse if datum, ellps or any earth model information is set */ + if (0==strncmp(sword,"tellps=", 7)) { + int n = 0; + + n += pj_param(ctx, *start, "tdatum").i; + n += pj_param(ctx, *start, "tellps").i; + n += pj_param(ctx, *start, "ta").i; + n += pj_param(ctx, *start, "tb").i; + n += pj_param(ctx, *start, "trf").i; + n += pj_param(ctx, *start, "tf").i; + n += pj_param(ctx, *start, "te").i; + n += pj_param(ctx, *start, "tes").i; + + if (0==n) + next = next->next = pj_mkparam(sword+1); } else next = next->next = pj_mkparam(sword+1); } + + } else { @@ -434,6 +441,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { PJ *(*proj)(PJ *); paralist *curr; int i; + int err; int found_def = 0; PJ *PIN = 0; int n_pipelines = 0; @@ -536,13 +544,14 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { return pj_default_destructor (PIN, PJD_ERR_MISSING_ARGS); if (PIN->need_ellps) { - if (0 != pj_ellipsoid (PIN)) { + int ret = pj_ellipsoid (PIN); + if (0 != ret) { pj_log (ctx, PJ_LOG_DEBUG_MINOR, "pj_init_ctx: Must specify ellipsoid or sphere"); return pj_default_destructor (PIN, PJD_ERR_MISSING_ARGS); } PIN->a_orig = PIN->a; PIN->es_orig = PIN->es; - if (pj_calc_ellps_params(PIN, PIN->a, PIN->es)) + if (pj_calc_ellipsoid_params (PIN, PIN->a, PIN->es)) return pj_default_destructor (PIN, PJD_ERR_ECCENTRICITY_IS_ONE); } @@ -700,12 +709,13 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { geod_init(PIN->geod, PIN->a, (1 - sqrt (1 - PIN->es))); /* projection specific initialization */ + err = proj_errno_reset (PIN); PIN = proj(PIN); - if ((0==PIN) || ctx->last_errno) - { + if (proj_errno (PIN)) { pj_free(PIN); return 0; } + proj_errno_restore (PIN, err); return PIN; } diff --git a/src/proj.def b/src/proj.def index ca10489a..d5faae91 100644 --- a/src/proj.def +++ b/src/proj.def @@ -149,4 +149,4 @@ EXPORTS proj_angular_output @134 pj_ellipsoid @135 - pj_calc_ellps_params @136 + pj_calc_ellipsoid_params @136 diff --git a/src/proj_internal.h b/src/proj_internal.h index 95f34994..fd6dc75d 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -101,11 +101,11 @@ typedef void (*PJ_LOG_FUNCTION)(void *, int, const char *); void proj_log_error (PJ *P, const char *fmt, ...); void proj_log_debug (PJ *P, const char *fmt, ...); void proj_log_trace (PJ *P, const char *fmt, ...); -/*void proj_log_func (PJ *P, void *app_data, void (*log)(void *, int, const char *));*/ void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION log); -void pj_inherit_ellipsoid_defs(const PJ *src, PJ *dst); -int pj_calc_ellps_params(PJ *P, double a, double es); +void pj_inherit_ellipsoid_def (const PJ *src, PJ *dst); +void pj_erase_ellipsoid_def (PJ *P); +int pj_calc_ellipsoid_params (PJ *P, double a, double es); /* Lowest level: Minimum support for fileapi */ void proj_fileapi_set (PJ *P, void *fileapi); |
