1 #define PJ_LIB__
2 
3 #include <errno.h>
4 #include <math.h>
5 
6 #include "proj.h"
7 #include "proj_internal.h"
8 
9 PROJ_HEAD(kav5,    "Kavraisky V")         "\n\tPCyl, Sph";
10 PROJ_HEAD(qua_aut, "Quartic Authalic")    "\n\tPCyl, Sph";
11 PROJ_HEAD(fouc,    "Foucaut")             "\n\tPCyl, Sph";
12 PROJ_HEAD(mbt_s,   "McBryde-Thomas Flat-Polar Sine (No. 1)") "\n\tPCyl, Sph";
13 
14 
15 namespace { // anonymous namespace
16 struct pj_opaque {
17 	double C_x, C_y, C_p;
18 	int tan_mode;
19 };
20 } // anonymous namespace
21 
22 
sts_s_forward(PJ_LP lp,PJ * P)23 static PJ_XY sts_s_forward (PJ_LP lp, PJ *P) {           /* Spheroidal, forward */
24     PJ_XY xy = {0.0,0.0};
25     struct pj_opaque *Q = static_cast<struct pj_opaque*>(P->opaque);
26 
27     xy.x = Q->C_x * lp.lam * cos(lp.phi);
28     xy.y = Q->C_y;
29     lp.phi *= Q->C_p;
30     const double c = cos(lp.phi);
31     if (Q->tan_mode) {
32             xy.x *= c * c;
33             xy.y *= tan (lp.phi);
34     } else {
35             xy.x /= c;
36             xy.y *= sin (lp.phi);
37     }
38     return xy;
39 }
40 
41 
sts_s_inverse(PJ_XY xy,PJ * P)42 static PJ_LP sts_s_inverse (PJ_XY xy, PJ *P) {           /* Spheroidal, inverse */
43     PJ_LP lp = {0.0,0.0};
44     struct pj_opaque *Q = static_cast<struct pj_opaque*>(P->opaque);
45 
46     xy.y /= Q->C_y;
47     lp.phi = Q->tan_mode ? atan (xy.y) : aasin (P->ctx, xy.y);
48     const double c = cos (lp.phi);
49     lp.phi /= Q->C_p;
50     lp.lam = xy.x / (Q->C_x * cos(lp.phi));
51     if (Q->tan_mode)
52             lp.lam /= c * c;
53     else
54             lp.lam *= c;
55     return lp;
56 }
57 
58 
setup(PJ * P,double p,double q,int mode)59 static PJ *setup(PJ *P, double p, double q, int mode) {
60     P->es  = 0.;
61     P->inv = sts_s_inverse;
62     P->fwd = sts_s_forward;
63     static_cast<struct pj_opaque*>(P->opaque)->C_x = q / p;
64     static_cast<struct pj_opaque*>(P->opaque)->C_y = p;
65     static_cast<struct pj_opaque*>(P->opaque)->C_p = 1/ q;
66     static_cast<struct pj_opaque*>(P->opaque)->tan_mode = mode;
67     return P;
68 }
69 
70 
71 
PROJECTION(fouc)72 PJ *PROJECTION(fouc) {
73     struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
74     if (nullptr==Q)
75         return pj_default_destructor(P, ENOMEM);
76     P->opaque = Q;
77     return setup(P, 2., 2., 1);
78 }
79 
80 
81 
PROJECTION(kav5)82 PJ *PROJECTION(kav5) {
83     struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
84     if (nullptr==Q)
85         return pj_default_destructor(P, ENOMEM);
86     P->opaque = Q;
87 
88     return setup(P, 1.50488, 1.35439, 0);
89 }
90 
91 
92 
PROJECTION(qua_aut)93 PJ *PROJECTION(qua_aut) {
94     struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
95     if (nullptr==Q)
96         return pj_default_destructor(P, ENOMEM);
97     P->opaque = Q;
98     return setup(P, 2., 2., 0);
99 }
100 
101 
102 
PROJECTION(mbt_s)103 PJ *PROJECTION(mbt_s) {
104     struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
105     if (nullptr==Q)
106         return pj_default_destructor(P, ENOMEM);
107     P->opaque = Q;
108     return setup(P, 1.48875, 1.36509, 0);
109 }
110