svn-gvsig-desktop / tags / tmp_build_del / libraries / libjni-proj4 / src / PJ_ob_tran.c @ 38629
History | View | Annotate | Download (4.11 KB)
1 |
#ifndef lint
|
---|---|
2 |
static const char SCCSID[]="@(#)PJ_ob_tran.c 4.1 94/02/15 GIE REL"; |
3 |
#endif
|
4 |
#define PROJ_PARMS__ \
|
5 |
struct PJconsts *link; \
|
6 |
double lamp; \
|
7 |
double cphip, sphip;
|
8 |
#define PJ_LIB__
|
9 |
#include <projects.h> |
10 |
#include <string.h> |
11 |
PROJ_HEAD(ob_tran, "General Oblique Transformation") "\n\tMisc Sph" |
12 |
"\n\to_proj= plus parameters for projection"
|
13 |
"\n\to_lat_p= o_lon_p= (new pole) or"
|
14 |
"\n\to_alpha= o_lon_c= o_lat_c= or"
|
15 |
"\n\to_lon_1= o_lat_1= o_lon_2= o_lat_2=";
|
16 |
#define TOL 1e-10 |
17 |
FORWARD(o_forward); /* spheroid */
|
18 |
double coslam, sinphi, cosphi;
|
19 |
|
20 |
(void) xy;
|
21 |
|
22 |
coslam = cos(lp.lam); |
23 |
sinphi = sin(lp.phi); |
24 |
cosphi = cos(lp.phi); |
25 |
lp.lam = adjlon(aatan2(cosphi * sin(lp.lam), P->sphip * cosphi * coslam + |
26 |
P->cphip * sinphi) + P->lamp); |
27 |
lp.phi = aasin(P->sphip * sinphi - P->cphip * cosphi * coslam); |
28 |
return (P->link->fwd(lp, P->link));
|
29 |
} |
30 |
FORWARD(t_forward); /* spheroid */
|
31 |
double cosphi, coslam;
|
32 |
|
33 |
(void) xy;
|
34 |
|
35 |
cosphi = cos(lp.phi); |
36 |
coslam = cos(lp.lam); |
37 |
lp.lam = adjlon(aatan2(cosphi * sin(lp.lam), sin(lp.phi)) + P->lamp); |
38 |
lp.phi = aasin(- cosphi * coslam); |
39 |
return (P->link->fwd(lp, P->link));
|
40 |
} |
41 |
INVERSE(o_inverse); /* spheroid */
|
42 |
double coslam, sinphi, cosphi;
|
43 |
|
44 |
lp = P->link->inv(xy, P->link); |
45 |
if (lp.lam != HUGE_VAL) {
|
46 |
coslam = cos(lp.lam -= P->lamp); |
47 |
sinphi = sin(lp.phi); |
48 |
cosphi = cos(lp.phi); |
49 |
lp.phi = aasin(P->sphip * sinphi + P->cphip * cosphi * coslam); |
50 |
lp.lam = aatan2(cosphi * sin(lp.lam), P->sphip * cosphi * coslam - |
51 |
P->cphip * sinphi); |
52 |
} |
53 |
return (lp);
|
54 |
} |
55 |
INVERSE(t_inverse); /* spheroid */
|
56 |
double cosphi, t;
|
57 |
|
58 |
lp = P->link->inv(xy, P->link); |
59 |
if (lp.lam != HUGE_VAL) {
|
60 |
cosphi = cos(lp.phi); |
61 |
t = lp.lam - P->lamp; |
62 |
lp.lam = aatan2(cosphi * sin(t), - sin(lp.phi)); |
63 |
lp.phi = aasin(cosphi * cos(t)); |
64 |
} |
65 |
return (lp);
|
66 |
} |
67 |
FREEUP; |
68 |
if (P) {
|
69 |
if (P->link)
|
70 |
(*(P->link->pfree))(P->link); |
71 |
pj_dalloc(P); |
72 |
} |
73 |
} |
74 |
ENTRY1(ob_tran, link) |
75 |
int i;
|
76 |
double phip;
|
77 |
char *name, *s;
|
78 |
|
79 |
/* get name of projection to be translated */
|
80 |
if (!(name = pj_param(P->params, "so_proj").s)) E_ERROR(-26); |
81 |
for (i = 0; (s = pj_list[i].id) && strcmp(name, s) ; ++i) ; |
82 |
if (!s || !(P->link = (*pj_list[i].proj)(0))) E_ERROR(-37); |
83 |
/* copy existing header into new */
|
84 |
P->es = 0.; /* force to spherical */ |
85 |
P->link->params = P->params; |
86 |
P->link->over = P->over; |
87 |
P->link->geoc = P->geoc; |
88 |
P->link->a = P->a; |
89 |
P->link->es = P->es; |
90 |
P->link->ra = P->ra; |
91 |
P->link->lam0 = P->lam0; |
92 |
P->link->phi0 = P->phi0; |
93 |
P->link->x0 = P->x0; |
94 |
P->link->y0 = P->y0; |
95 |
P->link->k0 = P->k0; |
96 |
/* force spherical earth */
|
97 |
P->link->one_es = P->link->rone_es = 1.;
|
98 |
P->link->es = P->link->e = 0.;
|
99 |
if (!(P->link = pj_list[i].proj(P->link))) {
|
100 |
freeup(P); |
101 |
return 0; |
102 |
} |
103 |
if (pj_param(P->params, "to_alpha").i) { |
104 |
double lamc, phic, alpha;
|
105 |
|
106 |
lamc = pj_param(P->params, "ro_lon_c").f;
|
107 |
phic = pj_param(P->params, "ro_lat_c").f;
|
108 |
alpha = pj_param(P->params, "ro_alpha").f;
|
109 |
/*
|
110 |
if (fabs(phic) <= TOL ||
|
111 |
fabs(fabs(phic) - HALFPI) <= TOL ||
|
112 |
fabs(fabs(alpha) - HALFPI) <= TOL)
|
113 |
*/
|
114 |
if (fabs(fabs(phic) - HALFPI) <= TOL)
|
115 |
E_ERROR(-32);
|
116 |
P->lamp = lamc + aatan2(-cos(alpha), -sin(alpha) * sin(phic)); |
117 |
phip = aasin(cos(phic) * sin(alpha)); |
118 |
} else if (pj_param(P->params, "to_lat_p").i) { /* specified new pole */ |
119 |
P->lamp = pj_param(P->params, "ro_lon_p").f;
|
120 |
phip = pj_param(P->params, "ro_lat_p").f;
|
121 |
} else { /* specified new "equator" points */ |
122 |
double lam1, lam2, phi1, phi2, con;
|
123 |
|
124 |
lam1 = pj_param(P->params, "ro_lon_1").f;
|
125 |
phi1 = pj_param(P->params, "ro_lat_1").f;
|
126 |
lam2 = pj_param(P->params, "ro_lon_2").f;
|
127 |
phi2 = pj_param(P->params, "ro_lat_2").f;
|
128 |
if (fabs(phi1 - phi2) <= TOL ||
|
129 |
(con = fabs(phi1)) <= TOL || |
130 |
fabs(con - HALFPI) <= TOL || |
131 |
fabs(fabs(phi2) - HALFPI) <= TOL) E_ERROR(-33);
|
132 |
P->lamp = atan2(cos(phi1) * sin(phi2) * cos(lam1) - |
133 |
sin(phi1) * cos(phi2) * cos(lam2), |
134 |
sin(phi1) * cos(phi2) * sin(lam2) - |
135 |
cos(phi1) * sin(phi2) * sin(lam1)); |
136 |
phip = atan(-cos(P->lamp - lam1) / tan(phi1)); |
137 |
} |
138 |
if (fabs(phip) > TOL) { /* oblique */ |
139 |
P->cphip = cos(phip); |
140 |
P->sphip = sin(phip); |
141 |
P->fwd = o_forward; |
142 |
P->inv = P->link->inv ? o_inverse : 0;
|
143 |
} else { /* transverse */ |
144 |
P->fwd = t_forward; |
145 |
P->inv = P->link->inv ? t_inverse : 0;
|
146 |
} |
147 |
ENDENTRY(P) |