aboutsummaryrefslogtreecommitdiff
path: root/src/projections/PJ_tobmerc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/projections/PJ_tobmerc.cpp')
-rw-r--r--src/projections/PJ_tobmerc.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/projections/PJ_tobmerc.cpp b/src/projections/PJ_tobmerc.cpp
new file mode 100644
index 00000000..9c939f0b
--- /dev/null
+++ b/src/projections/PJ_tobmerc.cpp
@@ -0,0 +1,51 @@
+#define PJ_LIB__
+
+#include <float.h>
+#include <math.h>
+
+#include "proj_internal.h"
+#include "proj.h"
+#include "proj_math.h"
+#include "projects.h"
+
+PROJ_HEAD(tobmerc, "Tobler-Mercator") "\n\tCyl, Sph";
+
+#define EPS10 1.e-10
+static double logtanpfpim1(double x) { /* log(tan(x/2 + M_FORTPI)) */
+ if (fabs(x) <= DBL_EPSILON) {
+ /* tan(M_FORTPI + .5 * x) can be approximated by 1.0 + x */
+ return log1p(x);
+ }
+ return log(tan(M_FORTPI + .5 * x));
+}
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0, 0.0};
+ double cosphi;
+
+ if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10) {
+ proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
+ return xy;
+ }
+
+ cosphi = cos(lp.phi);
+ xy.x = P->k0 * lp.lam * cosphi * cosphi;
+ xy.y = P->k0 * logtanpfpim1(lp.phi);
+ return xy;
+}
+
+static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
+ LP lp = {0.0, 0.0};
+ double cosphi;
+
+ lp.phi = atan(sinh(xy.y / P->k0));
+ cosphi = cos(lp.phi);
+ lp.lam = xy.x / P->k0 / (cosphi * cosphi);
+ return lp;
+}
+
+PJ *PROJECTION(tobmerc) {
+ P->inv = s_inverse;
+ P->fwd = s_forward;
+ return P;
+}