use core::fmt::Debug;
use core::fmt::Display;
use geo::CoordFloat;
use geo_types::Coord;
use crate::in_delta::in_delta;
use crate::math::EPSILON;
use crate::Transform;
pub fn projection_equal<'a, P, T>(
projector: &P,
expected_location: &'a Coord<T>,
expected_point: &'a Coord<T>,
delta_p: Option<T>,
) -> bool
where
P: Transform<T = T>,
T: CoordFloat + Display,
{
let delta = delta_p.map_or_else(|| T::from(EPSILON).unwrap(), |d| d);
println!("project_equal");
println!(
"1) expected location [{:?}, {:?}], expected point [{:?}, {:?}]",
expected_location.x, expected_location.y, expected_point.x, expected_point.y,
);
let actual_location = projector.invert(expected_point);
let actual_point = projector.transform(expected_location);
println!("2) actual location {actual_location:?}, actual point {actual_point:?}");
planar_equal(&actual_point, expected_point, delta)
&& spherical_equal(&actual_location, expected_location, delta)
}
fn planar_equal<T: CoordFloat + Debug + Display>(
actual: &Coord<T>,
expected: &Coord<T>,
delta: T,
) -> bool {
let e0 = in_delta(actual.x, expected.x, delta);
let e1 = in_delta(actual.y, expected.y, delta);
e0 && e1
}
fn spherical_equal<T>(actual: &Coord<T>, expected: &Coord<T>, delta: T) -> bool
where
T: CoordFloat + Display,
{
let e0 = logitude_equal(actual.x, expected.x, delta);
let e1 = in_delta(actual.y, expected.y, delta);
e0 && e1
}
fn logitude_equal<T>(actual: T, expected: T, delta: T) -> bool
where
T: CoordFloat,
{
let actual = (actual - expected).abs() % T::from(360_f64).unwrap();
actual <= delta || actual >= T::from(360_f64).unwrap() - delta
}