use core::fmt;
use crate::exchange::etsi::reference_position::{
altitude_from_etsi, altitude_to_etsi, coordinate_from_etsi, coordinate_to_etsi,
};
use crate::mobility::position::Position;
use serde::{Deserialize, Serialize};
#[derive(Clone, Default, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ReferencePosition113 {
#[serde(default = "default_latitude")]
pub latitude: i32,
#[serde(default = "default_longitude")]
pub longitude: i32,
#[serde(default = "default_altitude")]
pub altitude: i32,
}
fn default_latitude() -> i32 {
900000001
}
fn default_longitude() -> i32 {
1800000001
}
fn default_altitude() -> i32 {
800001
}
impl ReferencePosition113 {
pub fn as_position(&self) -> Position {
Position {
latitude: coordinate_from_etsi(self.latitude),
longitude: coordinate_from_etsi(self.longitude),
altitude: altitude_from_etsi(self.altitude),
}
}
}
impl From<Position> for ReferencePosition113 {
fn from(position: Position) -> Self {
ReferencePosition113 {
latitude: coordinate_to_etsi(position.latitude),
longitude: coordinate_to_etsi(position.longitude),
altitude: altitude_to_etsi(position.altitude),
}
}
}
impl fmt::Display for ReferencePosition113 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"(lat: {} / lon: {} / alt: {})",
self.latitude, self.longitude, self.altitude,
)
}
}
#[serde_with::skip_serializing_none]
#[derive(Default, Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct PositionConfidence {
pub position_confidence_ellipse: Option<PositionConfidenceEllipse>,
pub altitude: Option<u8>,
}
#[serde_with::skip_serializing_none]
#[derive(Default, Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct PositionConfidenceEllipse {
pub semi_major_confidence: Option<u16>,
pub semi_minor_confidence: Option<u16>,
pub semi_major_orientation: Option<u16>,
}
#[cfg(test)]
mod tests {
use crate::exchange::etsi::reference_position113::ReferencePosition113;
use crate::mobility::position::Position;
#[test]
fn reference_position_113_as_position() {
let reference_position = ReferencePosition113 {
latitude: 488417860,
longitude: 23678940,
altitude: 16880,
};
let expected_position = Position {
latitude: 48.8417860_f64.to_radians(),
longitude: 2.3678940_f64.to_radians(),
altitude: 168.80,
};
let position = reference_position.as_position();
assert!(
(position.latitude - expected_position.latitude).abs() <= 1e-11,
"Actual latitude: {} (Expected: {}",
position.latitude,
expected_position.latitude,
);
assert!(
(position.longitude - expected_position.longitude).abs() <= 1e-11,
"Actual longitude: {} (Expected: {}",
position.longitude,
expected_position.longitude,
);
assert!(
(position.altitude - expected_position.altitude).abs() <= 1e-11,
"Actual altitude: {} (Expected: {}",
position.altitude,
expected_position.altitude,
);
}
#[test]
fn reference_position_113_from_position() {
let position = Position {
latitude: 48.8417860_f64.to_radians(),
longitude: 2.3678940_f64.to_radians(),
altitude: 168.80,
};
let expected_reference_position = ReferencePosition113 {
latitude: 488417860,
longitude: 23678940,
altitude: 16880,
};
let reference_position = ReferencePosition113::from(position);
assert_eq!(
reference_position.latitude,
expected_reference_position.latitude
);
assert_eq!(
reference_position.longitude,
expected_reference_position.longitude
);
assert_eq!(
reference_position.altitude,
expected_reference_position.altitude
);
}
}