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