diff options
| author | Thomas Knudsen <lastname DOT firstname AT gmail DOT com> | 2016-04-01 23:10:44 +0200 |
|---|---|---|
| committer | Thomas Knudsen <lastname DOT firstname AT gmail DOT com> | 2016-04-01 23:10:44 +0200 |
| commit | 186c6e3303ccef8e833026e4e9dbaa76be6cb93b (patch) | |
| tree | b806475ab8896a3a9841cad737da0b8ee0d30859 /src/PJ_cass.c | |
| parent | a648ae934034924f15e1468b04bd986e007fd381 (diff) | |
| download | PROJ-186c6e3303ccef8e833026e4e9dbaa76be6cb93b.tar.gz PROJ-186c6e3303ccef8e833026e4e9dbaa76be6cb93b.zip | |
First steps toward simplified macros/internals
The brief version::
In an attempt to make proj.4 code slightly more secure and much easier
to read and maintain, I'm trying to eliminate a few unfortunate design
decisions from the early days of proj.4
The work will be *very* intrusive, especially in the PJ_xxx segment of
the code tree, but great care has been taken to design a process that
can be implemented stepwise and localized, one projection at a time,
then finalized with a relatively small and concentrated work package.
The (very) long version: See the comments in PJ_minimal.c
Diffstat (limited to 'src/PJ_cass.c')
| -rw-r--r-- | src/PJ_cass.c | 165 |
1 files changed, 106 insertions, 59 deletions
diff --git a/src/PJ_cass.c b/src/PJ_cass.c index 38fa9db5..5d7aea3c 100644 --- a/src/PJ_cass.c +++ b/src/PJ_cass.c @@ -1,79 +1,126 @@ -#define PROJ_PARMS__ \ - double m0; \ - double n; \ - double t; \ - double a1; \ - double c; \ - double r; \ - double dd; \ - double d2; \ - double a2; \ - double tn; \ - double *en; #define PJ_LIB__ # include <projects.h> PROJ_HEAD(cass, "Cassini") "\n\tCyl, Sph&Ell"; + + # define EPS10 1e-10 # define C1 .16666666666666666666 # define C2 .00833333333333333333 # define C3 .04166666666666666666 # define C4 .33333333333333333333 # define C5 .06666666666666666666 -FORWARD(e_forward); /* ellipsoid */ - xy.y = pj_mlfn(lp.phi, P->n = sin(lp.phi), P->c = cos(lp.phi), P->en); - P->n = 1./sqrt(1. - P->es * P->n * P->n); - P->tn = tan(lp.phi); P->t = P->tn * P->tn; - P->a1 = lp.lam * P->c; - P->c *= P->es * P->c / (1 - P->es); - P->a2 = P->a1 * P->a1; - xy.x = P->n * P->a1 * (1. - P->a2 * P->t * - (C1 - (8. - P->t + 8. * P->c) * P->a2 * C2)); - xy.y -= P->m0 - P->n * P->tn * P->a2 * - (.5 + (5. - P->t + 6. * P->c) * P->a2 * C3); - return (xy); + + +struct opaque { + /* These are the only opaque members actually initialized */ + double *en; + double m0; + + /* Apparently this group of opaque members should be demoted to local variables in e_forward and e_inverse */ + double n; + double t; + double a1; + double c; + double r; + double dd; + double d2; + double a2; + double tn; +}; + + + +static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */ + XY xy = {0.0,0.0}; + struct opaque *O = P->opaq; + xy.y = pj_mlfn(lp.phi, O->n = sin(lp.phi), O->c = cos(lp.phi), O->en); + O->n = 1./sqrt(1. - P->es * O->n * O->n); + O->tn = tan(lp.phi); O->t = O->tn * O->tn; + O->a1 = lp.lam * O->c; + O->c *= P->es * O->c / (1 - P->es); + O->a2 = O->a1 * O->a1; + xy.x = O->n * O->a1 * (1. - O->a2 * O->t * + (C1 - (8. - O->t + 8. * O->c) * O->a2 * C2)); + xy.y -= O->m0 - O->n * O->tn * O->a2 * + (.5 + (5. - O->t + 6. * O->c) * O->a2 * C3); + return xy; } -FORWARD(s_forward); /* spheroid */ + + +static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ + XY xy = {0.0,0.0}; xy.x = asin(cos(lp.phi) * sin(lp.lam)); xy.y = atan2(tan(lp.phi) , cos(lp.lam)) - P->phi0; - return (xy); + return xy; } -INVERSE(e_inverse); /* ellipsoid */ + + +static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ + LP lp = {0.0,0.0}; + struct opaque *O = P->opaq; double ph1; - ph1 = pj_inv_mlfn(P->ctx, P->m0 + xy.y, P->es, P->en); - P->tn = tan(ph1); P->t = P->tn * P->tn; - P->n = sin(ph1); - P->r = 1. / (1. - P->es * P->n * P->n); - P->n = sqrt(P->r); - P->r *= (1. - P->es) * P->n; - P->dd = xy.x / P->n; - P->d2 = P->dd * P->dd; - lp.phi = ph1 - (P->n * P->tn / P->r) * P->d2 * - (.5 - (1. + 3. * P->t) * P->d2 * C3); - lp.lam = P->dd * (1. + P->t * P->d2 * - (-C4 + (1. + 3. * P->t) * P->d2 * C5)) / cos(ph1); - return (lp); + ph1 = pj_inv_mlfn(P->ctx, O->m0 + xy.y, P->es, O->en); + O->tn = tan(ph1); O->t = O->tn * O->tn; + O->n = sin(ph1); + O->r = 1. / (1. - P->es * O->n * O->n); + O->n = sqrt(O->r); + O->r *= (1. - P->es) * O->n; + O->dd = xy.x / O->n; + O->d2 = O->dd * O->dd; + lp.phi = ph1 - (O->n * O->tn / O->r) * O->d2 * + (.5 - (1. + 3. * O->t) * O->d2 * C3); + lp.lam = O->dd * (1. + O->t * O->d2 * + (-C4 + (1. + 3. * O->t) * O->d2 * C5)) / cos(ph1); + return lp; } -INVERSE(s_inverse); /* spheroid */ - lp.phi = asin(sin(P->dd = xy.y + P->phi0) * cos(xy.x)); - lp.lam = atan2(tan(xy.x), cos(P->dd)); - return (lp); + + +static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ + LP lp = {0.0,0.0}; + lp.phi = asin(sin(P->opaq->dd = xy.y + P->phi0) * cos(xy.x)); + lp.lam = atan2(tan(xy.x), cos(P->opaq->dd)); + return lp; } -FREEUP; - if (P) { - if (P->en) - pj_dalloc(P->en); - pj_dalloc(P); - } + + +static void freeup(PJ *P) { /* Destructor */ + if (0==P) + return; + if (0==P->opaq) { + pj_dealloc (P); + return; + } + pj_dealloc(P->opaq->en); + pj_dealloc(P->opaq); + pj_dealloc(P); } -ENTRY1(cass, en) - if (P->es) { - if (!(P->en = pj_enfn(P->es))) E_ERROR_0; - P->m0 = pj_mlfn(P->phi0, sin(P->phi0), cos(P->phi0), P->en); - P->inv = e_inverse; - P->fwd = e_forward; - } else { + + +PJ *PROJECTION(cass) { + + /* Spheroidal? */ + if (0==P->es) { P->inv = s_inverse; P->fwd = s_forward; - } -ENDENTRY(P) + } + + /* Otherwise it's ellipsoidal */ + P->opaq = pj_calloc (1, sizeof (struct opaque)); + if (0==P->opaq) { + freeup (P); + return 0; + } + + P->opaq->en = pj_enfn(P->es); + if (0==P->opaq->en) { + freeup (P); + return 0; + } + + P->opaq->m0 = pj_mlfn(P->phi0, sin(P->phi0), cos(P->phi0), P->opaq->en); + P->inv = e_inverse; + P->fwd = e_forward; + + return P; +} |
