use crate::IO_RADIUS_M;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct IoCoord {
pub latitude_deg: f64,
pub longitude_deg: f64,
pub elevation_m: f64,
}
impl IoCoord {
pub fn new(latitude_deg: f64, longitude_deg: f64, elevation_m: f64) -> Self {
Self {
latitude_deg,
longitude_deg,
elevation_m,
}
}
}
pub fn great_circle_distance_km(a: IoCoord, b: IoCoord) -> f64 {
let lat1 = a.latitude_deg.to_radians();
let lat2 = b.latitude_deg.to_radians();
let dlat = (b.latitude_deg - a.latitude_deg).to_radians();
let dlon = (b.longitude_deg - a.longitude_deg).to_radians();
let hav = (dlat * 0.5).sin().powi(2) + lat1.cos() * lat2.cos() * (dlon * 0.5).sin().powi(2);
IO_RADIUS_M * 2.0 * hav.sqrt().asin() / 1_000.0
}
pub fn antipode(coord: IoCoord) -> IoCoord {
let lon = if coord.longitude_deg >= 0.0 {
coord.longitude_deg - 180.0
} else {
coord.longitude_deg + 180.0
};
IoCoord::new(-coord.latitude_deg, lon, -coord.elevation_m)
}