irox_carto/
altitude.rs

1// SPDX-License-Identifier: MIT
2// Copyright 2025 IROX Contributors
3//
4
5//!
6//! Altitude and Altitude Reference Frames
7
8use core::fmt::{Display, Formatter};
9
10use irox_units::units::length::Length;
11
12/// The reference or zero point for a particular Altitude value
13#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
14pub enum AltitudeReferenceFrame {
15    /// The frame is unknown or unspecified
16    #[default]
17    Unspecified,
18
19    /// The frame is "above the specified ellipsoidal model" - most commonly WGS84
20    Ellipsoid,
21
22    /// The frame is "above the specified geoidal model" - most commonly EGM/MSL - Mean Sea Level
23    Geoid,
24
25    /// The frame is "above the local terrain" - Above Ground Level (AGL)
26    Terrain,
27
28    /// The frame is "the center of mass" of the Earth
29    Geocentric,
30
31    /// The frame is "above the tallest local surface features"
32    /// Examples include trees, buildings, mountains, towers, etc.
33    /// Most commonly used by aircraft as a "hard deck", positive values imply an aircraft
34    /// will not collide with a structure
35    SurfaceFeatures,
36
37    /// Elevation above a standard datum air-pressure level
38    PressureAltitude,
39
40    /// The altitude as indicated by a altimeter pressure measuring instrument
41    IndicatedAltitude,
42
43    /// The altitude
44    DensityAltitude,
45}
46
47impl AltitudeReferenceFrame {
48    pub fn short_name(&self) -> &'static str {
49        match self {
50            AltitudeReferenceFrame::Unspecified => "UNK",
51            AltitudeReferenceFrame::Ellipsoid => "ELL",
52            AltitudeReferenceFrame::Geoid => "MSL",
53            AltitudeReferenceFrame::Terrain => "AGL",
54            AltitudeReferenceFrame::Geocentric => "GEO",
55            AltitudeReferenceFrame::SurfaceFeatures => "MSA",
56            AltitudeReferenceFrame::PressureAltitude => "PA",
57            AltitudeReferenceFrame::IndicatedAltitude => "IA",
58            AltitudeReferenceFrame::DensityAltitude => "DA",
59        }
60    }
61}
62
63/// A distance above a particular reference point
64#[derive(Debug, Default, Copy, Clone, PartialEq)]
65pub struct Altitude {
66    value: Length,
67    reference_frame: AltitudeReferenceFrame,
68}
69
70impl Altitude {
71    #[must_use]
72    pub const fn new(value: Length, reference_frame: AltitudeReferenceFrame) -> Altitude {
73        Altitude {
74            value,
75            reference_frame,
76        }
77    }
78
79    #[must_use]
80    pub const fn new_unknown(value: Length) -> Altitude {
81        Altitude::new(value, AltitudeReferenceFrame::Unspecified)
82    }
83
84    #[must_use]
85    pub fn value(&self) -> Length {
86        self.value
87    }
88
89    #[must_use]
90    pub fn reference_frame(&self) -> AltitudeReferenceFrame {
91        self.reference_frame
92    }
93}
94
95impl Display for Altitude {
96    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
97        f.write_fmt(format_args!(
98            "{} {}",
99            self.value,
100            self.reference_frame.short_name()
101        ))
102    }
103}