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
pub mod mercator {
use crate::wgs84::EARTH_RADIUS_KM;
pub fn lon2x(lon: f64) -> f64 {
EARTH_RADIUS_KM * 1000. * lon.to_radians()
}
pub fn x2lon(x: f64) -> f64 {
(x / (EARTH_RADIUS_KM * 1000.)).to_degrees()
}
pub fn lat2y(lat: f64) -> f64 {
((lat.to_radians() / 2. + std::f64::consts::PI / 4.).tan()).log(std::f64::consts::E)
* EARTH_RADIUS_KM
* 1000.
}
pub fn y2lat(y: f64) -> f64 {
(2. * ((y / (EARTH_RADIUS_KM * 1000.)).exp()).atan() - std::f64::consts::PI / 2.)
.to_degrees()
}
}
#[cfg(test)]
mod tests {
use crate::projection::mercator::{lat2y, lon2x, x2lon, y2lat};
const ALLOWED_ERROR: f64 = 0.0000000000001;
#[test]
pub fn lon_conversion_roundtrip() {
for i in -180_00..180_01 {
let lon = f64::from(i) * 0.01;
let result = x2lon(lon2x(lon));
assert!((lon - result).abs() < ALLOWED_ERROR);
}
}
#[test]
pub fn lat_conversion_roundtrip() {
for i in -90_00..90_01 {
let lat = f64::from(i) * 0.01;
let result = y2lat(lat2y(lat));
assert!((lat - result).abs() < ALLOWED_ERROR);
}
}
}