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
use std::f32::consts; #[derive(Clone, Debug, PartialEq, Default)] pub struct EarthLocation { pub latitude: f32, pub longitude: f32, } pub fn compute_distance(origin: &EarthLocation, destination: &EarthLocation) -> f32 { let radius: f32 = 6371.0; let d_lat = to_radians(origin.latitude - destination.latitude); let d_long = to_radians(origin.longitude - destination.longitude); let a = (d_lat / 2.0).sin() * (d_lat / 2.0).sin() + to_radians(origin.latitude).cos() * to_radians(destination.latitude).cos() * (d_long / 2.0).sin() * (d_long / 2.0).sin(); let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt()); radius * c } fn to_radians(degree: f32) -> f32 { let value: f32 = consts::PI; degree * (value / 180.0f32) } #[cfg(test)] mod tests { use super::*; #[test] fn test_distance() { let origin = EarthLocation { latitude: 32.9545, longitude: -117.2333, }; let destination = EarthLocation { latitude: 70.0733, longitude: 29.7497, }; let distance = compute_distance(&origin, &destination); let diff = (distance - 8255.1).abs(); println!("distance: {} diff: {}", distance, diff); assert!(diff < 0.2); } }