-
Notifications
You must be signed in to change notification settings - Fork 814
/
Copy pathlatitudes.cpp
68 lines (62 loc) · 2.12 KB
/
latitudes.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
* Project: PROJ
*
* Helper functions to compute latitudes
*
* Some from Map Projections - A Working Manual. 1987. John P. Snyder
* https://neacsu.net/docs/geodesy/snyder/2-general/sect_3/
*
* Copyright (c) 2025 Javier Jimenez Shaw
*/
#include <math.h>
#include "proj_internal.h"
/*****************************************************************************/
double pj_conformal_lat(double phi, double e) {
/***********************************
* The conformal latitude chi
* giving a sphere which is truly conformal in accordance with the ellipsoid
* Snyder, A working manual, formula 3-1
*
* phi: geodetic latitude, in radians
* e: ellipsoid eccentricity
* returns: conformal latitude, in radians
***********************************/
if (e == 0.0)
return phi;
const double esinphi = e * sin(phi);
const double chi =
2 * atan(tan(M_FORTPI + phi / 2) *
std::pow(((1 - esinphi) / (1 + esinphi)), (e / 2))) -
M_HALFPI;
return chi;
}
/*****************************************************************************/
double pj_conformal_lat_inverse(double chi, double e, double threshold) {
/***********************************
* The inverse formula of the conformal latitude
* for phi (geodetic latitude) in terms of chi (conformal latitude),
* Snyder, A working manual, formula 3-4
*
* chi: conformal latitude, in radians
* e: ellipsoid eccentricity
* threshold: between two consecutive iteratinons to break the loop, radians
* returns: geodetic latitude, in radians
***********************************/
if (e == 0.0)
return chi;
const double taninit = tan(M_PI / 4 + chi / 2);
double phi = chi;
for (int i = 0; i < 10; i++) {
const double esinphi = e * sin(phi);
const double new_phi =
2 * atan(taninit *
std::pow(((1 + esinphi) / (1 - esinphi)), (e / 2))) -
0.5 * M_PI;
if (abs(new_phi - phi) < threshold) {
phi = new_phi;
break;
}
phi = new_phi;
}
return phi;
}