1use std::f32::consts;
2
3#[derive(Clone, Debug, PartialEq, Default)]
4pub struct EarthLocation {
5 pub latitude: f32,
6 pub longitude: f32,
7}
8
9pub fn compute_distance(origin: &EarthLocation, destination: &EarthLocation) -> f32 {
10 let radius: f32 = 6371.0;
11 let d_lat = to_radians(origin.latitude - destination.latitude);
12 let d_long = to_radians(origin.longitude - destination.longitude);
13 let a = (d_lat / 2.0).sin() * (d_lat / 2.0).sin()
14 + to_radians(origin.latitude).cos()
15 * to_radians(destination.latitude).cos()
16 * (d_long / 2.0).sin()
17 * (d_long / 2.0).sin();
18 let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt());
19 radius * c
20}
21
22fn to_radians(degree: f32) -> f32 {
23 let value: f32 = consts::PI;
24 degree * (value / 180.0f32)
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30
31 #[test]
32 fn test_distance() {
33 let origin = EarthLocation {
34 latitude: 32.9545,
35 longitude: -117.2333,
36 };
37 let destination = EarthLocation {
38 latitude: 70.0733,
39 longitude: 29.7497,
40 };
41 let distance = compute_distance(&origin, &destination);
42 let diff = (distance - 8255.1).abs();
43 println!("distance: {distance} diff: {diff}");
44 assert!(diff < 0.2);
45 }
46}