diff options
| author | Thomas Knudsen <lastname DOT firstname AT gmail DOT com> | 2016-04-12 17:25:22 +0200 |
|---|---|---|
| committer | Thomas Knudsen <lastname DOT firstname AT gmail DOT com> | 2016-04-12 17:25:22 +0200 |
| commit | 86a3221bdc26ea2cdbe85fcf270263ce02fef0e6 (patch) | |
| tree | 3d50ff375a58f75a9f6ff0e4d8d9f957449318fc /src/PJ_cass.c | |
| parent | f50841c72455fe01c3d7a3310c1eba9b5eec40b8 (diff) | |
| download | PROJ-86a3221bdc26ea2cdbe85fcf270263ce02fef0e6.tar.gz PROJ-86a3221bdc26ea2cdbe85fcf270263ce02fef0e6.zip | |
refactoring + added selftest for 8 more projections
calcofi, cass,cc,wag2, wag3, wag7, wink1, wink2
Diffstat (limited to 'src/PJ_cass.c')
| -rw-r--r-- | src/PJ_cass.c | 196 |
1 files changed, 122 insertions, 74 deletions
diff --git a/src/PJ_cass.c b/src/PJ_cass.c index 5f885376..28d35b91 100644 --- a/src/PJ_cass.c +++ b/src/PJ_cass.c @@ -1,96 +1,90 @@ #define PJ_LIB__ -# include <projects.h> +# 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 +# define EPS10 1e-10 +# define C1 .16666666666666666666 +# define C2 .00833333333333333333 +# define C3 .04166666666666666666 +# define C4 .33333333333333333333 +# define C5 .06666666666666666666 struct pj_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; + double *en; + double m0; }; static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */ - XY xy = {0.0,0.0}; + double n, t, a1, c, a2, tn; + XY xy = {0.0, 0.0}; struct pj_opaque *Q = P->opaque; - xy.y = pj_mlfn(lp.phi, Q->n = sin(lp.phi), Q->c = cos(lp.phi), Q->en); - Q->n = 1./sqrt(1. - P->es * Q->n * Q->n); - Q->tn = tan(lp.phi); Q->t = Q->tn * Q->tn; - Q->a1 = lp.lam * Q->c; - Q->c *= P->es * Q->c / (1 - P->es); - Q->a2 = Q->a1 * Q->a1; - xy.x = Q->n * Q->a1 * (1. - Q->a2 * Q->t * - (C1 - (8. - Q->t + 8. * Q->c) * Q->a2 * C2)); - xy.y -= Q->m0 - Q->n * Q->tn * Q->a2 * - (.5 + (5. - Q->t + 6. * Q->c) * Q->a2 * C3); - return xy; + + xy.y = pj_mlfn (lp.phi, n = sin (lp.phi), c = cos (lp.phi), Q->en); + + n = 1./sqrt(1. - P->es * n*n); + tn = tan(lp.phi); t = tn * tn; + a1 = lp.lam * c; + c *= P->es * c / (1 - P->es); + a2 = a1 * a1; + + xy.x = n * a1 * (1. - a2 * t * + (C1 - (8. - t + 8. * c) * a2 * C2)); + xy.y -= Q->m0 - n * tn * a2 * + (.5 + (5. - t + 6. * c) * a2 * C3); + + return xy; } 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; + 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; } static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ - LP lp = {0.0,0.0}; + double n, t, r, dd, d2, tn, ph1; + LP lp = {0.0, 0.0}; struct pj_opaque *Q = P->opaque; - double ph1; - - ph1 = pj_inv_mlfn(P->ctx, Q->m0 + xy.y, P->es, Q->en); - Q->tn = tan(ph1); Q->t = Q->tn * Q->tn; - Q->n = sin(ph1); - Q->r = 1. / (1. - P->es * Q->n * Q->n); - Q->n = sqrt(Q->r); - Q->r *= (1. - P->es) * Q->n; - Q->dd = xy.x / Q->n; - Q->d2 = Q->dd * Q->dd; - lp.phi = ph1 - (Q->n * Q->tn / Q->r) * Q->d2 * - (.5 - (1. + 3. * Q->t) * Q->d2 * C3); - lp.lam = Q->dd * (1. + Q->t * Q->d2 * - (-C4 + (1. + 3. * Q->t) * Q->d2 * C5)) / cos(ph1); - return lp; + + ph1 = pj_inv_mlfn (P->ctx, Q->m0 + xy.y, P->es, Q->en); + tn = tan (ph1); t = tn*tn; + n = sin (ph1); + r = 1. / (1. - P->es * n * n); + n = sqrt (r); + r *= (1. - P->es) * n; + dd = xy.x / n; + d2 = dd * dd; + lp.phi = ph1 - (n * tn / r) * d2 * + (.5 - (1. + 3. * t) * d2 * C3); + lp.lam = dd * (1. + t * d2 * + (-C4 + (1. + 3. * t) * d2 * C5)) / cos (ph1); + return lp; } static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ LP lp = {0.0,0.0}; - lp.phi = asin(sin(P->opaque->dd = xy.y + P->phi0) * cos(xy.x)); - lp.lam = atan2(tan(xy.x), cos(P->opaque->dd)); - return lp; + double dd; + lp.phi = asin(sin(dd = xy.y + P->phi0) * cos(xy.x)); + lp.lam = atan2(tan(xy.x), cos(dd)); + return lp; } static void *freeup_new(PJ *P) { /* Destructor */ - if (0==P) + if (0==P) return 0; if (0==P->opaque) return pj_dealloc (P); - pj_dealloc(P->opaque->en); + pj_dealloc(P->opaque->en); pj_dealloc(P->opaque); return pj_dealloc(P); } @@ -103,28 +97,82 @@ static void freeup(PJ *P) { /* Destructor */ PJ *PROJECTION(cass) { /* Spheroidal? */ - if (0==P->es) { - P->inv = s_inverse; - P->fwd = s_forward; + if (0==P->es) { + P->inv = s_inverse; + P->fwd = s_forward; return P; } - /* Otherwise it's ellipsoidal */ + /* otherwise it's ellipsoidal */ P->opaque = pj_calloc (1, sizeof (struct pj_opaque)); - if (0==P->opaque) { - freeup (P); - return 0; - } + if (0==P->opaque) + return freeup_new (P); - P->opaque->en = pj_enfn(P->es); - if (0==P->opaque->en) { - freeup (P); - return 0; - } + P->opaque->en = pj_enfn (P->es); + if (0==P->opaque->en) + return freeup_new (P); - P->opaque->m0 = pj_mlfn(P->phi0, sin(P->phi0), cos(P->phi0), P->opaque->en); - P->inv = e_inverse; - P->fwd = e_forward; + P->opaque->m0 = pj_mlfn (P->phi0, sin (P->phi0), cos (P->phi0), P->opaque->en); + P->inv = e_inverse; + P->fwd = e_forward; return P; } + + +#ifdef PJ_OMIT_SELFTEST +int pj_cass_selftest (void) {return 0;} +#else + +int pj_cass_selftest (void) { + double tolerance_lp = 1e-10; + double tolerance_xy = 1e-7; + + char e_args[] = {"+proj=cass +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; + char s_args[] = {"+proj=cass +a=6400000 +lat_1=0.5 +lat_2=2"}; + + LP fwd_in[] = { + { 2, 1}, + { 2,-1}, + {-2, 1}, + {-2,-1} + }; + + XY e_fwd_expect[] = { + { 222605.28577699114, 110642.22925399939}, + { 222605.28577699114, -110642.22925399939}, + {-222605.28577699114, 110642.22925399939}, + {-222605.28577699114, -110642.22925399939}, + }; + + XY s_fwd_expect[] = { + { 223368.10520348375, 111769.14504058579}, + { 223368.10520348375, -111769.14504058579}, + {-223368.10520348375, 111769.14504058579}, + {-223368.10520348375, -111769.14504058579}, + }; + + XY inv_in[] = { + { 200, 100}, + { 200,-100}, + {-200, 100}, + {-200,-100} + }; + + LP e_inv_expect[] = { + { 0.0017966305684613522, 0.00090436947663183841}, + { 0.0017966305684613522, -0.00090436947663183841}, + {-0.0017966305684613522, 0.00090436947663183841}, + {-0.0017966305684613522, -0.00090436947663183841}, + }; + + LP s_inv_expect[] = { + { 0.0017904931100023887, 0.00089524655445477922}, + { 0.0017904931100023887, -0.00089524655445477922}, + {-0.0017904931100023887, 0.00089524655445477922}, + {-0.0017904931100023887, -0.00089524655445477922}, + }; + + return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); +} +#endif |
