Statistics
| Revision:

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

History | View | Annotate | Download (5.74 KB)

1
#ifndef lint
2
static const char SCCSID[]="@(#)PJ_stere.c        4.1        94/02/15        GIE        REL";
3
#endif
4
#define PROJ_PARMS__ \
5
        double phits; \
6
        double sinX1; \
7
        double cosX1; \
8
        double akm1; \
9
        int        mode;
10
#define PJ_LIB__
11
#include        <projects.h>
12
PROJ_HEAD(stere, "Stereographic") "\n\tAzi, Sph&Ell\n\tlat_ts=";
13
PROJ_HEAD(ups, "Universal Polar Stereographic") "\n\tAzi, Sph&Ell\n\tsouth";
14
#define sinph0        P->sinX1
15
#define cosph0        P->cosX1
16
#define EPS10        1.e-10
17
#define TOL        1.e-8
18
#define NITER        8
19
#define CONV        1.e-10
20
#define S_POLE        0
21
#define N_POLE        1
22
#define OBLIQ        2
23
#define EQUIT        3
24
        static double
25
ssfn_(double phit, double sinphi, double eccen) {
26
        sinphi *= eccen;
27
        return (tan (.5 * (HALFPI + phit)) *
28
           pow((1. - sinphi) / (1. + sinphi), .5 * eccen));
29
}
30
FORWARD(e_forward); /* ellipsoid */
31
        double coslam, sinlam, sinX=0.0, cosX=0.0, X, A, sinphi;
32

    
33
        coslam = cos(lp.lam);
34
        sinlam = sin(lp.lam);
35
        sinphi = sin(lp.phi);
36
        if (P->mode == OBLIQ || P->mode == EQUIT) {
37
                sinX = sin(X = 2. * atan(ssfn_(lp.phi, sinphi, P->e)) - HALFPI);
38
                cosX = cos(X);
39
        }
40
        switch (P->mode) {
41
        case OBLIQ:
42
                A = P->akm1 / (P->cosX1 * (1. + P->sinX1 * sinX +
43
                   P->cosX1 * cosX * coslam));
44
                xy.y = A * (P->cosX1 * sinX - P->sinX1 * cosX * coslam);
45
                goto xmul;
46
        case EQUIT:
47
                A = 2. * P->akm1 / (1. + cosX * coslam);
48
                xy.y = A * sinX;
49
xmul:
50
                xy.x = A * cosX;
51
                break;
52
        case S_POLE:
53
                lp.phi = -lp.phi;
54
                coslam = - coslam;
55
                sinphi = -sinphi;
56
        case N_POLE:
57
                xy.x = P->akm1 * pj_tsfn(lp.phi, sinphi, P->e);
58
                xy.y = - xy.x * coslam;
59
                break;
60
        }
61
        xy.x = xy.x * sinlam;
62
        return (xy);
63
}
64
FORWARD(s_forward); /* spheroid */
65
        double  sinphi, cosphi, coslam, sinlam;
66

    
67
        sinphi = sin(lp.phi);
68
        cosphi = cos(lp.phi);
69
        coslam = cos(lp.lam);
70
        sinlam = sin(lp.lam);
71
        switch (P->mode) {
72
        case EQUIT:
73
                xy.y = 1. + cosphi * coslam;
74
                goto oblcon;
75
        case OBLIQ:
76
                xy.y = 1. + sinph0 * sinphi + cosph0 * cosphi * coslam;
77
oblcon:
78
                if (xy.y <= EPS10) F_ERROR;
79
                xy.x = (xy.y = P->akm1 / xy.y) * cosphi * sinlam;
80
                xy.y *= (P->mode == EQUIT) ? sinphi :
81
                   cosph0 * sinphi - sinph0 * cosphi * coslam;
82
                break;
83
        case N_POLE:
84
                coslam = - coslam;
85
                lp.phi = - lp.phi;
86
        case S_POLE:
87
                if (fabs(lp.phi - HALFPI) < TOL) F_ERROR;
88
                xy.x = sinlam * ( xy.y = P->akm1 * tan(FORTPI + .5 * lp.phi) );
89
                xy.y *= coslam;
90
                break;
91
        }
92
        return (xy);
93
}
94
INVERSE(e_inverse); /* ellipsoid */
95
        double cosphi, sinphi, tp=0.0, phi_l=0.0, rho, halfe=0.0, halfpi=0.0;
96
        int i;
97

    
98
        rho = hypot(xy.x, xy.y);
99
        switch (P->mode) {
100
        case OBLIQ:
101
        case EQUIT:
102
                cosphi = cos( tp = 2. * atan2(rho * P->cosX1 , P->akm1) );
103
                sinphi = sin(tp);
104
                if( rho == 0.0 )
105
                    phi_l = asin(cosphi * P->sinX1);
106
                else
107
                    phi_l = asin(cosphi * P->sinX1 + (xy.y * sinphi * P->cosX1 / rho));
108

    
109
                tp = tan(.5 * (HALFPI + phi_l));
110
                xy.x *= sinphi;
111
                xy.y = rho * P->cosX1 * cosphi - xy.y * P->sinX1* sinphi;
112
                halfpi = HALFPI;
113
                halfe = .5 * P->e;
114
                break;
115
        case N_POLE:
116
                xy.y = -xy.y;
117
        case S_POLE:
118
                phi_l = HALFPI - 2. * atan(tp = - rho / P->akm1);
119
                halfpi = -HALFPI;
120
                halfe = -.5 * P->e;
121
                break;
122
        }
123
        for (i = NITER; i--; phi_l = lp.phi) {
124
                sinphi = P->e * sin(phi_l);
125
                lp.phi = 2. * atan(tp * pow((1.+sinphi)/(1.-sinphi),
126
                   halfe)) - halfpi;
127
                if (fabs(phi_l - lp.phi) < CONV) {
128
                        if (P->mode == S_POLE)
129
                                lp.phi = -lp.phi;
130
                        lp.lam = (xy.x == 0. && xy.y == 0.) ? 0. : atan2(xy.x, xy.y);
131
                        return (lp);
132
                }
133
        }
134
        I_ERROR;
135
}
136
INVERSE(s_inverse); /* spheroid */
137
        double  c, rh, sinc, cosc;
138

    
139
        sinc = sin(c = 2. * atan((rh = hypot(xy.x, xy.y)) / P->akm1));
140
        cosc = cos(c);
141
        lp.lam = 0.;
142
        switch (P->mode) {
143
        case EQUIT:
144
                if (fabs(rh) <= EPS10)
145
                        lp.phi = 0.;
146
                else
147
                        lp.phi = asin(xy.y * sinc / rh);
148
                if (cosc != 0. || xy.x != 0.)
149
                        lp.lam = atan2(xy.x * sinc, cosc * rh);
150
                break;
151
        case OBLIQ:
152
                if (fabs(rh) <= EPS10)
153
                        lp.phi = P->phi0;
154
                else
155
                        lp.phi = asin(cosc * sinph0 + xy.y * sinc * cosph0 / rh);
156
                if ((c = cosc - sinph0 * sin(lp.phi)) != 0. || xy.x != 0.)
157
                        lp.lam = atan2(xy.x * sinc * cosph0, c * rh);
158
                break;
159
        case N_POLE:
160
                xy.y = -xy.y;
161
        case S_POLE:
162
                if (fabs(rh) <= EPS10)
163
                        lp.phi = P->phi0;
164
                else
165
                        lp.phi = asin(P->mode == S_POLE ? - cosc : cosc);
166
                lp.lam = (xy.x == 0. && xy.y == 0.) ? 0. : atan2(xy.x, xy.y);
167
                break;
168
        }
169
        return (lp);
170
}
171
FREEUP; if (P) pj_dalloc(P); }
172
        static PJ *
173
setup(PJ *P) { /* general initialization */
174
        double t;
175

    
176
        if (fabs((t = fabs(P->phi0)) - HALFPI) < EPS10)
177
                P->mode = P->phi0 < 0. ? S_POLE : N_POLE;
178
        else
179
                P->mode = t > EPS10 ? OBLIQ : EQUIT;
180
        P->phits = fabs(P->phits);
181
        if (P->es) {
182
                double X;
183

    
184
                switch (P->mode) {
185
                case N_POLE:
186
                case S_POLE:
187
                        if (fabs(P->phits - HALFPI) < EPS10)
188
                                P->akm1 = 2. * P->k0 /
189
                                   sqrt(pow(1+P->e,1+P->e)*pow(1-P->e,1-P->e));
190
                        else {
191
                                P->akm1 = cos(P->phits) /
192
                                   pj_tsfn(P->phits, t = sin(P->phits), P->e);
193
                                t *= P->e;
194
                                P->akm1 /= sqrt(1. - t * t);
195
                        }
196
                        break;
197
                case EQUIT:
198
                        P->akm1 = 2. * P->k0;
199
                        break;
200
                case OBLIQ:
201
                        t = sin(P->phi0);
202
                        X = 2. * atan(ssfn_(P->phi0, t, P->e)) - HALFPI;
203
                        t *= P->e;
204
                        P->akm1 = 2. * P->k0 * cos(P->phi0) / sqrt(1. - t * t);
205
                        P->sinX1 = sin(X);
206
                        P->cosX1 = cos(X);
207
                        break;
208
                }
209
                P->inv = e_inverse;
210
                P->fwd = e_forward;
211
        } else {
212
                switch (P->mode) {
213
                case OBLIQ:
214
                        sinph0 = sin(P->phi0);
215
                        cosph0 = cos(P->phi0);
216
                case EQUIT:
217
                        P->akm1 = 2. * P->k0;
218
                        break;
219
                case S_POLE:
220
                case N_POLE:
221
                        P->akm1 = fabs(P->phits - HALFPI) >= EPS10 ?
222
                           cos(P->phits) / tan(FORTPI - .5 * P->phits) :
223
                           2. * P->k0 ;
224
                        break;
225
                }
226
                P->inv = s_inverse;
227
                P->fwd = s_forward;
228
        }
229
        return P;
230
}
231
ENTRY0(stere)
232
        P->phits = pj_param(P->params, "tlat_ts").i ?
233
                P->phits = pj_param(P->params, "rlat_ts").f : HALFPI;
234
ENDENTRY(setup(P))
235
ENTRY0(ups)
236
        /* International Ellipsoid */
237
        P->phi0 = pj_param(P->params, "bsouth").i ? - HALFPI: HALFPI;
238
        if (!P->es) E_ERROR(-34);
239
        P->k0 = .994;
240
        P->x0 = 2000000.;
241
        P->y0 = 2000000.;
242
        P->phits = HALFPI;
243
        P->lam0 = 0.;
244
ENDENTRY(setup(P))