aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKristian Evers <kristianevers@gmail.com>2016-05-03 19:51:52 +0200
committerKristian Evers <kristianevers@gmail.com>2016-05-03 19:51:52 +0200
commit5e02d7221b994e80c922a14c17755fe5473ec29f (patch)
tree8b2377d9ab60ce9222e0161b4defe59d91f7c2f0 /src
parent492c4048772e4441dbe07c6f74f22efea5c0d5c0 (diff)
downloadPROJ-5e02d7221b994e80c922a14c17755fe5473ec29f.tar.gz
PROJ-5e02d7221b994e80c922a14c17755fe5473ec29f.zip
Converted ortho
Diffstat (limited to 'src')
-rw-r--r--src/PJ_aea.c1
-rw-r--r--src/PJ_ortho.c131
2 files changed, 105 insertions, 27 deletions
diff --git a/src/PJ_aea.c b/src/PJ_aea.c
index a7806344..5f1c369f 100644
--- a/src/PJ_aea.c
+++ b/src/PJ_aea.c
@@ -365,7 +365,6 @@ int pj_lonlat_selftest (void) {return 10000;}
int pj_longlat_selftest (void) {return 10000;}
int pj_ob_tran_selftest (void) {return 10000;}
-int pj_ortho_selftest (void) {return 10000;}
int pj_patterson_selftest (void) {return 10000;}
int pj_poly_selftest (void) {return 10000;}
int pj_putp2_selftest (void) {return 10000;}
diff --git a/src/PJ_ortho.c b/src/PJ_ortho.c
index 202b0176..14aeacc3 100644
--- a/src/PJ_ortho.c
+++ b/src/PJ_ortho.c
@@ -1,29 +1,37 @@
-#define PROJ_PARMS__ \
- double sinph0; \
- double cosph0; \
- int mode;
#define PJ_LIB__
-#include <projects.h>
+#include <projects.h>
+
PROJ_HEAD(ortho, "Orthographic") "\n\tAzi, Sph.";
+
+struct pj_opaque {
+ double sinph0;
+ double cosph0;
+ int mode;
+};
+
#define EPS10 1.e-10
#define N_POLE 0
#define S_POLE 1
#define EQUIT 2
#define OBLIQ 3
-FORWARD(s_forward); /* spheroid */
+
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0,0.0};
+ struct pj_opaque *Q = P->opaque;
double coslam, cosphi, sinphi;
cosphi = cos(lp.phi);
coslam = cos(lp.lam);
- switch (P->mode) {
+ switch (Q->mode) {
case EQUIT:
if (cosphi * coslam < - EPS10) F_ERROR;
xy.y = sin(lp.phi);
break;
case OBLIQ:
- if (P->sinph0 * (sinphi = sin(lp.phi)) +
- P->cosph0 * cosphi * coslam < - EPS10) F_ERROR;
- xy.y = P->cosph0 * sinphi - P->sinph0 * cosphi * coslam;
+ if (Q->sinph0 * (sinphi = sin(lp.phi)) +
+ Q->cosph0 * cosphi * coslam < - EPS10) F_ERROR;
+ xy.y = Q->cosph0 * sinphi - Q->sinph0 * cosphi * coslam;
break;
case N_POLE:
coslam = - coslam;
@@ -33,10 +41,13 @@ FORWARD(s_forward); /* spheroid */
break;
}
xy.x = cosphi * sin(lp.lam);
- 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 rh, cosc, sinc;
if ((sinc = (rh = hypot(xy.x, xy.y))) > 1.) {
@@ -48,7 +59,7 @@ INVERSE(s_inverse); /* spheroid */
lp.phi = P->phi0;
lp.lam = 0.0;
} else {
- switch (P->mode) {
+ switch (Q->mode) {
case N_POLE:
xy.y = -xy.y;
lp.phi = acos(sinc);
@@ -62,9 +73,9 @@ INVERSE(s_inverse); /* spheroid */
xy.y = cosc * rh;
goto sinchk;
case OBLIQ:
- lp.phi = cosc * P->sinph0 + xy.y * sinc * P->cosph0 /rh;
- xy.y = (cosc - P->sinph0 * lp.phi) * rh;
- xy.x *= sinc * P->cosph0;
+ lp.phi = cosc * Q->sinph0 + xy.y * sinc * Q->cosph0 /rh;
+ xy.y = (cosc - Q->sinph0 * lp.phi) * rh;
+ xy.x *= sinc * Q->cosph0;
sinchk:
if (fabs(lp.phi) >= 1.)
lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
@@ -72,24 +83,92 @@ INVERSE(s_inverse); /* spheroid */
lp.phi = asin(lp.phi);
break;
}
- lp.lam = (xy.y == 0. && (P->mode == OBLIQ || P->mode == EQUIT))
+ lp.lam = (xy.y == 0. && (Q->mode == OBLIQ || Q->mode == EQUIT))
? (xy.x == 0. ? 0. : xy.x < 0. ? -HALFPI : HALFPI)
: atan2(xy.x, xy.y);
}
- return (lp);
+ return lp;
}
-FREEUP; if (P) pj_dalloc(P); }
-ENTRY0(ortho)
+
+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(ortho) {
+ struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
+ if (0==Q)
+ return freeup_new (P);
+ P->opaque = Q;
+
if (fabs(fabs(P->phi0) - HALFPI) <= EPS10)
- P->mode = P->phi0 < 0. ? S_POLE : N_POLE;
+ Q->mode = P->phi0 < 0. ? S_POLE : N_POLE;
else if (fabs(P->phi0) > EPS10) {
- P->mode = OBLIQ;
- P->sinph0 = sin(P->phi0);
- P->cosph0 = cos(P->phi0);
+ Q->mode = OBLIQ;
+ Q->sinph0 = sin(P->phi0);
+ Q->cosph0 = cos(P->phi0);
} else
- P->mode = EQUIT;
+ Q->mode = EQUIT;
P->inv = s_inverse;
P->fwd = s_forward;
P->es = 0.;
-ENDENTRY(P)
+
+ return P;
+}
+
+
+#ifdef PJ_OMIT_SELFTEST
+int pj_ortho_selftest (void) {return 0;}
+#else
+
+int pj_ortho_selftest (void) {
+ double tolerance_lp = 1e-10;
+ double tolerance_xy = 1e-7;
+
+ char s_args[] = {"+proj=ortho +a=6400000 +lat_1=0.5 +lat_2=2"};
+
+ LP fwd_in[] = {
+ { 2, 1},
+ { 2,-1},
+ {-2, 1},
+ {-2,-1}
+ };
+
+ XY s_fwd_expect[] = {
+ { 223322.76057672748, 111695.401198614476},
+ { 223322.76057672748, -111695.401198614476},
+ {-223322.76057672748, 111695.401198614476},
+ {-223322.76057672748, -111695.401198614476},
+ };
+
+ XY inv_in[] = {
+ { 200, 100},
+ { 200,-100},
+ {-200, 100},
+ {-200,-100}
+ };
+
+ LP s_inv_expect[] = {
+ { 0.0017904931102938101, 0.000895246554928338998},
+ { 0.0017904931102938101, -0.000895246554928338998},
+ {-0.0017904931102938101, 0.000895246554928338998},
+ {-0.0017904931102938101, -0.000895246554928338998},
+ };
+
+ 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