changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > core / rust/lib/obj/src/object/location.rs

changeset 698: 96958d3eb5b0
parent: 3d78bed56188
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 04 Oct 2024 22:04:59 -0400
permissions: -rw-r--r--
description: fixes
1 //! obj::location
2 //!
3 //! Location object types
4 use crate::Objective;
5 
6 use serde::{Deserialize, Serialize};
7 
8 /// A City object descriptor. Serves as an anchor for many properties
9 /// in location-based data.
10 #[derive(Serialize, Deserialize, Debug)]
11 pub struct City {
12  point: Point,
13  name: String,
14  area: Option<Vec<Point>>,
15  region: Option<String>,
16  state: Option<String>,
17  country: Option<String>,
18  timezone: Option<String>,
19 }
20 
21 impl City {
22  pub fn new(point: Point) -> Self {
23  City {
24  point,
25  name: "ellisville".to_string(),
26  area: None,
27  region: None,
28  country: None,
29  state: None,
30  timezone: Some("est".to_string()),
31  }
32  }
33 }
34 impl Objective for City {}
35 
36 /// Geo-coordinate Point object type
37 #[derive(Serialize, Deserialize, Debug, Default, PartialEq)]
38 pub struct Point {
39  pub lat: f32,
40  pub lng: f32,
41 }
42 
43 impl Point {
44  /// Create a new Point from (f32, f32)
45  pub fn new(lat: f32, lng: f32) -> Self {
46  Point { lat, lng }
47  }
48 
49  /// Given an additional Point, and assuming Points are on Earth,
50  /// returns the distance in kilometers between them using the
51  /// Haversine formula
52  pub fn earth_distance_from(&self, other: Point) -> f32 {
53  let earth_radius_kilometer = 6371.0_f32;
54  let lat_rads = self.lat.to_radians();
55  let other_lat_rads = other.lat.to_radians();
56 
57  let delta_latitude = (self.lat - other.lat).to_radians();
58  let delta_longitude = (self.lng - other.lng).to_radians();
59 
60  let central_angle_inner = (delta_latitude / 2.0).sin().powi(2)
61  + lat_rads.cos()
62  * other_lat_rads.cos()
63  * (delta_longitude / 2.0).sin().powi(2);
64  let central_angle = 2.0 * central_angle_inner.sqrt().asin();
65 
66  let distance = earth_radius_kilometer * central_angle;
67 
68  println!(
69  "Distance between points on the surface of Earth is {:.1} kilometers",
70  distance
71  );
72 
73  distance
74  }
75 }
76 
77 #[test]
78 fn london_to_paris() {
79  assert_eq!(
80  Point::new(48.85341_f32, -2.34880_f32)
81  .earth_distance_from(Point::new(51.50853_f32, -0.12574_f32)),
82  334.9559_f32,
83  );
84 }
85 
86 impl From<City> for Point {
87  fn from(city: City) -> Self {
88  city.point
89  }
90 }
91 
92 impl Objective for Point {}