aboutsummaryrefslogtreecommitdiff
path: root/src/PJ_omerc.c
diff options
context:
space:
mode:
authorFrank Warmerdam <warmerdam@pobox.com>1999-03-18 16:34:52 +0000
committerFrank Warmerdam <warmerdam@pobox.com>1999-03-18 16:34:52 +0000
commit565a4bd035b9d4a83955808efef20f1d8dfa24cf (patch)
tree75785fc897708023f1ccdaf40079afcbaaf0fd3a /src/PJ_omerc.c
downloadPROJ-565a4bd035b9d4a83955808efef20f1d8dfa24cf.tar.gz
PROJ-565a4bd035b9d4a83955808efef20f1d8dfa24cf.zip
New
git-svn-id: http://svn.osgeo.org/metacrs/proj/trunk@776 4e78687f-474d-0410-85f9-8d5e500ac6b2
Diffstat (limited to 'src/PJ_omerc.c')
-rw-r--r--src/PJ_omerc.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/PJ_omerc.c b/src/PJ_omerc.c
new file mode 100644
index 00000000..5494186b
--- /dev/null
+++ b/src/PJ_omerc.c
@@ -0,0 +1,169 @@
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_omerc.c 4.2 95/01/01 GIE REL";
+#endif
+#define PROJ_PARMS__ \
+ double alpha, lamc, lam1, phi1, lam2, phi2, Gamma, al, bl, el, \
+ singam, cosgam, sinrot, cosrot, u_0; \
+ int ellips, rot;
+#define PJ_LIB__
+#include <projects.h>
+PROJ_HEAD(omerc, "Oblique Mercator")
+ "\n\tCyl, Sph&Ell\n\t no_rot rot_conv no_uoff and\n\t"
+"alpha= lonc= or\n\t lon_1= lat_1= lon_2= lat_2=";
+#define TOL 1.e-7
+#define EPS 1.e-10
+#define TSFN0(x) tan(.5 * (HALFPI - (x)))
+FORWARD(e_forward); /* ellipsoid & spheroid */
+ double con, q, s, ul, us, vl, vs;
+
+ vl = sin(P->bl * lp.lam);
+ if (fabs(fabs(lp.phi) - HALFPI) <= EPS) {
+ ul = lp.phi < 0. ? -P->singam : P->singam;
+ us = P->al * lp.phi / P->bl;
+ } else {
+ q = P->el / (P->ellips ? pow(pj_tsfn(lp.phi, sin(lp.phi), P->e), P->bl)
+ : TSFN0(lp.phi));
+ s = .5 * (q - 1. / q);
+ ul = 2. * (s * P->singam - vl * P->cosgam) / (q + 1. / q);
+ con = cos(P->bl * lp.lam);
+ if (fabs(con) >= TOL) {
+ us = P->al * atan((s * P->cosgam + vl * P->singam) / con) / P->bl;
+ if (con < 0.)
+ us += PI * P->al / P->bl;
+ } else
+ us = P->al * P->bl * lp.lam;
+ }
+ if (fabs(fabs(ul) - 1.) <= EPS) F_ERROR;
+ vs = .5 * P->al * log((1. - ul) / (1. + ul)) / P->bl;
+ us -= P->u_0;
+ if (! P->rot) {
+ xy.x = us;
+ xy.y = vs;
+ } else {
+ xy.x = vs * P->cosrot + us * P->sinrot;
+ xy.y = us * P->cosrot - vs * P->sinrot;
+ }
+ return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid & spheroid */
+ double q, s, ul, us, vl, vs;
+
+ if (! P->rot) {
+ us = xy.x;
+ vs = xy.y;
+ } else {
+ vs = xy.x * P->cosrot - xy.y * P->sinrot;
+ us = xy.y * P->cosrot + xy.x * P->sinrot;
+ }
+ us += P->u_0;
+ q = exp(- P->bl * vs / P->al);
+ s = .5 * (q - 1. / q);
+ vl = sin(P->bl * us / P->al);
+ ul = 2. * (vl * P->cosgam + s * P->singam) / (q + 1. / q);
+ if (fabs(fabs(ul) - 1.) < EPS) {
+ lp.lam = 0.;
+ lp.phi = ul < 0. ? -HALFPI : HALFPI;
+ } else {
+ lp.phi = P->el / sqrt((1. + ul) / (1. - ul));
+ if (P->ellips) {
+ if ((lp.phi = pj_phi2(pow(lp.phi, 1. / P->bl), P->e)) == HUGE_VAL)
+ I_ERROR;
+ } else
+ lp.phi = HALFPI - 2. * atan(lp.phi);
+ lp.lam = - atan2((s * P->cosgam -
+ vl * P->singam), cos(P->bl * us / P->al)) / P->bl;
+ }
+ return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(omerc)
+ double con, com, cosph0, d, f, h, l, sinph0, p, j;
+ int azi;
+
+ P->rot = pj_param(P->params, "bno_rot").i == 0;
+ if (azi = pj_param(P->params, "talpha").i) {
+ P->lamc = pj_param(P->params, "rlonc").f;
+ P->alpha = pj_param(P->params, "ralpha").f;
+ if ( fabs(P->alpha) <= TOL ||
+ fabs(fabs(P->phi0) - HALFPI) <= TOL ||
+ fabs(fabs(P->alpha) - HALFPI) <= TOL)
+ E_ERROR(-32);
+ } else {
+ P->lam1 = pj_param(P->params, "rlon_1").f;
+ P->phi1 = pj_param(P->params, "rlat_1").f;
+ P->lam2 = pj_param(P->params, "rlon_2").f;
+ P->phi2 = pj_param(P->params, "rlat_2").f;
+ if (fabs(P->phi1 - P->phi2) <= TOL ||
+ (con = fabs(P->phi1)) <= TOL ||
+ fabs(con - HALFPI) <= TOL ||
+ fabs(fabs(P->phi0) - HALFPI) <= TOL ||
+ fabs(fabs(P->phi2) - HALFPI) <= TOL) E_ERROR(-33);
+ }
+ com = (P->ellips = P->es > 0.) ? sqrt(P->one_es) : 1.;
+ if (fabs(P->phi0) > EPS) {
+ sinph0 = sin(P->phi0);
+ cosph0 = cos(P->phi0);
+ if (P->ellips) {
+ con = 1. - P->es * sinph0 * sinph0;
+ P->bl = cosph0 * cosph0;
+ P->bl = sqrt(1. + P->es * P->bl * P->bl / P->one_es);
+ P->al = P->bl * P->k0 * com / con;
+ d = P->bl * com / (cosph0 * sqrt(con));
+ } else {
+ P->bl = 1.;
+ P->al = P->k0;
+ d = 1. / cosph0;
+ }
+ if ((f = d * d - 1.) <= 0.)
+ f = 0.;
+ else {
+ f = sqrt(f);
+ if (P->phi0 < 0.)
+ f = -f;
+ }
+ P->el = f += d;
+ if (P->ellips) P->el *= pow(pj_tsfn(P->phi0, sinph0, P->e), P->bl);
+ else P->el *= TSFN0(P->phi0);
+ } else {
+ P->bl = 1. / com;
+ P->al = P->k0;
+ P->el = d = f = 1.;
+ }
+ if (azi) {
+ P->Gamma = asin(sin(P->alpha) / d);
+ P->lam0 = P->lamc - asin((.5 * (f - 1. / f)) *
+ tan(P->Gamma)) / P->bl;
+ } else {
+ if (P->ellips) {
+ h = pow(pj_tsfn(P->phi1, sin(P->phi1), P->e), P->bl);
+ l = pow(pj_tsfn(P->phi2, sin(P->phi2), P->e), P->bl);
+ } else {
+ h = TSFN0(P->phi1);
+ l = TSFN0(P->phi2);
+ }
+ f = P->el / h;
+ p = (l - h) / (l + h);
+ j = P->el * P->el;
+ j = (j - l * h) / (j + l * h);
+ if ((con = P->lam1 - P->lam2) < -PI)
+ P->lam2 -= TWOPI;
+ else if (con > PI)
+ P->lam2 += TWOPI;
+ P->lam0 = adjlon(.5 * (P->lam1 + P->lam2) - atan(
+ j * tan(.5 * P->bl * (P->lam1 - P->lam2)) / p) / P->bl);
+ P->Gamma = atan(2. * sin(P->bl * adjlon(P->lam1 - P->lam0)) /
+ (f - 1. / f));
+ P->alpha = asin(d * sin(P->Gamma));
+ }
+ P->singam = sin(P->Gamma);
+ P->cosgam = cos(P->Gamma);
+ f = pj_param(P->params, "brot_conv").i ? P->Gamma : P->alpha;
+ P->sinrot = sin(f);
+ P->cosrot = cos(f);
+ P->u_0 = pj_param(P->params, "bno_uoff").i ? 0. :
+ fabs(P->al * atan(sqrt(d * d - 1.) / P->cosrot) / P->bl);
+ if (P->phi0 < 0.)
+ P->u_0 = - P->u_0;
+ P->inv = e_inverse;
+ P->fwd = e_forward;
+ENDENTRY(P)