Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libjni-proj4 / src / PJ_omerc.c @ 7098

History | View | Annotate | Download (4.77 KB)

1
#ifndef lint
2
static const char SCCSID[]="@(#)PJ_omerc.c        4.2        95/01/01        GIE        REL";
3
#endif
4
#define PROJ_PARMS__ \
5
        double        alpha, lamc, lam1, phi1, lam2, phi2, Gamma, al, bl, el, \
6
                singam, cosgam, sinrot, cosrot, u_0; \
7
        int                ellips, rot;
8
#define PJ_LIB__
9
#include        <projects.h>
10
PROJ_HEAD(omerc, "Oblique Mercator")
11
        "\n\tCyl, Sph&Ell\n\t no_rot rot_conv no_uoff and\n\t"
12
"alpha= lonc= or\n\t lon_1= lat_1= lon_2= lat_2=";
13
#define TOL        1.e-7
14
#define EPS        1.e-10
15
#define TSFN0(x)        tan(.5 * (HALFPI - (x)))
16
FORWARD(e_forward); /* ellipsoid & spheroid */
17
        double  con, q, s, ul, us, vl, vs;
18

    
19
        vl = sin(P->bl * lp.lam);
20
        if (fabs(fabs(lp.phi) - HALFPI) <= EPS) {
21
                ul = lp.phi < 0. ? -P->singam : P->singam;
22
                us = P->al * lp.phi / P->bl;
23
        } else {
24
                q = P->el / (P->ellips ? pow(pj_tsfn(lp.phi, sin(lp.phi), P->e), P->bl)
25
                        : TSFN0(lp.phi));
26
                s = .5 * (q - 1. / q);
27
                ul = 2. * (s * P->singam - vl * P->cosgam) / (q + 1. / q);
28
                con = cos(P->bl * lp.lam);
29
                if (fabs(con) >= TOL) {
30
                        us = P->al * atan((s * P->cosgam + vl * P->singam) / con) / P->bl;
31
                        if (con < 0.)
32
                                us += PI * P->al / P->bl;
33
                } else
34
                        us = P->al * P->bl * lp.lam;
35
        }
36
        if (fabs(fabs(ul) - 1.) <= EPS) F_ERROR;
37
        vs = .5 * P->al * log((1. - ul) / (1. + ul)) / P->bl;
38
        us -= P->u_0;
39
        if (! P->rot) {
40
                xy.x = us;
41
                xy.y = vs;
42
        } else {
43
                xy.x = vs * P->cosrot + us * P->sinrot;
44
                xy.y = us * P->cosrot - vs * P->sinrot;
45
        }
46
        return (xy);
47
}
48
INVERSE(e_inverse); /* ellipsoid & spheroid */
49
        double  q, s, ul, us, vl, vs;
50

    
51
        if (! P->rot) {
52
                us = xy.x;
53
                vs = xy.y;
54
        } else {
55
                vs = xy.x * P->cosrot - xy.y * P->sinrot;
56
                us = xy.y * P->cosrot + xy.x * P->sinrot;
57
        }
58
        us += P->u_0;
59
        q = exp(- P->bl * vs / P->al);
60
        s = .5 * (q - 1. / q);
61
        vl = sin(P->bl * us / P->al);
62
        ul = 2. * (vl * P->cosgam + s * P->singam) / (q + 1. / q);
63
        if (fabs(fabs(ul) - 1.) < EPS) {
64
                lp.lam = 0.;
65
                lp.phi = ul < 0. ? -HALFPI : HALFPI;
66
        } else {
67
                lp.phi = P->el / sqrt((1. + ul) / (1. - ul));
68
                if (P->ellips) {
69
                        if ((lp.phi = pj_phi2(pow(lp.phi, 1. / P->bl), P->e)) == HUGE_VAL)
70
                                I_ERROR;
71
                } else
72
                        lp.phi = HALFPI - 2. * atan(lp.phi);
73
                lp.lam = - atan2((s * P->cosgam -
74
                        vl * P->singam), cos(P->bl * us / P->al)) / P->bl;
75
        }
76
        return (lp);
77
}
78
FREEUP; if (P) pj_dalloc(P); }
79
ENTRY0(omerc)
80
        double con, com, cosph0, d, f, h, l, sinph0, p, j;
81
        int azi;
82

    
83
        P->rot        = pj_param(P->params, "bno_rot").i == 0;
84
        if( (azi        = pj_param(P->params, "talpha").i) != 0.0) {
85
                P->lamc        = pj_param(P->params, "rlonc").f;
86
                P->alpha        = pj_param(P->params, "ralpha").f;
87
                if ( fabs(P->alpha) <= TOL ||
88
                        fabs(fabs(P->phi0) - HALFPI) <= TOL ||
89
                        fabs(fabs(P->alpha) - HALFPI) <= TOL)
90
                        E_ERROR(-32);
91
        } else {
92
                P->lam1        = pj_param(P->params, "rlon_1").f;
93
                P->phi1        = pj_param(P->params, "rlat_1").f;
94
                P->lam2        = pj_param(P->params, "rlon_2").f;
95
                P->phi2        = pj_param(P->params, "rlat_2").f;
96
                if (fabs(P->phi1 - P->phi2) <= TOL ||
97
                        (con = fabs(P->phi1)) <= TOL ||
98
                        fabs(con - HALFPI) <= TOL ||
99
                        fabs(fabs(P->phi0) - HALFPI) <= TOL ||
100
                        fabs(fabs(P->phi2) - HALFPI) <= TOL) E_ERROR(-33);
101
        }
102
        com = (P->ellips = P->es > 0.) ? sqrt(P->one_es) : 1.;
103
        if (fabs(P->phi0) > EPS) {
104
                sinph0 = sin(P->phi0);
105
                cosph0 = cos(P->phi0);
106
                if (P->ellips) {
107
                        con = 1. - P->es * sinph0 * sinph0;
108
                        P->bl = cosph0 * cosph0;
109
                        P->bl = sqrt(1. + P->es * P->bl * P->bl / P->one_es);
110
                        P->al = P->bl * P->k0 * com / con;
111
                        d = P->bl * com / (cosph0 * sqrt(con));
112
                } else {
113
                        P->bl = 1.;
114
                        P->al = P->k0;
115
                        d = 1. / cosph0;
116
                }
117
                if ((f = d * d - 1.) <= 0.)
118
                        f = 0.;
119
                else {
120
                        f = sqrt(f);
121
                        if (P->phi0 < 0.)
122
                                f = -f;
123
                }
124
                P->el = f += d;
125
                if (P->ellips)        P->el *= pow(pj_tsfn(P->phi0, sinph0, P->e), P->bl);
126
                else                P->el *= TSFN0(P->phi0);
127
        } else {
128
                P->bl = 1. / com;
129
                P->al = P->k0;
130
                P->el = d = f = 1.;
131
        }
132
        if (azi) {
133
                P->Gamma = asin(sin(P->alpha) / d);
134
                P->lam0 = P->lamc - asin((.5 * (f - 1. / f)) *
135
                   tan(P->Gamma)) / P->bl;
136
        } else {
137
                if (P->ellips) {
138
                        h = pow(pj_tsfn(P->phi1, sin(P->phi1), P->e), P->bl);
139
                        l = pow(pj_tsfn(P->phi2, sin(P->phi2), P->e), P->bl);
140
                } else {
141
                        h = TSFN0(P->phi1);
142
                        l = TSFN0(P->phi2);
143
                }
144
                f = P->el / h;
145
                p = (l - h) / (l + h);
146
                j = P->el * P->el;
147
                j = (j - l * h) / (j + l * h);
148
                if ((con = P->lam1 - P->lam2) < -PI)
149
                        P->lam2 -= TWOPI;
150
                else if (con > PI)
151
                        P->lam2 += TWOPI;
152
                P->lam0 = adjlon(.5 * (P->lam1 + P->lam2) - atan(
153
                   j * tan(.5 * P->bl * (P->lam1 - P->lam2)) / p) / P->bl);
154
                P->Gamma = atan(2. * sin(P->bl * adjlon(P->lam1 - P->lam0)) /
155
                   (f - 1. / f));
156
                P->alpha = asin(d * sin(P->Gamma));
157
        }
158
        P->singam = sin(P->Gamma);
159
        P->cosgam = cos(P->Gamma);
160
        f = pj_param(P->params, "brot_conv").i ? P->Gamma : P->alpha;
161
        P->sinrot = sin(f);
162
        P->cosrot = cos(f);
163
        P->u_0 = pj_param(P->params, "bno_uoff").i ? 0. :
164
                fabs(P->al * atan(sqrt(d * d - 1.) / P->cosrot) / P->bl);
165
        if (P->phi0 < 0.)
166
                P->u_0 = - P->u_0;
167
        P->inv = e_inverse;
168
        P->fwd = e_forward;
169
ENDENTRY(P)