1 #define PJ_LIB__
2 # include	<projects.h>
3 
4 PROJ_HEAD(kav5,    "Kavraisky V")         "\n\tPCyl., Sph.";
5 PROJ_HEAD(qua_aut, "Quartic Authalic")    "\n\tPCyl., Sph.";
6 PROJ_HEAD(fouc,    "Foucaut")             "\n\tPCyl., Sph.";
7 PROJ_HEAD(mbt_s,   "McBryde-Thomas Flat-Polar Sine (No. 1)") "\n\tPCyl., Sph.";
8 
9 
10 struct pj_opaque {
11 	double C_x, C_y, C_p; \
12 	int tan_mode;
13 };
14 
15 
s_forward(LP lp,PJ * P)16 static XY s_forward (LP lp, PJ *P) {           /* Spheroidal, forward */
17     XY xy = {0.0,0.0};
18     struct pj_opaque *Q = P->opaque;
19 	double c;
20 
21 	xy.x = Q->C_x * lp.lam * cos(lp.phi);
22 	xy.y = Q->C_y;
23 	lp.phi *= Q->C_p;
24 	c = cos(lp.phi);
25 	if (Q->tan_mode) {
26 		xy.x *= c * c;
27 		xy.y *= tan (lp.phi);
28 	} else {
29 		xy.x /= c;
30 		xy.y *= sin (lp.phi);
31 	}
32 	return xy;
33 }
34 
35 
s_inverse(XY xy,PJ * P)36 static LP s_inverse (XY xy, PJ *P) {           /* Spheroidal, inverse */
37     LP lp = {0.0,0.0};
38     struct pj_opaque *Q = P->opaque;
39 	double c;
40 
41 	xy.y /= Q->C_y;
42 	c = cos (lp.phi = Q->tan_mode ? atan (xy.y) : aasin (P->ctx, xy.y));
43 	lp.phi /= Q->C_p;
44 	lp.lam = xy.x / (Q->C_x * cos(lp.phi));
45 	if (Q->tan_mode)
46 		lp.lam /= c * c;
47 	else
48 		lp.lam *= c;
49 	return lp;
50 }
51 
52 
freeup_new(PJ * P)53 static void *freeup_new (PJ *P) {                       /* Destructor */
54     if (0==P)
55         return 0;
56     pj_dealloc (P->opaque);
57     return pj_dealloc(P);
58 }
59 
freeup(PJ * P)60 static void freeup (PJ *P) {
61     freeup_new (P);
62     return;
63 }
64 
65 
setup(PJ * P,double p,double q,int mode)66 static PJ *setup(PJ *P, double p, double q, int mode) {
67 	P->es  = 0.;
68 	P->inv = s_inverse;
69 	P->fwd = s_forward;
70 	P->opaque->C_x = q / p;
71 	P->opaque->C_y = p;
72 	P->opaque->C_p = 1/ q;
73 	P->opaque->tan_mode = mode;
74 	return P;
75 }
76 
77 
78 
79 
80 
PROJECTION(fouc)81 PJ *PROJECTION(fouc) {
82     struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
83     if (0==Q)
84         return freeup_new (P);
85     P->opaque = Q;
86     return setup(P, 2., 2., 1);
87 }
88 
89 
90 #ifndef PJ_SELFTEST
pj_fouc_selftest(void)91 int pj_fouc_selftest (void) {return 0;}
92 #else
pj_fouc_selftest(void)93 int pj_fouc_selftest (void) {
94     double tolerance_lp = 1e-10;
95     double tolerance_xy = 1e-7;
96 
97     char e_args[] = {"+proj=fouc   +ellps=GRS80  +lat_1=0.5 +lat_2=2 +n=0.5"};
98     char s_args[] = {"+proj=fouc   +a=6400000    +lat_1=0.5 +lat_2=2 +n=0.5"};
99 
100     LP fwd_in[] = {
101         { 2, 1},
102         { 2,-1},
103         {-2, 1},
104         {-2,-1}
105     };
106 
107     XY e_fwd_expect[] = {
108         {222588.12067589167,  111322.31670069379},
109         {222588.12067589167,  -111322.31670069379},
110         {-222588.12067589167,  111322.31670069379},
111         {-222588.12067589167,  -111322.31670069379},
112     };
113 
114     XY s_fwd_expect[] = {
115         {223351.10900341379,  111703.9077217125},
116         {223351.10900341379,  -111703.9077217125},
117         {-223351.10900341379,  111703.9077217125},
118         {-223351.10900341379,  -111703.9077217125},
119     };
120 
121     XY inv_in[] = {
122         { 200, 100},
123         { 200,-100},
124         {-200, 100},
125         {-200,-100}
126     };
127 
128     LP e_inv_expect[] = {
129         {0.0017966305685702751,  0.00089831528410111959},
130         {0.0017966305685702751,  -0.00089831528410111959},
131         {-0.0017966305685702751,  0.00089831528410111959},
132         {-0.0017966305685702751,  -0.00089831528410111959},
133     };
134 
135     LP s_inv_expect[] = {
136         {0.0017904931101116717,  0.00089524655487369749},
137         {0.0017904931101116717,  -0.00089524655487369749},
138         {-0.0017904931101116717,  0.00089524655487369749},
139         {-0.0017904931101116717,  -0.00089524655487369749},
140     };
141 
142     return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect);
143 }
144 #endif
145 
146 
147 
148 
149 
150 
PROJECTION(kav5)151 PJ *PROJECTION(kav5) {
152     struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
153     if (0==Q)
154         return freeup_new (P);
155     P->opaque = Q;
156 
157     return setup(P, 1.50488, 1.35439, 0);
158 }
159 
160 
161 #ifndef PJ_SELFTEST
pj_kav5_selftest(void)162 int pj_kav5_selftest (void) {return 0;}
163 #else
pj_kav5_selftest(void)164 int pj_kav5_selftest (void) {
165     double tolerance_lp = 1e-10;
166     double tolerance_xy = 1e-7;
167 
168     char e_args[] = {"+proj=kav5   +ellps=GRS80  +lat_1=0.5 +lat_2=2 +n=0.5"};
169     char s_args[] = {"+proj=kav5   +a=6400000    +lat_1=0.5 +lat_2=2 +n=0.5"};
170 
171     LP fwd_in[] = {
172         { 2, 1},
173         { 2,-1},
174         {-2, 1},
175         {-2,-1}
176     };
177 
178     XY e_fwd_expect[] = {
179         {200360.90530882866,  123685.08247699818},
180         {200360.90530882866,  -123685.08247699818},
181         {-200360.90530882866,  123685.08247699818},
182         {-200360.90530882866,  -123685.08247699818},
183     };
184 
185     XY s_fwd_expect[] = {
186         {201047.7031108776,  124109.05062917093},
187         {201047.7031108776,  -124109.05062917093},
188         {-201047.7031108776,  124109.05062917093},
189         {-201047.7031108776,  -124109.05062917093},
190     };
191 
192     XY inv_in[] = {
193         { 200, 100},
194         { 200,-100},
195         {-200, 100},
196         {-200,-100}
197     };
198 
199     LP e_inv_expect[] = {
200         {0.0019962591348533314,  0.00080848256185253912},
201         {0.0019962591348533314,  -0.00080848256185253912},
202         {-0.0019962591348533314,  0.00080848256185253912},
203         {-0.0019962591348533314,  -0.00080848256185253912},
204     };
205 
206     LP s_inv_expect[] = {
207         {0.0019894397264987643,  0.00080572070962591153},
208         {0.0019894397264987643,  -0.00080572070962591153},
209         {-0.0019894397264987643,  0.00080572070962591153},
210         {-0.0019894397264987643,  -0.00080572070962591153},
211     };
212 
213     return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect);
214 }
215 #endif
216 
217 
218 
219 
220 
PROJECTION(qua_aut)221 PJ *PROJECTION(qua_aut) {
222     struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
223     if (0==Q)
224         return freeup_new (P);
225     P->opaque = Q;
226     return setup(P, 2., 2., 0);
227 }
228 
229 #ifndef PJ_SELFTEST
pj_qua_aut_selftest(void)230 int pj_qua_aut_selftest (void) {return 0;}
231 #else
pj_qua_aut_selftest(void)232 int pj_qua_aut_selftest (void) {
233     double tolerance_lp = 1e-10;
234     double tolerance_xy = 1e-7;
235 
236     char e_args[] = {"+proj=qua_aut   +ellps=GRS80  +lat_1=0.5 +lat_2=2 +n=0.5"};
237     char s_args[] = {"+proj=qua_aut   +a=6400000    +lat_1=0.5 +lat_2=2 +n=0.5"};
238 
239     LP fwd_in[] = {
240         { 2, 1},
241         { 2,-1},
242         {-2, 1},
243         {-2,-1}
244     };
245 
246     XY e_fwd_expect[] = {
247         {222613.54903309655,  111318.07788798446},
248         {222613.54903309655,  -111318.07788798446},
249         {-222613.54903309655,  111318.07788798446},
250         {-222613.54903309655,  -111318.07788798446},
251     };
252 
253     XY s_fwd_expect[] = {
254         {223376.62452402918,  111699.65437918637},
255         {223376.62452402918,  -111699.65437918637},
256         {-223376.62452402918,  111699.65437918637},
257         {-223376.62452402918,  -111699.65437918637},
258     };
259 
260     XY inv_in[] = {
261         { 200, 100},
262         { 200,-100},
263         {-200, 100},
264         {-200,-100}
265     };
266 
267     LP e_inv_expect[] = {
268         {0.0017966305684046586,  0.00089831528412872229},
269         {0.0017966305684046586,  -0.00089831528412872229},
270         {-0.0017966305684046586,  0.00089831528412872229},
271         {-0.0017966305684046586,  -0.00089831528412872229},
272     };
273 
274     LP s_inv_expect[] = {
275         {0.0017904931099477471,  0.00089524655490101819},
276         {0.0017904931099477471,  -0.00089524655490101819},
277         {-0.0017904931099477471,  0.00089524655490101819},
278         {-0.0017904931099477471,  -0.00089524655490101819},
279     };
280 
281     return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect);
282 }
283 #endif
284 
285 
286 
287 
288 
PROJECTION(mbt_s)289 PJ *PROJECTION(mbt_s) {
290     struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
291     if (0==Q)
292         return freeup_new (P);
293     P->opaque = Q;
294     return setup(P, 1.48875, 1.36509, 0);
295 }
296 
297 #ifndef PJ_SELFTEST
pj_mbt_s_selftest(void)298 int pj_mbt_s_selftest (void) {return 0;}
299 #else
pj_mbt_s_selftest(void)300 int pj_mbt_s_selftest (void) {
301     double tolerance_lp = 1e-10;
302     double tolerance_xy = 1e-7;
303 
304     char e_args[] = {"+proj=mbt_s   +ellps=GRS80  +lat_1=0.5 +lat_2=2 +n=0.5"};
305     char s_args[] = {"+proj=mbt_s   +a=6400000    +lat_1=0.5 +lat_2=2 +n=0.5"};
306 
307     LP fwd_in[] = {
308         { 2, 1},
309         { 2,-1},
310         {-2, 1},
311         {-2,-1}
312     };
313 
314     XY e_fwd_expect[] = {
315         {204131.51785027285,  121400.33022550763},
316         {204131.51785027285,  -121400.33022550763},
317         {-204131.51785027285,  121400.33022550763},
318         {-204131.51785027285,  -121400.33022550763},
319     };
320 
321     XY s_fwd_expect[] = {
322         {204831.24057099217,  121816.46669603503},
323         {204831.24057099217,  -121816.46669603503},
324         {-204831.24057099217,  121816.46669603503},
325         {-204831.24057099217,  -121816.46669603503},
326     };
327 
328     XY inv_in[] = {
329         { 200, 100},
330         { 200,-100},
331         {-200, 100},
332         {-200,-100}
333     };
334 
335     LP e_inv_expect[] = {
336         {0.0019593827209883237,  0.00082369854658027549},
337         {0.0019593827209883237,  -0.00082369854658027549},
338         {-0.0019593827209883237,  0.00082369854658027549},
339         {-0.0019593827209883237,  -0.00082369854658027549},
340     };
341 
342     LP s_inv_expect[] = {
343         {0.0019526892859206603,  0.00082088471512331508},
344         {0.0019526892859206603,  -0.00082088471512331508},
345         {-0.0019526892859206603,  0.00082088471512331508},
346         {-0.0019526892859206603,  -0.00082088471512331508},
347     };
348 
349     return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect);
350 }
351 #endif
352