aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/PJ_aea.c8
-rw-r--r--src/PJ_calcofi.c154
-rw-r--r--src/PJ_cass.c196
-rw-r--r--src/PJ_cc.c87
-rw-r--r--src/PJ_wag2.c81
-rw-r--r--src/PJ_wag3.c103
-rw-r--r--src/PJ_wag7.c66
-rw-r--r--src/PJ_wink1.c104
-rw-r--r--src/PJ_wink2.c89
-rw-r--r--src/projects.h2
10 files changed, 712 insertions, 178 deletions
diff --git a/src/PJ_aea.c b/src/PJ_aea.c
index 59f3e7bd..6de8f00d 100644
--- a/src/PJ_aea.c
+++ b/src/PJ_aea.c
@@ -356,9 +356,6 @@ source files
int pj_aeqd_selftest (void) {return 10000;}
int pj_alsk_selftest (void) {return 10000;}
-int pj_calcofi_selftest (void) {return 10000;}
-int pj_cass_selftest (void) {return 10000;}
-int pj_cc_selftest (void) {return 10000;}
int pj_cea_selftest (void) {return 10000;}
int pj_chamb_selftest (void) {return 10000;}
int pj_collg_selftest (void) {return 10000;}
@@ -476,13 +473,8 @@ int pj_vandg3_selftest (void) {return 10000;}
int pj_vandg4_selftest (void) {return 10000;}
int pj_vitk1_selftest (void) {return 10000;}
int pj_wag1_selftest (void) {return 10000;}
-int pj_wag2_selftest (void) {return 10000;}
-int pj_wag3_selftest (void) {return 10000;}
int pj_wag4_selftest (void) {return 10000;}
int pj_wag5_selftest (void) {return 10000;}
int pj_wag6_selftest (void) {return 10000;}
-int pj_wag7_selftest (void) {return 10000;}
int pj_weren_selftest (void) {return 10000;}
-int pj_wink1_selftest (void) {return 10000;}
-int pj_wink2_selftest (void) {return 10000;}
#endif
diff --git a/src/PJ_calcofi.c b/src/PJ_calcofi.c
index 2d142938..62749a93 100644
--- a/src/PJ_calcofi.c
+++ b/src/PJ_calcofi.c
@@ -1,25 +1,27 @@
#define PJ_LIB__
#include <projects.h>
+
+PROJ_HEAD(calcofi,
+ "Cal Coop Ocean Fish Invest Lines/Stations") "\n\tCyl, Sph&Ell";
+
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <proj_api.h>
#include <errno.h>
-/* Conversions for the California Cooperative Oceanic Fisheries Investigations
+/* Conversions for the California Cooperative Oceanic Fisheries Investigations
Line/Station coordinate system following the algorithm of:
-Eber, L.E., and R.P. Hewitt. 1979. Conversion algorithms for the CALCOFI
-station grid. California Cooperative Oceanic Fisheries Investigations Reports
-20:135-137. (corrected for typographical errors).
+Eber, L.E., and R.P. Hewitt. 1979. Conversion algorithms for the CALCOFI
+station grid. California Cooperative Oceanic Fisheries Investigations Reports
+20:135-137. (corrected for typographical errors).
http://www.calcofi.org/publications/calcofireports/v20/Vol_20_Eber___Hewitt.pdf
-They assume 1 unit of CalCOFI Line == 1/5 degree in longitude or
-meridional units at reference point O, and similarly 1 unit of CalCOFI
-Station == 1/15 of a degree at O.
-By convention, CalCOFI Line/Station conversions use Clarke 1866 but we use
+They assume 1 unit of CalCOFI Line == 1/5 degree in longitude or
+meridional units at reference point O, and similarly 1 unit of CalCOFI
+Station == 1/15 of a degree at O.
+By convention, CalCOFI Line/Station conversions use Clarke 1866 but we use
whatever ellipsoid is provided. */
-PROJ_HEAD(calcofi,
- "Cal Coop Ocean Fish Invest Lines/Stations") "\n\tCyl, Sph&Ell";
#define EPS10 1.e-10
#define DEG_TO_LINE 5
@@ -31,14 +33,17 @@ PROJ_HEAD(calcofi,
#define PT_O_LAMBDA -2.1144663887911301 /* lon -121.15 and */
#define PT_O_PHI 0.59602993955606354 /* lat 34.15 */
#define ROTATION_ANGLE 0.52359877559829882 /*CalCOFI angle of 30 deg in rad */
-FORWARD(e_forward); /* ellipsoid */
+
+
+static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */
+ XY xy = {0.0,0.0};
double oy; /* pt O y value in Mercator */
double l1; /* l1 and l2 are distances calculated using trig that sum
to the east/west distance between point O and point xy */
double l2;
- double ry; /* r is the point on the same station as o (60) and the same
+ double ry; /* r is the point on the same station as o (60) and the same
line as xy xy, r, o form a right triangle */
- /* if the user has specified +lon_0 or +k0 for some reason,
+ /* if the user has specified +lon_0 or +k0 for some reason,
we're going to ignore it so that xy is consistent with point O */
lp.lam = lp.lam + P->lam0;
if (fabs(fabs(lp.phi) - HALFPI) <= EPS10) F_ERROR;
@@ -49,18 +54,21 @@ FORWARD(e_forward); /* ellipsoid */
l2 = -xy.x - l1 + PT_O_LAMBDA;
ry = l2 * cos(ROTATION_ANGLE) * sin(ROTATION_ANGLE) + xy.y;
ry = pj_phi2(P->ctx, exp(-ry), P->e); /*inverse Mercator*/
- xy.x = PT_O_LINE - RAD_TO_DEG *
- (ry - PT_O_PHI) * DEG_TO_LINE / cos(ROTATION_ANGLE);
- xy.y = PT_O_STATION + RAD_TO_DEG *
+ xy.x = PT_O_LINE - RAD_TO_DEG *
+ (ry - PT_O_PHI) * DEG_TO_LINE / cos(ROTATION_ANGLE);
+ xy.y = PT_O_STATION + RAD_TO_DEG *
(ry - lp.phi) * DEG_TO_STATION / sin(ROTATION_ANGLE);
/* set a = 1, x0 = 0, and y0 = 0 so that no further unit adjustments
are done */
P->a = 1;
P->x0 = 0;
P->y0 = 0;
- return (xy);
+ return xy;
}
-FORWARD(s_forward); /* spheroid */
+
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0,0.0};
double oy;
double l1;
double l2;
@@ -73,17 +81,20 @@ FORWARD(s_forward); /* spheroid */
l1 = (xy.y - oy) * tan(ROTATION_ANGLE);
l2 = -xy.x - l1 + PT_O_LAMBDA;
ry = l2 * cos(ROTATION_ANGLE) * sin(ROTATION_ANGLE) + xy.y;
- ry = HALFPI - 2. * atan(exp(-ry));
- xy.x = PT_O_LINE - RAD_TO_DEG *
- (ry - PT_O_PHI) * DEG_TO_LINE / cos(ROTATION_ANGLE);
- xy.y = PT_O_STATION + RAD_TO_DEG *
+ ry = HALFPI - 2. * atan(exp(-ry));
+ xy.x = PT_O_LINE - RAD_TO_DEG *
+ (ry - PT_O_PHI) * DEG_TO_LINE / cos(ROTATION_ANGLE);
+ xy.y = PT_O_STATION + RAD_TO_DEG *
(ry - lp.phi) * DEG_TO_STATION / sin(ROTATION_ANGLE);
P->a = 1;
P->x0 = 0;
P->y0 = 0;
- return (xy);
+ return xy;
}
-INVERSE(e_inverse); /* ellipsoid */
+
+
+static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */
+ LP lp = {0.0,0.0};
double ry; /* y value of point r */
double oymctr; /* Mercator-transformed y value of point O */
double rymctr; /* Mercator-transformed ry */
@@ -93,7 +104,7 @@ INVERSE(e_inverse); /* ellipsoid */
/* turn x and y back into Line/Station */
xy.x /= P->ra;
xy.y /= P->ra;
- ry = PT_O_PHI - LINE_TO_RAD * (xy.x - PT_O_LINE) *
+ ry = PT_O_PHI - LINE_TO_RAD * (xy.x - PT_O_LINE) *
cos(ROTATION_ANGLE);
lp.phi = ry - STATION_TO_RAD * (xy.y - PT_O_STATION) * sin(ROTATION_ANGLE);
oymctr = -log(pj_tsfn(PT_O_PHI, sin(PT_O_PHI), P->e));
@@ -103,9 +114,12 @@ INVERSE(e_inverse); /* ellipsoid */
l2 = (rymctr - xymctr) / (cos(ROTATION_ANGLE) * sin(ROTATION_ANGLE));
lp.lam = PT_O_LAMBDA - (l1 + l2);
P->over = 1;
- return (lp);
+ return lp;
}
-INVERSE(s_inverse); /* spheroid */
+
+
+static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
+ LP lp = {0.0,0.0};
double ry;
double oymctr;
double rymctr;
@@ -114,7 +128,7 @@ INVERSE(s_inverse); /* spheroid */
double l2;
xy.x /= P->ra;
xy.y /= P->ra;
- ry = PT_O_PHI - LINE_TO_RAD * (xy.x - PT_O_LINE) *
+ ry = PT_O_PHI - LINE_TO_RAD * (xy.x - PT_O_LINE) *
cos(ROTATION_ANGLE);
lp.phi = ry - STATION_TO_RAD * (xy.y - PT_O_STATION) * sin(ROTATION_ANGLE);
oymctr = log(tan(FORTPI + .5 * PT_O_PHI));
@@ -124,10 +138,25 @@ INVERSE(s_inverse); /* spheroid */
l2 = (rymctr - xymctr) / (cos(ROTATION_ANGLE) * sin(ROTATION_ANGLE));
lp.lam = PT_O_LAMBDA - (l1 + l2);
P->over = 1;
- return (lp);
+ return lp;
}
-FREEUP; if (P) pj_dalloc(P); }
-ENTRY0(calcofi)
+
+
+static void *freeup_new (PJ *P) { /* Destructor */
+ return pj_dealloc (P);
+}
+
+static void freeup (PJ *P) {
+ freeup_new (P);
+ return;
+}
+
+
+PJ *PROJECTION(calcofi) {
+ P->opaque = 0;
+
+ P->pfree = freeup;
+ P->descr = des_calcofi;
if (P->es) { /* ellipsoid */
P->inv = e_inverse;
P->fwd = e_forward;
@@ -135,4 +164,65 @@ ENTRY0(calcofi)
P->inv = s_inverse;
P->fwd = s_forward;
}
-ENDENTRY(P)
+ return P;
+}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_calcofi_selftest (void) {return 0;}
+#else
+
+int pj_calcofi_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char e_args[] = {"+proj=calcofi +ellps=GRS80 +lat_1=0.5 +lat_2=2"};
+ char s_args[] = {"+proj=calcofi +a=6400000 +lat_1=0.5 +lat_2=2"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY e_fwd_expect[] = {
+ {508.44487214981905, -1171.7648604175156},
+ {514.99916815188112, -1145.8219814677668},
+ {500.68538412539851, -1131.4453779204598},
+ {507.36971913666355, -1106.1782014834275},
+ };
+
+ XY s_fwd_expect[] = {
+ {507.09050748781806, -1164.7273751978314},
+ {513.68613637462886, -1138.9992682173072},
+ {499.33626147591531, -1124.4351309968195},
+ {506.0605703929898, -1099.3756650673038},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP e_inv_expect[] = {
+ {-110.36330792469906, 12.032056975840137},
+ {-98.455008863288782, 18.698723642506803},
+ {-207.4470245036909, 81.314089278595247},
+ {-62.486322854481287, 87.980755945261919},
+ };
+
+ LP s_inv_expect[] = {
+ {-110.30519040955151, 12.032056975840137},
+ {-98.322360950234085, 18.698723642506803},
+ {-207.54490681381429, 81.314089278595247},
+ {-62.576950371885275, 87.980755945261919},
+ };
+
+ 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
diff --git a/src/PJ_cass.c b/src/PJ_cass.c
index 5f885376..28d35b91 100644
--- a/src/PJ_cass.c
+++ b/src/PJ_cass.c
@@ -1,96 +1,90 @@
#define PJ_LIB__
-# include <projects.h>
+# include <projects.h>
PROJ_HEAD(cass, "Cassini") "\n\tCyl, Sph&Ell";
-# define EPS10 1e-10
-# define C1 .16666666666666666666
-# define C2 .00833333333333333333
-# define C3 .04166666666666666666
-# define C4 .33333333333333333333
-# define C5 .06666666666666666666
+# define EPS10 1e-10
+# define C1 .16666666666666666666
+# define C2 .00833333333333333333
+# define C3 .04166666666666666666
+# define C4 .33333333333333333333
+# define C5 .06666666666666666666
struct pj_opaque {
- /* These are the only opaque members actually initialized */
- double *en;
- double m0;
-
- /* Apparently this group of opaque members should be demoted to local variables in e_forward and e_inverse */
- double n;
- double t;
- double a1;
- double c;
- double r;
- double dd;
- double d2;
- double a2;
- double tn;
+ double *en;
+ double m0;
};
static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */
- XY xy = {0.0,0.0};
+ double n, t, a1, c, a2, tn;
+ XY xy = {0.0, 0.0};
struct pj_opaque *Q = P->opaque;
- xy.y = pj_mlfn(lp.phi, Q->n = sin(lp.phi), Q->c = cos(lp.phi), Q->en);
- Q->n = 1./sqrt(1. - P->es * Q->n * Q->n);
- Q->tn = tan(lp.phi); Q->t = Q->tn * Q->tn;
- Q->a1 = lp.lam * Q->c;
- Q->c *= P->es * Q->c / (1 - P->es);
- Q->a2 = Q->a1 * Q->a1;
- xy.x = Q->n * Q->a1 * (1. - Q->a2 * Q->t *
- (C1 - (8. - Q->t + 8. * Q->c) * Q->a2 * C2));
- xy.y -= Q->m0 - Q->n * Q->tn * Q->a2 *
- (.5 + (5. - Q->t + 6. * Q->c) * Q->a2 * C3);
- return xy;
+
+ xy.y = pj_mlfn (lp.phi, n = sin (lp.phi), c = cos (lp.phi), Q->en);
+
+ n = 1./sqrt(1. - P->es * n*n);
+ tn = tan(lp.phi); t = tn * tn;
+ a1 = lp.lam * c;
+ c *= P->es * c / (1 - P->es);
+ a2 = a1 * a1;
+
+ xy.x = n * a1 * (1. - a2 * t *
+ (C1 - (8. - t + 8. * c) * a2 * C2));
+ xy.y -= Q->m0 - n * tn * a2 *
+ (.5 + (5. - t + 6. * c) * a2 * C3);
+
+ return xy;
}
static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
- XY xy = {0.0,0.0};
- xy.x = asin(cos(lp.phi) * sin(lp.lam));
- xy.y = atan2(tan(lp.phi) , cos(lp.lam)) - P->phi0;
- return xy;
+ XY xy = {0.0, 0.0};
+ xy.x = asin (cos (lp.phi) * sin (lp.lam));
+ xy.y = atan2 (tan (lp.phi), cos (lp.lam)) - P->phi0;
+ return xy;
}
static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */
- LP lp = {0.0,0.0};
+ double n, t, r, dd, d2, tn, ph1;
+ LP lp = {0.0, 0.0};
struct pj_opaque *Q = P->opaque;
- double ph1;
-
- ph1 = pj_inv_mlfn(P->ctx, Q->m0 + xy.y, P->es, Q->en);
- Q->tn = tan(ph1); Q->t = Q->tn * Q->tn;
- Q->n = sin(ph1);
- Q->r = 1. / (1. - P->es * Q->n * Q->n);
- Q->n = sqrt(Q->r);
- Q->r *= (1. - P->es) * Q->n;
- Q->dd = xy.x / Q->n;
- Q->d2 = Q->dd * Q->dd;
- lp.phi = ph1 - (Q->n * Q->tn / Q->r) * Q->d2 *
- (.5 - (1. + 3. * Q->t) * Q->d2 * C3);
- lp.lam = Q->dd * (1. + Q->t * Q->d2 *
- (-C4 + (1. + 3. * Q->t) * Q->d2 * C5)) / cos(ph1);
- return lp;
+
+ ph1 = pj_inv_mlfn (P->ctx, Q->m0 + xy.y, P->es, Q->en);
+ tn = tan (ph1); t = tn*tn;
+ n = sin (ph1);
+ r = 1. / (1. - P->es * n * n);
+ n = sqrt (r);
+ r *= (1. - P->es) * n;
+ dd = xy.x / n;
+ d2 = dd * dd;
+ lp.phi = ph1 - (n * tn / r) * d2 *
+ (.5 - (1. + 3. * t) * d2 * C3);
+ lp.lam = dd * (1. + t * d2 *
+ (-C4 + (1. + 3. * t) * d2 * C5)) / cos (ph1);
+ return lp;
}
static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
LP lp = {0.0,0.0};
- lp.phi = asin(sin(P->opaque->dd = xy.y + P->phi0) * cos(xy.x));
- lp.lam = atan2(tan(xy.x), cos(P->opaque->dd));
- return lp;
+ double dd;
+ lp.phi = asin(sin(dd = xy.y + P->phi0) * cos(xy.x));
+ lp.lam = atan2(tan(xy.x), cos(dd));
+ return lp;
}
static void *freeup_new(PJ *P) { /* Destructor */
- if (0==P)
+ if (0==P)
return 0;
if (0==P->opaque)
return pj_dealloc (P);
- pj_dealloc(P->opaque->en);
+ pj_dealloc(P->opaque->en);
pj_dealloc(P->opaque);
return pj_dealloc(P);
}
@@ -103,28 +97,82 @@ static void freeup(PJ *P) { /* Destructor */
PJ *PROJECTION(cass) {
/* Spheroidal? */
- if (0==P->es) {
- P->inv = s_inverse;
- P->fwd = s_forward;
+ if (0==P->es) {
+ P->inv = s_inverse;
+ P->fwd = s_forward;
return P;
}
- /* Otherwise it's ellipsoidal */
+ /* otherwise it's ellipsoidal */
P->opaque = pj_calloc (1, sizeof (struct pj_opaque));
- if (0==P->opaque) {
- freeup (P);
- return 0;
- }
+ if (0==P->opaque)
+ return freeup_new (P);
- P->opaque->en = pj_enfn(P->es);
- if (0==P->opaque->en) {
- freeup (P);
- return 0;
- }
+ P->opaque->en = pj_enfn (P->es);
+ if (0==P->opaque->en)
+ return freeup_new (P);
- P->opaque->m0 = pj_mlfn(P->phi0, sin(P->phi0), cos(P->phi0), P->opaque->en);
- P->inv = e_inverse;
- P->fwd = e_forward;
+ P->opaque->m0 = pj_mlfn (P->phi0, sin (P->phi0), cos (P->phi0), P->opaque->en);
+ P->inv = e_inverse;
+ P->fwd = e_forward;
return P;
}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_cass_selftest (void) {return 0;}
+#else
+
+int pj_cass_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char e_args[] = {"+proj=cass +ellps=GRS80 +lat_1=0.5 +lat_2=2"};
+ char s_args[] = {"+proj=cass +a=6400000 +lat_1=0.5 +lat_2=2"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY e_fwd_expect[] = {
+ { 222605.28577699114, 110642.22925399939},
+ { 222605.28577699114, -110642.22925399939},
+ {-222605.28577699114, 110642.22925399939},
+ {-222605.28577699114, -110642.22925399939},
+ };
+
+ XY s_fwd_expect[] = {
+ { 223368.10520348375, 111769.14504058579},
+ { 223368.10520348375, -111769.14504058579},
+ {-223368.10520348375, 111769.14504058579},
+ {-223368.10520348375, -111769.14504058579},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP e_inv_expect[] = {
+ { 0.0017966305684613522, 0.00090436947663183841},
+ { 0.0017966305684613522, -0.00090436947663183841},
+ {-0.0017966305684613522, 0.00090436947663183841},
+ {-0.0017966305684613522, -0.00090436947663183841},
+ };
+
+ LP s_inv_expect[] = {
+ { 0.0017904931100023887, 0.00089524655445477922},
+ { 0.0017904931100023887, -0.00089524655445477922},
+ {-0.0017904931100023887, 0.00089524655445477922},
+ {-0.0017904931100023887, -0.00089524655445477922},
+ };
+
+ 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
diff --git a/src/PJ_cc.c b/src/PJ_cc.c
index 0f573929..475fbae4 100644
--- a/src/PJ_cc.c
+++ b/src/PJ_cc.c
@@ -1,20 +1,89 @@
-#define PROJ_PARMS__ \
- double ap;
#define PJ_LIB__
#include <projects.h>
+
PROJ_HEAD(cc, "Central Cylindrical") "\n\tCyl, Sph";
#define EPS10 1.e-10
-FORWARD(s_forward); /* spheroid */
- if (fabs(fabs(lp.phi) - HALFPI) <= EPS10) F_ERROR;
+
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0,0.0};
+ if (fabs (fabs(lp.phi) - HALFPI) <= EPS10) F_ERROR;
xy.x = lp.lam;
xy.y = tan(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};
(void) P;
lp.phi = atan(xy.y);
lp.lam = xy.x;
- return (lp);
+ return lp;
}
-FREEUP; if (P) pj_dalloc(P); }
-ENTRY0(cc) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
+
+
+static void *freeup_new (PJ *P) { /* Destructor */
+ return pj_dealloc(P);
+}
+
+
+static void freeup (PJ *P) {
+ freeup_new (P);
+ return;
+}
+
+
+PJ *PROJECTION(cc) {
+ P->es = 0.;
+
+ P->inv = s_inverse;
+ P->fwd = s_forward;
+
+ return P;
+}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_cc_selftest (void) {return 0;}
+#else
+
+int pj_cc_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char s_args[] = {"+proj=cc +a=6400000 +lat_1=0.5 +lat_2=2"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY s_fwd_expect[] = {
+ {223402.14425527418, 111712.41554059254},
+ {223402.14425527418, -111712.41554059254},
+ {-223402.14425527418, 111712.41554059254},
+ {-223402.14425527418, -111712.41554059254},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP s_inv_expect[] = {
+ {0.0017904931097838226, 0.00089524655481905597},
+ {0.0017904931097838226, -0.00089524655481905597},
+ {-0.0017904931097838226, 0.00089524655481905597},
+ {-0.0017904931097838226, -0.00089524655481905597},
+ };
+
+ 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);
+}
+
+
+#endif
diff --git a/src/PJ_wag2.c b/src/PJ_wag2.c
index f4942bb2..b70dcd4f 100644
--- a/src/PJ_wag2.c
+++ b/src/PJ_wag2.c
@@ -5,17 +5,84 @@ PROJ_HEAD(wag2, "Wagner II") "\n\tPCyl., Sph.";
#define C_y 1.38725
#define C_p1 0.88022
#define C_p2 0.88550
-FORWARD(s_forward); /* spheroid */
- lp.phi = aasin(P->ctx,C_p1 * sin(C_p2 * lp.phi));
- xy.x = C_x * lp.lam * cos(lp.phi);
+
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0,0.0};
+ lp.phi = aasin (P->ctx,C_p1 * sin (C_p2 * lp.phi));
+ xy.x = C_x * lp.lam * cos (lp.phi);
xy.y = C_y * lp.phi;
return (xy);
}
-INVERSE(s_inverse); /* spheroid */
+
+
+static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
+ LP lp = {0.0,0.0};
lp.phi = xy.y / C_y;
lp.lam = xy.x / (C_x * cos(lp.phi));
- lp.phi = aasin(P->ctx,sin(lp.phi) / C_p1) / C_p2;
+ lp.phi = aasin (P->ctx,sin(lp.phi) / C_p1) / C_p2;
return (lp);
}
-FREEUP; if (P) pj_dalloc(P); }
-ENTRY0(wag2) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
+
+
+static void *freeup_new (PJ *P) { /* Destructor */
+ return pj_dealloc(P);
+}
+
+static void freeup (PJ *P) {
+ freeup_new (P);
+ return;
+}
+
+
+PJ *PROJECTION(wag2) {
+ P->es = 0.;
+ P->inv = s_inverse;
+ P->fwd = s_forward;
+ return P;
+}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_wag2_selftest (void) {return 0;}
+#else
+
+int pj_wag2_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char s_args[] = {"+proj=wag2 +a=6400000 +lat_1=0.5 +lat_2=2"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY s_fwd_expect[] = {
+ { 206589.88809996162, 120778.04035754716},
+ { 206589.88809996162, -120778.04035754716},
+ {-206589.88809996162, 120778.04035754716},
+ {-206589.88809996162, -120778.04035754716},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP s_inv_expect[] = {
+ { 0.0019360240367390709, 0.00082795765763814082},
+ { 0.0019360240367390709, -0.00082795765763814082},
+ {-0.0019360240367390709, 0.00082795765763814082},
+ {-0.0019360240367390709, -0.00082795765763814082},
+ };
+
+ 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);
+}
+
+
+#endif
diff --git a/src/PJ_wag3.c b/src/PJ_wag3.c
index 482e389c..0539f4a1 100644
--- a/src/PJ_wag3.c
+++ b/src/PJ_wag3.c
@@ -1,24 +1,101 @@
-#define PROJ_PARMS__ \
- double C_x;
#define PJ_LIB__
# include <projects.h>
PROJ_HEAD(wag3, "Wagner III") "\n\tPCyl., Sph.\n\tlat_ts=";
#define TWOTHIRD 0.6666666666666666666667
-FORWARD(s_forward); /* spheroid */
- xy.x = P->C_x * lp.lam * cos(TWOTHIRD * lp.phi);
+
+struct pj_opaque {
+ double C_x;
+};
+
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0,0.0};
+ xy.x = P->opaque->C_x * lp.lam * cos(TWOTHIRD * lp.phi);
xy.y = lp.phi;
- return (xy);
+ return xy;
}
+
+
+#if 0
INVERSE(s_inverse); /* spheroid */
+#endif
+
+
+static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
+ LP lp = {0.0,0.0};
lp.phi = xy.y;
- lp.lam = xy.x / (P->C_x * cos(TWOTHIRD * lp.phi));
- return (lp);
+ lp.lam = xy.x / (P->opaque->C_x * cos(TWOTHIRD * lp.phi));
+ return lp;
+}
+
+
+static void *freeup_new (PJ *P) { /* Destructor */
+ return pj_dealloc(P);
}
-FREEUP; if (P) pj_dalloc(P); }
-ENTRY0(wag3)
+
+static void freeup (PJ *P) {
+ freeup_new (P);
+ return;
+}
+
+
+PJ *PROJECTION(wag3) {
double ts;
+ struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
+ if (0==Q)
+ return freeup_new (P);
+ P->opaque = Q;
+
+ ts = pj_param (P->ctx, P->params, "rlat_ts").f;
+ P->opaque->C_x = cos (ts) / cos (2.*ts/3.);
+ P->es = 0.;
+ P->inv = s_inverse;
+ P->fwd = s_forward;
+
+ return P;
+}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_wag3_selftest (void) {return 0;}
+#else
+
+int pj_wag3_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char s_args[] = {"+proj=wag3 +a=6400000 +lat_1=0.5 +lat_2=2"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY s_fwd_expect[] = {
+ {223387.02171816575, 111701.07212763709},
+ {223387.02171816575, -111701.07212763709},
+ {-223387.02171816575, 111701.07212763709},
+ {-223387.02171816575, -111701.07212763709},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP s_inv_expect[] = {
+ {0.001790493109880963, 0.00089524655489191132},
+ {0.001790493109880963, -0.00089524655489191132},
+ {-0.001790493109880963, 0.00089524655489191132},
+ {-0.001790493109880963, -0.00089524655489191132},
+ };
+
+ 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);
+}
+
- ts = pj_param(P->ctx, P->params, "rlat_ts").f;
- P->C_x = cos(ts) / cos(2.*ts/3.);
- P->es = 0.; P->inv = s_inverse; P->fwd = s_forward;
-ENDENTRY(P)
+#endif
diff --git a/src/PJ_wag7.c b/src/PJ_wag7.c
index db29ffb1..847566d8 100644
--- a/src/PJ_wag7.c
+++ b/src/PJ_wag7.c
@@ -1,15 +1,67 @@
#define PJ_LIB__
#include <projects.h>
+
PROJ_HEAD(wag7, "Wagner VII") "\n\tMisc Sph, no inv.";
-FORWARD(s_forward); /* sphere */
+
+
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0, 0.0};
double theta, ct, D;
- (void) P;
- theta = asin(xy.y = 0.90630778703664996 * sin(lp.phi));
- xy.x = 2.66723 * (ct = cos(theta)) * sin(lp.lam /= 3.);
- xy.y *= 1.24104 * (D = 1/(sqrt(0.5 * (1 + ct * cos(lp.lam)))));
+ (void) P; /* Shut up compiler warnnings about unused P */
+
+ theta = asin (xy.y = 0.90630778703664996 * sin(lp.phi));
+ xy.x = 2.66723 * (ct = cos (theta)) * sin (lp.lam /= 3.);
+ xy.y *= 1.24104 * (D = 1/(sqrt (0.5 * (1 + ct * cos (lp.lam)))));
xy.x *= D;
return (xy);
}
-FREEUP; if (P) pj_dalloc(P); }
-ENTRY0(wag7) P->fwd = s_forward; P->inv = 0; P->es = 0.; ENDENTRY(P)
+
+
+static void *freeup_new (PJ *P) { /* Destructor */
+ return pj_dealloc(P);
+}
+
+static void freeup (PJ *P) {
+ freeup_new (P);
+ return;
+}
+
+
+
+PJ *PROJECTION(wag7) {
+ P->fwd = s_forward;
+ P->inv = 0;
+ P->es = 0.;
+ return P;
+}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_wag7_selftest (void) {return 0;}
+#else
+
+int pj_wag7_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char s_args[] = {"+proj=wag7 +a=6400000 +lat_1=0.5 +lat_2=2"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY s_fwd_expect[] = {
+ { 198601.87695731167, 125637.0457141714},
+ { 198601.87695731167, -125637.0457141714},
+ {-198601.87695731167, 125637.0457141714},
+ {-198601.87695731167, -125637.0457141714},
+ };
+
+ return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0);
+}
+#endif
diff --git a/src/PJ_wink1.c b/src/PJ_wink1.c
index dfb455e0..f9d127c0 100644
--- a/src/PJ_wink1.c
+++ b/src/PJ_wink1.c
@@ -1,20 +1,100 @@
-#define PROJ_PARMS__ \
- double cosphi1;
#define PJ_LIB__
-# include <projects.h>
+#include <projects.h>
PROJ_HEAD(wink1, "Winkel I") "\n\tPCyl., Sph.\n\tlat_ts=";
-FORWARD(s_forward); /* spheroid */
- xy.x = .5 * lp.lam * (P->cosphi1 + cos(lp.phi));
+
+
+struct pj_opaque {
+ double cosphi1;
+};
+
+
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0,0.0};
+ xy.x = .5 * lp.lam * (P->opaque->cosphi1 + cos(lp.phi));
xy.y = lp.phi;
return (xy);
}
-INVERSE(s_inverse); /* spheroid */
+
+
+static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
+ LP lp = {0.0,0.0};
lp.phi = xy.y;
- lp.lam = 2. * xy.x / (P->cosphi1 + cos(lp.phi));
+ lp.lam = 2. * xy.x / (P->opaque->cosphi1 + cos(lp.phi));
return (lp);
}
-FREEUP; if (P) pj_dalloc(P); }
-ENTRY0(wink1)
- P->cosphi1 = cos(pj_param(P->ctx, P->params, "rlat_ts").f);
- P->es = 0.; P->inv = s_inverse; P->fwd = s_forward;
-ENDENTRY(P)
+
+
+static void *freeup_new (PJ *P) { /* Destructor */
+ if (0==P)
+ return 0;
+ if (0==P->opaque)
+ return pj_dealloc (P);
+ pj_dealloc (P->opaque);
+ return pj_dealloc(P);
+}
+
+static void freeup (PJ *P) {
+ freeup_new (P);
+ return;
+}
+
+
+PJ *PROJECTION(wink1) {
+ struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
+ if (0==Q)
+ return freeup_new (P);
+ P->opaque = Q;
+
+ P->opaque->cosphi1 = cos (pj_param(P->ctx, P->params, "rlat_ts").f);
+ P->es = 0.;
+ P->inv = s_inverse;
+ P->fwd = s_forward;
+
+ return P;
+}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_wink1_selftest (void) {return 0;}
+#else
+
+int pj_wink1_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char s_args[] = {"+proj=wink1 +a=6400000 +lat_1=0.5 +lat_2=2"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY s_fwd_expect[] = {
+ { 223385.13164095284, 111701.07212763709},
+ { 223385.13164095284, -111701.07212763709},
+ {-223385.13164095284, 111701.07212763709},
+ {-223385.13164095284, -111701.07212763709},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP s_inv_expect[] = {
+ { 0.0017904931098931057, 0.00089524655489191132},
+ { 0.0017904931098931057, -0.00089524655489191132},
+ {-0.0017904931098931057, 0.00089524655489191132},
+ {-0.0017904931098931057, -0.00089524655489191132},
+ };
+
+ 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);
+}
+
+
+#endif
diff --git a/src/PJ_wink2.c b/src/PJ_wink2.c
index 388c790a..f31ba5a5 100644
--- a/src/PJ_wink2.c
+++ b/src/PJ_wink2.c
@@ -1,34 +1,93 @@
-#define PROJ_PARMS__ \
- double cosphi1;
#define PJ_LIB__
# include <projects.h>
+
PROJ_HEAD(wink2, "Winkel II") "\n\tPCyl., Sph., no inv.\n\tlat_1=";
+
+struct pj_opaque { double cosphi1; };
+
#define MAX_ITER 10
#define LOOP_TOL 1e-7
#define TWO_D_PI 0.636619772367581343
-FORWARD(s_forward); /* spheroid */
+
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0, 0.0};
double k, V;
int i;
xy.y = lp.phi * TWO_D_PI;
- k = PI * sin(lp.phi);
+ k = PI * sin (lp.phi);
lp.phi *= 1.8;
for (i = MAX_ITER; i ; --i) {
- lp.phi -= V = (lp.phi + sin(lp.phi) - k) /
- (1. + cos(lp.phi));
- if (fabs(V) < LOOP_TOL)
+ lp.phi -= V = (lp.phi + sin (lp.phi) - k) /
+ (1. + cos (lp.phi));
+ if (fabs (V) < LOOP_TOL)
break;
}
if (!i)
lp.phi = (lp.phi < 0.) ? -HALFPI : HALFPI;
else
lp.phi *= 0.5;
- xy.x = 0.5 * lp.lam * (cos(lp.phi) + P->cosphi1);
- xy.y = FORTPI * (sin(lp.phi) + xy.y);
- return (xy);
+ xy.x = 0.5 * lp.lam * (cos (lp.phi) + P->opaque->cosphi1);
+ xy.y = FORTPI * (sin (lp.phi) + xy.y);
+ return xy;
+}
+
+
+static void *freeup_new (PJ *P) { /* Destructor */
+ if (0==P)
+ return 0;
+ if (0==P->opaque)
+ return pj_dealloc (P);
+ pj_dealloc (P->opaque);
+ return pj_dealloc(P);
+}
+
+static void freeup (PJ *P) {
+ freeup_new (P);
+ return;
+}
+
+
+PJ *PROJECTION(wink2) {
+ struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
+ if (0==Q)
+ return freeup_new (P);
+ P->opaque = Q;
+
+ P->opaque->cosphi1 = cos(pj_param(P->ctx, P->params, "rlat_1").f);
+ P->es = 0.;
+ P->inv = 0;
+ P->fwd = s_forward;
+
+ return P;
+}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_wink2_selftest (void) {return 0;}
+#else
+
+int pj_wink2_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char s_args[] = {"+proj=wink2 +a=6400000 +lat_1=0.5 +lat_2=2"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY s_fwd_expect[] = {
+ { 223387.39643378611, 124752.03279744535},
+ { 223387.39643378611, -124752.03279744535},
+ {-223387.39643378611, 124752.03279744535},
+ {-223387.39643378611, -124752.03279744535},
+ };
+
+ return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0);
}
-FREEUP; if (P) pj_dalloc(P); }
-ENTRY0(wink2)
- P->cosphi1 = cos(pj_param(P->ctx, P->params, "rlat_1").f);
- P->es = 0.; P->inv = 0; P->fwd = s_forward;
-ENDENTRY(P)
+#endif
diff --git a/src/projects.h b/src/projects.h
index 307b69bd..2957f848 100644
--- a/src/projects.h
+++ b/src/projects.h
@@ -359,7 +359,7 @@ extern struct PJ_PRIME_MERIDIANS pj_prime_meridians[];
#define INVERSE3D(name) static LPZ name(XYZ xyz, PJ *P) {LPZ lpz = {0.0, 0.0, 0.0}
#define FREEUP static void freeup(PJ *P) {
#define SPECIAL(name) static void name(LP lp, PJ *P, struct FACTORS *fac)
-
+#define ELLIPSOIDAL(P) ((P->es==0)? (FALSE): (TRUE))
/* cleaned up alternative to most of the "repetitive projection code" macros */
#define PROJECTION(name) \