diff options
| author | Kristian Evers <kristianevers@gmail.com> | 2016-05-02 17:49:00 +0200 |
|---|---|---|
| committer | Kristian Evers <kristianevers@gmail.com> | 2016-05-02 17:49:00 +0200 |
| commit | 359c182fa6f4d834192bb01b0f8170bc2b306247 (patch) | |
| tree | 527a94f91db98b27bb19a98992291ff377eba996 | |
| parent | 36e87f4100166694733e23df9572ef7ef1222532 (diff) | |
| download | PROJ-359c182fa6f4d834192bb01b0f8170bc2b306247.tar.gz PROJ-359c182fa6f4d834192bb01b0f8170bc2b306247.zip | |
Converted ocea
| -rw-r--r-- | src/PJ_aea.c | 1 | ||||
| -rw-r--r-- | src/PJ_ocea.c | 221 |
2 files changed, 149 insertions, 73 deletions
diff --git a/src/PJ_aea.c b/src/PJ_aea.c index d244f27e..ddf92a45 100644 --- a/src/PJ_aea.c +++ b/src/PJ_aea.c @@ -365,7 +365,6 @@ int pj_lonlat_selftest (void) {return 10000;} int pj_longlat_selftest (void) {return 10000;} int pj_ob_tran_selftest (void) {return 10000;} -int pj_ocea_selftest (void) {return 10000;} int pj_oea_selftest (void) {return 10000;} int pj_omerc_selftest (void) {return 10000;} int pj_ortho_selftest (void) {return 10000;} diff --git a/src/PJ_ocea.c b/src/PJ_ocea.c index b268e1b8..4727b09a 100644 --- a/src/PJ_ocea.c +++ b/src/PJ_ocea.c @@ -1,76 +1,153 @@ -#define PROJ_PARMS__ \ - double rok; \ - double rtk; \ - double sinphi; \ - double cosphi; \ - double singam; \ - double cosgam; #define PJ_LIB__ -#include <projects.h> +#include <projects.h> + PROJ_HEAD(ocea, "Oblique Cylindrical Equal Area") "\n\tCyl, Sph" - "lonc= alpha= or\n\tlat_1= lat_2= lon_1= lon_2="; -FORWARD(s_forward); /* spheroid */ - double t; - - xy.y = sin(lp.lam); -/* - xy.x = atan2((tan(lp.phi) * P->cosphi + P->sinphi * xy.y) , cos(lp.lam)); -*/ - t = cos(lp.lam); - xy.x = atan((tan(lp.phi) * P->cosphi + P->sinphi * xy.y) / t); - if (t < 0.) - xy.x += PI; - xy.x *= P->rtk; - xy.y = P->rok * (P->sinphi * sin(lp.phi) - P->cosphi * cos(lp.phi) * xy.y); - return (xy); + "lonc= alpha= or\n\tlat_1= lat_2= lon_1= lon_2="; + +struct pj_opaque { + double rok; + double rtk; + double sinphi; + double cosphi; + double singam; + double cosgam; +}; + + +static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ + XY xy = {0.0,0.0}; + struct pj_opaque *Q = P->opaque; + double t; + + xy.y = sin(lp.lam); + t = cos(lp.lam); + xy.x = atan((tan(lp.phi) * Q->cosphi + Q->sinphi * xy.y) / t); + if (t < 0.) + xy.x += PI; + xy.x *= Q->rtk; + xy.y = Q->rok * (Q->sinphi * sin(lp.phi) - Q->cosphi * cos(lp.phi) * xy.y); + return (xy); +} + + +static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ + LP lp = {0.0,0.0}; + struct pj_opaque *Q = P->opaque; + double t, s; + + xy.y /= Q->rok; + xy.x /= Q->rtk; + t = sqrt(1. - xy.y * xy.y); + lp.phi = asin(xy.y * Q->sinphi + t * Q->cosphi * (s = sin(xy.x))); + lp.lam = atan2(t * Q->sinphi * s - xy.y * Q->cosphi, + t * cos(xy.x)); + return (lp); +} + + +static void *freeup_new (PJ *P) { /* Destructor */ + if (0==P) + return 0; + if (0==P->opaque) + return pj_dealloc (P); + + pj_dealloc (P->opaque); + return pj_dealloc(P); +} + +static void freeup (PJ *P) { + freeup_new (P); + return; +} + + +PJ *PROJECTION(ocea) { + struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); + if (0==Q) + return freeup_new (P); + P->opaque = Q; + + double phi_0=0.0, phi_1, phi_2, lam_1, lam_2, lonz, alpha; + + Q->rok = P->a / P->k0; + Q->rtk = P->a * P->k0; + /*If the keyword "alpha" is found in the sentence then use 1point+1azimuth*/ + if ( pj_param(P->ctx, P->params, "talpha").i) { + /*Define Pole of oblique transformation from 1 point & 1 azimuth*/ + alpha = pj_param(P->ctx, P->params, "ralpha").f; + lonz = pj_param(P->ctx, P->params, "rlonc").f; + /*Equation 9-8 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ + Q->singam = atan(-cos(alpha)/(-sin(phi_0) * sin(alpha))) + lonz; + /*Equation 9-7 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ + Q->sinphi = asin(cos(phi_0) * sin(alpha)); + /*If the keyword "alpha" is NOT found in the sentence then use 2points*/ + } else { + /*Define Pole of oblique transformation from 2 points*/ + phi_1 = pj_param(P->ctx, P->params, "rlat_1").f; + phi_2 = pj_param(P->ctx, P->params, "rlat_2").f; + lam_1 = pj_param(P->ctx, P->params, "rlon_1").f; + lam_2 = pj_param(P->ctx, P->params, "rlon_2").f; + /*Equation 9-1 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ + Q->singam = atan2(cos(phi_1) * sin(phi_2) * cos(lam_1) - + sin(phi_1) * cos(phi_2) * cos(lam_2), + sin(phi_1) * cos(phi_2) * sin(lam_2) - + cos(phi_1) * sin(phi_2) * sin(lam_1) ); + /*Equation 9-2 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ + Q->sinphi = atan(-cos(Q->singam - lam_1) / tan(phi_1)); + } + P->lam0 = Q->singam + HALFPI; + Q->cosphi = cos(Q->sinphi); + Q->sinphi = sin(Q->sinphi); + Q->cosgam = cos(Q->singam); + Q->singam = sin(Q->singam); + P->inv = s_inverse; + P->fwd = s_forward; + P->es = 0.; + + return P; } -INVERSE(s_inverse); /* spheroid */ - double t, s; - - xy.y /= P->rok; - xy.x /= P->rtk; - t = sqrt(1. - xy.y * xy.y); - lp.phi = asin(xy.y * P->sinphi + t * P->cosphi * (s = sin(xy.x))); - lp.lam = atan2(t * P->sinphi * s - xy.y * P->cosphi, - t * cos(xy.x)); - return (lp); + + +#ifdef PJ_OMIT_SELFTEST +int pj_ocea_selftest (void) {return 0;} +#else + +int pj_ocea_selftest (void) { + double tolerance_lp = 1e-10; + double tolerance_xy = 1e-7; + + char s_args[] = {"+proj=ocea +a=6400000 +lat_1=0.5 +lat_2=2"}; + + LP fwd_in[] = { + { 2, 1}, + { 2,-1}, + {-2, 1}, + {-2,-1} + }; + + XY s_fwd_expect[] = { + {127964312562778.156, 1429265667691.05786}, + {129394957619297.641, 1429265667691.06812}, + {127964312562778.188, -1429265667691.0498}, + {129394957619297.688, -1429265667691.03955}, + }; + + XY inv_in[] = { + { 200, 100}, + { 200,-100}, + {-200, 100}, + {-200,-100} + }; + + LP s_inv_expect[] = { + { 179.999999999860108, 2.79764548403721305e-10}, + {-179.999999999860108, 2.7976454840372327e-10}, + { 179.999999999860108, -2.7976454840372327e-10}, + {-179.999999999860108, -2.79764548403721305e-10}, + }; + + return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); } -FREEUP; if (P) pj_dalloc(P); } -ENTRY0(ocea) - double phi_0=0.0, phi_1, phi_2, lam_1, lam_2, lonz, alpha; - - P->rok = P->a / P->k0; - P->rtk = P->a * P->k0; - /*If the keyword "alpha" is found in the sentence then use 1point+1azimuth*/ - if ( pj_param(P->ctx, P->params, "talpha").i) { - /*Define Pole of oblique transformation from 1 point & 1 azimuth*/ - alpha = pj_param(P->ctx, P->params, "ralpha").f; - lonz = pj_param(P->ctx, P->params, "rlonc").f; - /*Equation 9-8 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - P->singam = atan(-cos(alpha)/(-sin(phi_0) * sin(alpha))) + lonz; - /*Equation 9-7 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - P->sinphi = asin(cos(phi_0) * sin(alpha)); - /*If the keyword "alpha" is NOT found in the sentence then use 2points*/ - } else { - /*Define Pole of oblique transformation from 2 points*/ - phi_1 = pj_param(P->ctx, P->params, "rlat_1").f; - phi_2 = pj_param(P->ctx, P->params, "rlat_2").f; - lam_1 = pj_param(P->ctx, P->params, "rlon_1").f; - lam_2 = pj_param(P->ctx, P->params, "rlon_2").f; - /*Equation 9-1 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - P->singam = atan2(cos(phi_1) * sin(phi_2) * cos(lam_1) - - sin(phi_1) * cos(phi_2) * cos(lam_2), - sin(phi_1) * cos(phi_2) * sin(lam_2) - - cos(phi_1) * sin(phi_2) * sin(lam_1) ); - /*Equation 9-2 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - P->sinphi = atan(-cos(P->singam - lam_1) / tan(phi_1)); - } - P->lam0 = P->singam + HALFPI; - P->cosphi = cos(P->sinphi); - P->sinphi = sin(P->sinphi); - P->cosgam = cos(P->singam); - P->singam = sin(P->singam); - P->inv = s_inverse; - P->fwd = s_forward; - P->es = 0.; -ENDENTRY(P) + + +#endif |
