1 #define PJ_LIB__
2 #include <projects.h>
3 
4 struct pj_opaque {
5     double  A, B;
6 };
7 
8 PROJ_HEAD(putp5, "Putnins P5") "\n\tPCyl., Sph.";
9 PROJ_HEAD(putp5p, "Putnins P5'") "\n\tPCyl., Sph.";
10 
11 #define C 1.01346
12 #define D 1.2158542
13 
14 
s_forward(LP lp,PJ * P)15 static XY s_forward (LP lp, PJ *P) {           /* Spheroidal, forward */
16     XY xy = {0.0,0.0};
17     struct pj_opaque *Q = P->opaque;
18 
19     xy.x = C * lp.lam * (Q->A - Q->B * sqrt(1. + D * lp.phi * lp.phi));
20     xy.y = C * lp.phi;
21 
22     return xy;
23 }
24 
25 
s_inverse(XY xy,PJ * P)26 static LP s_inverse (XY xy, PJ *P) {           /* Spheroidal, inverse */
27     LP lp = {0.0,0.0};
28     struct pj_opaque *Q = P->opaque;
29 
30     lp.phi = xy.y / C;
31     lp.lam = xy.x / (C * (Q->A - Q->B * sqrt(1. + D * lp.phi * lp.phi)));
32 
33     return lp;
34 }
35 
36 
freeup_new(PJ * P)37 static void *freeup_new (PJ *P) {                       /* Destructor */
38     if (0==P)
39         return 0;
40     if (0==P->opaque)
41         return pj_dealloc (P);
42 
43     pj_dealloc (P->opaque);
44     return pj_dealloc(P);
45 }
46 
47 
freeup(PJ * P)48 static void freeup (PJ *P) {
49     freeup_new (P);
50     return;
51 }
52 
53 
PROJECTION(putp5)54 PJ *PROJECTION(putp5) {
55     struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
56     if (0==Q)
57         return freeup_new (P);
58     P->opaque = Q;
59 
60     Q->A = 2.;
61     Q->B = 1.;
62 
63     P->es = 0.;
64     P->inv = s_inverse;
65     P->fwd = s_forward;
66 
67     return P;
68 }
69 
70 
PROJECTION(putp5p)71 PJ *PROJECTION(putp5p) {
72     struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
73     if (0==Q)
74         return freeup_new (P);
75     P->opaque = Q;
76 
77     Q->A = 1.5;
78     Q->B = 0.5;
79 
80     P->es = 0.;
81     P->inv = s_inverse;
82     P->fwd = s_forward;
83 
84     return P;
85 }
86 
87 #ifndef PJ_SELFTEST
pj_putp5_selftest(void)88 int pj_putp5_selftest (void) {return 0;}
89 #else
90 
pj_putp5_selftest(void)91 int pj_putp5_selftest (void) {
92     double tolerance_lp = 1e-10;
93     double tolerance_xy = 1e-7;
94 
95     char s_args[] = {"+proj=putp5   +a=6400000    +lat_1=0.5 +lat_2=2"};
96 
97     LP fwd_in[] = {
98         { 2, 1},
99         { 2,-1},
100         {-2, 1},
101         {-2,-1}
102     };
103 
104     XY s_fwd_expect[] = {
105         { 226367.21338056153,  113204.56855847509},
106         { 226367.21338056153, -113204.56855847509},
107         {-226367.21338056153,  113204.56855847509},
108         {-226367.21338056153, -113204.56855847509},
109     };
110 
111     XY inv_in[] = {
112         { 200, 100},
113         { 200,-100},
114         {-200, 100},
115         {-200,-100}
116     };
117 
118     LP s_inv_expect[] = {
119         { 0.00176671315102969553,  0.000883356575387199546},
120         { 0.00176671315102969553, -0.000883356575387199546},
121         {-0.00176671315102969553,  0.000883356575387199546},
122         {-0.00176671315102969553, -0.000883356575387199546},
123     };
124 
125     return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect);
126 }
127 
128 #endif
129 
130 
131 #ifndef PJ_SELFTEST
pj_putp5p_selftest(void)132 int pj_putp5p_selftest (void) {return 0;}
133 #else
134 
pj_putp5p_selftest(void)135 int pj_putp5p_selftest (void) {
136     double tolerance_lp = 1e-10;
137     double tolerance_xy = 1e-7;
138 
139     char s_args[] = {"+proj=putp5p   +a=6400000    +lat_1=0.5 +lat_2=2"};
140 
141     LP fwd_in[] = {
142         { 2, 1},
143         { 2,-1},
144         {-2, 1},
145         {-2,-1}
146     };
147 
148     XY s_fwd_expect[] = {
149         { 226388.175248755841,  113204.56855847509},
150         { 226388.175248755841, -113204.56855847509},
151         {-226388.175248755841,  113204.56855847509},
152         {-226388.175248755841, -113204.56855847509},
153     };
154 
155     XY inv_in[] = {
156         { 200, 100},
157         { 200,-100},
158         {-200, 100},
159         {-200,-100}
160     };
161 
162     LP s_inv_expect[] = {
163         { 0.00176671315090204742,  0.000883356575387199546},
164         { 0.00176671315090204742, -0.000883356575387199546},
165         {-0.00176671315090204742,  0.000883356575387199546},
166         {-0.00176671315090204742, -0.000883356575387199546},
167     };
168 
169     return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect);
170 }
171 
172 #endif
173