1use serde::{Serialize, Deserialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
7pub struct GeoCoordinate {
8 pub lat: f64,
9 pub lng: f64,
10 pub altitude: f64,
12}
13
14impl GeoCoordinate {
15 pub fn new(lat: f64, lng: f64) -> Result<Self, crate::ShaumError> {
19 if !(-90.0..=90.0).contains(&lat) {
20 return Err(crate::ShaumError::ValidationError(
21 format!("Latitude {} out of range [-90, 90]", lat)
22 ));
23 }
24 if !(-180.0..=180.0).contains(&lng) {
25 return Err(crate::ShaumError::ValidationError(
26 format!("Longitude {} out of range [-180, 180]", lng)
27 ));
28 }
29 Ok(Self { lat, lng, altitude: 0.0 })
30 }
31
32 #[inline]
34 pub const fn new_unchecked(lat: f64, lng: f64) -> Self {
35 Self { lat, lng, altitude: 0.0 }
36 }
37
38 pub fn with_altitude(mut self, altitude: f64) -> Self {
40 self.altitude = altitude;
41 self
42 }
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
50pub struct VisibilityCriteria {
51 pub min_altitude: f64,
53 pub min_elongation: f64,
55}
56
57impl Default for VisibilityCriteria {
58 fn default() -> Self {
59 Self { min_altitude: 3.0, min_elongation: 6.4 }
60 }
61}
62
63impl VisibilityCriteria {
64 pub fn new(min_altitude: f64, min_elongation: f64) -> Self {
66 Self { min_altitude, min_elongation }
67 }
68
69 pub fn mabims() -> Self { Self::default() }
71
72 pub fn istanbul_1978() -> Self {
74 Self { min_altitude: 5.0, min_elongation: 8.0 }
75 }
76}