aboutsummaryrefslogtreecommitdiff
path: root/src/PJ_sts.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/PJ_sts.c')
-rw-r--r--src/PJ_sts.c367
1 files changed, 332 insertions, 35 deletions
diff --git a/src/PJ_sts.c b/src/PJ_sts.c
index c35d5cfc..347a7303 100644
--- a/src/PJ_sts.c
+++ b/src/PJ_sts.c
@@ -1,54 +1,351 @@
-#define PROJ_PARMS__ \
- double C_x, C_y, C_p; \
- int tan_mode;
#define PJ_LIB__
# include <projects.h>
-PROJ_HEAD(kav5, "Kavraisky V") "\n\tPCyl., Sph.";
-PROJ_HEAD(qua_aut, "Quartic Authalic") "\n\tPCyl., Sph.";
-PROJ_HEAD(mbt_s, "McBryde-Thomas Flat-Polar Sine (No. 1)") "\n\tPCyl., Sph.";
-PROJ_HEAD(fouc, "Foucaut") "\n\tPCyl., Sph.";
-FORWARD(s_forward); /* spheroid */
+
+PROJ_HEAD(kav5, "Kavraisky V") "\n\tPCyl., Sph.";
+PROJ_HEAD(qua_aut, "Quartic Authalic") "\n\tPCyl., Sph.";
+PROJ_HEAD(fouc, "Foucaut") "\n\tPCyl., Sph.";
+PROJ_HEAD(mbt_s, "McBryde-Thomas Flat-Polar Sine (No. 1)") "\n\tPCyl., Sph.";
+
+
+struct pj_opaque {
+ double C_x, C_y, C_p; \
+ int tan_mode;
+};
+
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0,0.0};
+ struct pj_opaque *Q = P->opaque;
double c;
- xy.x = P->C_x * lp.lam * cos(lp.phi);
- xy.y = P->C_y;
- lp.phi *= P->C_p;
+ xy.x = Q->C_x * lp.lam * cos(lp.phi);
+ xy.y = Q->C_y;
+ lp.phi *= Q->C_p;
c = cos(lp.phi);
- if (P->tan_mode) {
+ if (Q->tan_mode) {
xy.x *= c * c;
- xy.y *= tan(lp.phi);
+ xy.y *= tan (lp.phi);
} else {
xy.x /= c;
- xy.y *= sin(lp.phi);
+ xy.y *= sin (lp.phi);
}
- return (xy);
+ return xy;
}
-INVERSE(s_inverse); /* spheroid */
+
+
+static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
+ LP lp = {0.0,0.0};
+ struct pj_opaque *Q = P->opaque;
double c;
-
- xy.y /= P->C_y;
- c = cos(lp.phi = P->tan_mode ? atan(xy.y) : aasin(P->ctx,xy.y));
- lp.phi /= P->C_p;
- lp.lam = xy.x / (P->C_x * cos(lp.phi));
- if (P->tan_mode)
+
+ xy.y /= Q->C_y;
+ c = cos (lp.phi = Q->tan_mode ? atan (xy.y) : aasin (P->ctx, xy.y));
+ lp.phi /= Q->C_p;
+ lp.lam = xy.x / (Q->C_x * cos(lp.phi));
+ if (Q->tan_mode)
lp.lam /= c * c;
else
lp.lam *= c;
- return (lp);
+ return lp;
+}
+
+
+static void *freeup_new (PJ *P) { /* Destructor */
+ if (0==P)
+ return 0;
+ pj_dealloc (P->opaque);
+ return pj_dealloc(P);
+}
+
+static void freeup (PJ *P) {
+ freeup_new (P);
+ return;
}
-FREEUP; if (P) pj_dalloc(P); }
- static PJ *
-setup(PJ *P, double p, double q, int mode) {
- P->es = 0.;
+
+
+static PJ *setup(PJ *P, double p, double q, int mode) {
+ P->es = 0.;
P->inv = s_inverse;
P->fwd = s_forward;
- P->C_x = q / p;
- P->C_y = p;
- P->C_p = 1/ q;
- P->tan_mode = mode;
+ P->opaque->C_x = q / p;
+ P->opaque->C_y = p;
+ P->opaque->C_p = 1/ q;
+ P->opaque->tan_mode = mode;
return P;
}
-ENTRY0(kav5) ENDENTRY(setup(P, 1.50488, 1.35439, 0))
-ENTRY0(qua_aut) ENDENTRY(setup(P, 2., 2., 0))
-ENTRY0(mbt_s) ENDENTRY(setup(P, 1.48875, 1.36509, 0))
-ENTRY0(fouc) ENDENTRY(setup(P, 2., 2., 1))
+
+
+
+
+
+PJ *PROJECTION(fouc) {
+ struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
+ if (0==Q)
+ return freeup_new (P);
+ P->opaque = Q;
+ return setup(P, 2., 2., 1);
+}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_fouc_selftest (void) {return 0;}
+#else
+int pj_fouc_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char e_args[] = {"+proj=fouc +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"};
+ char s_args[] = {"+proj=fouc +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY e_fwd_expect[] = {
+ {222588.12067589167, 111322.31670069379},
+ {222588.12067589167, -111322.31670069379},
+ {-222588.12067589167, 111322.31670069379},
+ {-222588.12067589167, -111322.31670069379},
+ };
+
+ XY s_fwd_expect[] = {
+ {223351.10900341379, 111703.9077217125},
+ {223351.10900341379, -111703.9077217125},
+ {-223351.10900341379, 111703.9077217125},
+ {-223351.10900341379, -111703.9077217125},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP e_inv_expect[] = {
+ {0.0017966305685702751, 0.00089831528410111959},
+ {0.0017966305685702751, -0.00089831528410111959},
+ {-0.0017966305685702751, 0.00089831528410111959},
+ {-0.0017966305685702751, -0.00089831528410111959},
+ };
+
+ LP s_inv_expect[] = {
+ {0.0017904931101116717, 0.00089524655487369749},
+ {0.0017904931101116717, -0.00089524655487369749},
+ {-0.0017904931101116717, 0.00089524655487369749},
+ {-0.0017904931101116717, -0.00089524655487369749},
+ };
+
+ 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);
+}
+#endif
+
+
+
+
+
+
+PJ *PROJECTION(kav5) {
+ struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
+ if (0==Q)
+ return freeup_new (P);
+ P->opaque = Q;
+
+ return setup(P, 1.50488, 1.35439, 0);
+}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_kav5_selftest (void) {return 0;}
+#else
+int pj_kav5_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char e_args[] = {"+proj=kav5 +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"};
+ char s_args[] = {"+proj=kav5 +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY e_fwd_expect[] = {
+ {200360.90530882866, 123685.08247699818},
+ {200360.90530882866, -123685.08247699818},
+ {-200360.90530882866, 123685.08247699818},
+ {-200360.90530882866, -123685.08247699818},
+ };
+
+ XY s_fwd_expect[] = {
+ {201047.7031108776, 124109.05062917093},
+ {201047.7031108776, -124109.05062917093},
+ {-201047.7031108776, 124109.05062917093},
+ {-201047.7031108776, -124109.05062917093},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP e_inv_expect[] = {
+ {0.0019962591348533314, 0.00080848256185253912},
+ {0.0019962591348533314, -0.00080848256185253912},
+ {-0.0019962591348533314, 0.00080848256185253912},
+ {-0.0019962591348533314, -0.00080848256185253912},
+ };
+
+ LP s_inv_expect[] = {
+ {0.0019894397264987643, 0.00080572070962591153},
+ {0.0019894397264987643, -0.00080572070962591153},
+ {-0.0019894397264987643, 0.00080572070962591153},
+ {-0.0019894397264987643, -0.00080572070962591153},
+ };
+
+ 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);
+}
+#endif
+
+
+
+
+
+PJ *PROJECTION(qua_aut) {
+ struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
+ if (0==Q)
+ return freeup_new (P);
+ P->opaque = Q;
+ return setup(P, 2., 2., 0);
+}
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_qua_aut_selftest (void) {return 0;}
+#else
+int pj_qua_aut_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char e_args[] = {"+proj=qua_aut +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"};
+ char s_args[] = {"+proj=qua_aut +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY e_fwd_expect[] = {
+ {222613.54903309655, 111318.07788798446},
+ {222613.54903309655, -111318.07788798446},
+ {-222613.54903309655, 111318.07788798446},
+ {-222613.54903309655, -111318.07788798446},
+ };
+
+ XY s_fwd_expect[] = {
+ {223376.62452402918, 111699.65437918637},
+ {223376.62452402918, -111699.65437918637},
+ {-223376.62452402918, 111699.65437918637},
+ {-223376.62452402918, -111699.65437918637},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP e_inv_expect[] = {
+ {0.0017966305684046586, 0.00089831528412872229},
+ {0.0017966305684046586, -0.00089831528412872229},
+ {-0.0017966305684046586, 0.00089831528412872229},
+ {-0.0017966305684046586, -0.00089831528412872229},
+ };
+
+ LP s_inv_expect[] = {
+ {0.0017904931099477471, 0.00089524655490101819},
+ {0.0017904931099477471, -0.00089524655490101819},
+ {-0.0017904931099477471, 0.00089524655490101819},
+ {-0.0017904931099477471, -0.00089524655490101819},
+ };
+
+ 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);
+}
+#endif
+
+
+
+
+
+PJ *PROJECTION(mbt_s) {
+ struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
+ if (0==Q)
+ return freeup_new (P);
+ P->opaque = Q;
+ return setup(P, 1.48875, 1.36509, 0);
+}
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_mbt_s_selftest (void) {return 0;}
+#else
+int pj_mbt_s_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char e_args[] = {"+proj=mbt_s +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"};
+ char s_args[] = {"+proj=mbt_s +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY e_fwd_expect[] = {
+ {204131.51785027285, 121400.33022550763},
+ {204131.51785027285, -121400.33022550763},
+ {-204131.51785027285, 121400.33022550763},
+ {-204131.51785027285, -121400.33022550763},
+ };
+
+ XY s_fwd_expect[] = {
+ {204831.24057099217, 121816.46669603503},
+ {204831.24057099217, -121816.46669603503},
+ {-204831.24057099217, 121816.46669603503},
+ {-204831.24057099217, -121816.46669603503},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP e_inv_expect[] = {
+ {0.0019593827209883237, 0.00082369854658027549},
+ {0.0019593827209883237, -0.00082369854658027549},
+ {-0.0019593827209883237, 0.00082369854658027549},
+ {-0.0019593827209883237, -0.00082369854658027549},
+ };
+
+ LP s_inv_expect[] = {
+ {0.0019526892859206603, 0.00082088471512331508},
+ {0.0019526892859206603, -0.00082088471512331508},
+ {-0.0019526892859206603, 0.00082088471512331508},
+ {-0.0019526892859206603, -0.00082088471512331508},
+ };
+
+ 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);
+}
+#endif