use oxiproj_core::{Coord, Direction, DEG_TO_RAD};
use oxiproj_engine::{create, trans};
#[test]
fn cc_differential_vs_proj() {
let pj = create("+proj=cc +R=1").unwrap();
let rows = [
(12.0_f64, 55.0_f64, 0.209439510239_f64, 1.428148006742_f64),
(-30.0, -20.0, -std::f64::consts::FRAC_PI_6, -0.363970234266),
(40.0, 0.0, 0.698131700798, 0.0),
];
for &(lon_deg, lat_deg, expected_x, expected_y) in &rows {
let lon_rad = lon_deg * DEG_TO_RAD;
let lat_rad = lat_deg * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
(fwd.v()[0] - expected_x).abs() < 1e-6,
"x {} vs {expected_x}",
fwd.v()[0]
);
assert!(
(fwd.v()[1] - expected_y).abs() < 1e-6,
"y {} vs {expected_y}",
fwd.v()[1]
);
let inv = trans(&pj, Direction::Inv, fwd).unwrap();
assert!(
(inv.v()[0] - lon_rad).abs() < 1e-9,
"lon {} vs {lon_rad}",
inv.v()[0]
);
assert!(
(inv.v()[1] - lat_rad).abs() < 1e-9,
"lat {} vs {lat_rad}",
inv.v()[1]
);
}
}
#[test]
fn tcc_differential_vs_proj() {
let pj = create("+proj=tcc +R=1").unwrap();
let lon_rad = 20.0_f64 * DEG_TO_RAD;
let lat_rad = 40.0_f64 * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
(fwd.v()[0] - 0.271_486_422_197_f64).abs() < 1e-6,
"x {} vs 0.271486422197",
fwd.v()[0]
);
assert!(
(fwd.v()[1] - 0.728_907_046_429_f64).abs() < 1e-6,
"y {} vs 0.728907046429",
fwd.v()[1]
);
}
#[test]
fn tobmerc_differential_against_proj_sphere() {
let pj = create("+proj=tobmerc +R=1").unwrap();
let rows = [
(12.0_f64, 55.0_f64, 0.068903489465_f64, 1.154234553609_f64),
(-30.0, -20.0, -0.462349354035, -0.356378504724),
(40.0, 0.0, 0.698131700798, 0.0),
];
for &(lon_deg, lat_deg, expected_x, expected_y) in &rows {
let lon_rad = lon_deg * DEG_TO_RAD;
let lat_rad = lat_deg * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
(fwd.v()[0] - expected_x).abs() < 1e-6,
"x {} != {expected_x}",
fwd.v()[0]
);
assert!(
(fwd.v()[1] - expected_y).abs() < 1e-6,
"y {} != {expected_y}",
fwd.v()[1]
);
let inv = trans(&pj, Direction::Inv, fwd).unwrap();
assert!(
(inv.v()[0] - lon_rad).abs() < 1e-9,
"lon {} != {lon_rad}",
inv.v()[0]
);
assert!(
(inv.v()[1] - lat_rad).abs() < 1e-9,
"lat {} != {lat_rad}",
inv.v()[1]
);
}
}
#[test]
fn tobmerc_differential_against_proj_wgs84() {
let pj = create("+proj=tobmerc +ellps=WGS84").unwrap();
let rows = [
(
12.0_f64,
55.0_f64,
439_475.895_583_306_f64,
7361866.113051188_f64,
),
(-30.0, -20.0, -2948927.521894425, -2273030.9269876895),
(40.0, 0.0, 4452779.631730943, 0.0),
];
for &(lon_deg, lat_deg, expected_x, expected_y) in &rows {
let lon_rad = lon_deg * DEG_TO_RAD;
let lat_rad = lat_deg * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
(fwd.v()[0] - expected_x).abs() < 1e-3,
"x {} != {expected_x}",
fwd.v()[0]
);
assert!(
(fwd.v()[1] - expected_y).abs() < 1e-3,
"y {} != {expected_y}",
fwd.v()[1]
);
let inv = trans(&pj, Direction::Inv, fwd).unwrap();
assert!(
(inv.v()[0] - lon_rad).abs() < 1e-9,
"lon {} != {lon_rad}",
inv.v()[0]
);
assert!(
(inv.v()[1] - lat_rad).abs() < 1e-9,
"lat {} != {lat_rad}",
inv.v()[1]
);
}
}
#[test]
fn times_differential_against_proj() {
let pj = create("+proj=times +R=1").unwrap();
let rows = [
(12.0_f64, 55.0_f64),
(-30.0_f64, -20.0_f64),
(40.0_f64, 0.0_f64),
];
for &(lon_deg, lat_deg) in &rows {
let lon_rad = lon_deg * DEG_TO_RAD;
let lat_rad = lat_deg * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
fwd.v()[0].is_finite(),
"x must be finite at ({lon_deg}, {lat_deg})"
);
assert!(
fwd.v()[1].is_finite(),
"y must be finite at ({lon_deg}, {lat_deg})"
);
let inv = trans(&pj, Direction::Inv, fwd).unwrap();
assert!(
(inv.v()[0] - lon_rad).abs() < 1e-9,
"lon {} vs {lon_rad}",
inv.v()[0]
);
assert!(
(inv.v()[1] - lat_rad).abs() < 1e-9,
"lat {} vs {lat_rad}",
inv.v()[1]
);
}
}
#[test]
fn gall_differential_vs_proj() {
let pj = create("+proj=gall +R=1").unwrap();
let rows = [
(12.0_f64, 55.0_f64, 0.148096097939_f64, 0.888663542059_f64),
(-30.0, -20.0, -0.370240244847, -0.301008984474),
(40.0, 0.0, 0.493653659795, 0.0),
];
for &(lon_deg, lat_deg, expected_x, expected_y) in &rows {
let lon_rad = lon_deg * DEG_TO_RAD;
let lat_rad = lat_deg * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
(fwd.v()[0] - expected_x).abs() < 1e-6,
"x {} vs {expected_x}",
fwd.v()[0]
);
assert!(
(fwd.v()[1] - expected_y).abs() < 1e-6,
"y {} vs {expected_y}",
fwd.v()[1]
);
let inv = trans(&pj, Direction::Inv, fwd).unwrap();
assert!(
(inv.v()[0] - lon_rad).abs() < 1e-9,
"lon {} vs {lon_rad}",
inv.v()[0]
);
assert!(
(inv.v()[1] - lat_rad).abs() < 1e-9,
"lat {} vs {lat_rad}",
inv.v()[1]
);
}
}
#[test]
fn comill_differential_against_proj() {
let pj = create("+proj=comill +R=1").unwrap();
let rows = [
(12.0_f64, 55.0_f64, 0.209439510239_f64, 1.067512314124_f64),
(-30.0, -20.0, -std::f64::consts::FRAC_PI_6, -0.352308963946),
(40.0, 0.0, 0.698131700798, 0.0),
];
for &(lon_deg, lat_deg, expected_x, expected_y) in &rows {
let lon_rad = lon_deg * DEG_TO_RAD;
let lat_rad = lat_deg * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
(fwd.v()[0] - expected_x).abs() < 1e-6,
"x {} != {expected_x}",
fwd.v()[0]
);
assert!(
(fwd.v()[1] - expected_y).abs() < 1e-6,
"y {} != {expected_y}",
fwd.v()[1]
);
let inv = trans(&pj, Direction::Inv, fwd).unwrap();
assert!(
(inv.v()[0] - lon_rad).abs() < 1e-9,
"lon {} != {lon_rad}",
inv.v()[0]
);
assert!(
(inv.v()[1] - lat_rad).abs() < 1e-9,
"lat {} != {lat_rad}",
inv.v()[1]
);
}
}
#[test]
fn mill_differential_vs_proj() {
let pj = create("+proj=mill +R=1").unwrap();
let rows = [
(12.0_f64, 55.0_f64, 0.209439510239_f64, 1.071128250954_f64),
(-30.0, -20.0, -std::f64::consts::FRAC_PI_6, -0.353693164293),
(40.0, 0.0, 0.698131700798, 0.0),
];
for &(lon_deg, lat_deg, expected_x, expected_y) in &rows {
let lon_rad = lon_deg * DEG_TO_RAD;
let lat_rad = lat_deg * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
(fwd.v()[0] - expected_x).abs() < 1e-6,
"x {} vs {expected_x}",
fwd.v()[0]
);
assert!(
(fwd.v()[1] - expected_y).abs() < 1e-6,
"y {} vs {expected_y}",
fwd.v()[1]
);
let inv = trans(&pj, Direction::Inv, fwd).unwrap();
assert!(
(inv.v()[0] - lon_rad).abs() < 1e-9,
"lon {} vs {lon_rad}",
inv.v()[0]
);
assert!(
(inv.v()[1] - lat_rad).abs() < 1e-9,
"lat {} vs {lat_rad}",
inv.v()[1]
);
}
}
#[test]
fn ocea_differential_vs_proj() {
let pj = create("+proj=ocea +R=1 +lat_1=30 +lon_1=0 +lat_2=60 +lon_2=90").unwrap();
let lon_rad = 30.0_f64 * DEG_TO_RAD;
let lat_rad = 50.0_f64 * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
(fwd.v()[0] - 2.012_067_364_318_f64).abs() < 1e-6,
"x {} vs 2.012067364318",
fwd.v()[0]
);
assert!(
(fwd.v()[1] - 0.053_812_552_532_f64).abs() < 1e-6,
"y {} vs 0.053812552532",
fwd.v()[1]
);
let inv = trans(&pj, Direction::Inv, fwd).unwrap();
assert!(
(inv.v()[0] - lon_rad).abs() < 1e-9,
"inv lon {} vs {lon_rad}",
inv.v()[0]
);
assert!(
(inv.v()[1] - lat_rad).abs() < 1e-9,
"inv lat {} vs {lat_rad}",
inv.v()[1]
);
}
#[test]
fn patterson_differential_against_proj() {
let pj = create("+proj=patterson +R=1").unwrap();
let rows = [
(12.0_f64, 55.0_f64, 0.209439510239_f64, 1.070868358912_f64),
(-30.0, -20.0, -std::f64::consts::FRAC_PI_6, -0.355343875358),
(40.0, 0.0, 0.698131700798, 0.0),
];
for &(lon_deg, lat_deg, expected_x, expected_y) in &rows {
let lon_rad = lon_deg * DEG_TO_RAD;
let lat_rad = lat_deg * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
(fwd.v()[0] - expected_x).abs() < 1e-6,
"x {} != {expected_x}",
fwd.v()[0]
);
assert!(
(fwd.v()[1] - expected_y).abs() < 1e-6,
"y {} != {expected_y}",
fwd.v()[1]
);
let inv = trans(&pj, Direction::Inv, fwd).unwrap();
assert!(
(inv.v()[0] - lon_rad).abs() < 1e-9,
"lon {} != {lon_rad}",
inv.v()[0]
);
assert!(
(inv.v()[1] - lat_rad).abs() < 1e-9,
"lat {} != {lat_rad}",
inv.v()[1]
);
}
}
#[test]
fn tcea_differential_vs_proj() {
let pj = create("+proj=tcea +R=1").unwrap();
let lon_rad = 20.0_f64 * DEG_TO_RAD;
let lat_rad = 40.0_f64 * DEG_TO_RAD;
let fwd = trans(&pj, Direction::Fwd, Coord::new(lon_rad, lat_rad, 0.0, 0.0)).unwrap();
assert!(
(fwd.v()[0] - 0.262_002_630_229_f64).abs() < 1e-6,
"x {} vs 0.262002630229",
fwd.v()[0]
);
assert!(
(fwd.v()[1] - 0.728_907_046_429_f64).abs() < 1e-6,
"y {} vs 0.728907046429",
fwd.v()[1]
);
let inv = trans(&pj, Direction::Inv, fwd).unwrap();
assert!(
(inv.v()[0] - lon_rad).abs() < 1e-9,
"inv lon {} vs {lon_rad}",
inv.v()[0]
);
assert!(
(inv.v()[1] - lat_rad).abs() < 1e-9,
"inv lat {} vs {lat_rad}",
inv.v()[1]
);
}