aboutsummaryrefslogtreecommitdiff
path: root/src/PJ_cass.c
diff options
context:
space:
mode:
authorThomas Knudsen <lastname DOT firstname AT gmail DOT com>2016-04-01 23:10:44 +0200
committerThomas Knudsen <lastname DOT firstname AT gmail DOT com>2016-04-01 23:10:44 +0200
commit186c6e3303ccef8e833026e4e9dbaa76be6cb93b (patch)
treeb806475ab8896a3a9841cad737da0b8ee0d30859 /src/PJ_cass.c
parenta648ae934034924f15e1468b04bd986e007fd381 (diff)
downloadPROJ-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.c165
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;
+}