1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
use core::str::from_utf8_unchecked as utf8; #[derive(Copy, Clone, Default, PartialEq)] pub struct Latitude(pub i32); impl Latitude { pub fn degrees(self) -> u8 { (self.0.abs() / 100_00000) as u8 } pub fn minutes(self) -> u8 { ((self.0.abs() / 100000) % 100) as u8 } pub fn seconds(self) -> u8 { ((self.0.abs() / 1000) % 100) as u8 } pub fn sub_seconds(self) -> u16 { (self.0.abs() % 1000) as u16 } pub fn is_north(self) -> bool { self.0 >= 0 } pub fn is_south(self) -> bool { self.0 < 0 } } impl From<&[u8]> for Latitude { fn from(bytes: &[u8]) -> Self { if bytes.len() == 0 { return Self::default(); } let mut s = bytes.split(|&b| b == b'.'); let mut integer = 0i32; if let Some(field) = s.next() { integer = unsafe { utf8(field) }.parse().unwrap_or(0); } let mut decimal = 0i32; if let Some(field) = s.next() { decimal = unsafe { utf8(field) }.parse().unwrap_or(0); } Self(integer * 100000 + decimal) } } impl core::fmt::Display for Latitude { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { let direction = if self.0 >= 0 { "N" } else { "S" }; let degrees = self.degrees(); let minutes = self.minutes(); let seconds = self.seconds(); let sub_seconds = self.sub_seconds(); write!(f, "{}{:02}°{:02}'{:02}\"{:03}", direction, degrees, minutes, seconds, sub_seconds) } } impl core::fmt::Debug for Latitude { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{}", self) } }