use crate::{
prelude::{Error, Message},
utils::Utils,
};
use std::str::from_utf8;
#[derive(Debug, Clone, PartialEq)]
pub struct PositionGeo3d {
pub long_ddeg: f64,
pub lat_ddeg: f64,
pub alt_m: f64,
pub ellipsoid: String,
}
impl PositionGeo3d {
pub(crate) fn encoding_size(&self) -> usize {
let mut size = 24;
if !self.ellipsoid.eq("WGS84") {
let str_len = self.ellipsoid.len();
size += Message::bnxi_encoding_size(str_len as u32);
size += str_len;
} else {
size += 1;
}
size
}
pub(crate) fn encode(&self, big_endian: bool, buf: &mut [u8]) -> Result<usize, Error> {
let mut ptr = 0;
let size = self.encoding_size();
if buf.len() < size {
return Err(Error::NotEnoughBytes);
}
if self.ellipsoid.eq("WGS84") {
buf[ptr] = 0;
ptr += 1;
} else {
let str_len = self.ellipsoid.len();
let size = Message::encode_bnxi(str_len as u32, big_endian, &mut buf[ptr..])?;
ptr += size;
buf[ptr..ptr + str_len].copy_from_slice(self.ellipsoid.as_bytes());
ptr += str_len;
}
let bytes = if big_endian {
self.long_ddeg.to_be_bytes()
} else {
self.long_ddeg.to_le_bytes()
};
buf[ptr..ptr + 8].copy_from_slice(&bytes);
let bytes = if big_endian {
self.lat_ddeg.to_be_bytes()
} else {
self.lat_ddeg.to_le_bytes()
};
buf[ptr + 8..ptr + 16].copy_from_slice(&bytes);
let bytes = if big_endian {
self.alt_m.to_be_bytes()
} else {
self.alt_m.to_le_bytes()
};
buf[ptr + 16..ptr + 24].copy_from_slice(&bytes);
Ok(size)
}
pub(crate) fn decode(big_endian: bool, buf: &[u8]) -> Result<Self, Error> {
let buf_len = buf.len();
if buf_len < 2 {
return Err(Error::NotEnoughBytes);
}
let (str_len, mut ptr) = Message::decode_bnxi(buf, big_endian);
let str_len = str_len as usize;
let ellipsoid = if str_len == 0 {
"WGS84".to_string()
} else {
let ellipsoid_str =
from_utf8(&buf[ptr..ptr + str_len]).map_err(|_| Error::Utf8Error)?;
ellipsoid_str.to_string()
};
ptr += str_len;
if buf_len - str_len < 24 {
return Err(Error::NotEnoughBytes);
}
let long_ddeg = Utils::decode_f64(big_endian, &buf[ptr..ptr + 8])?;
let lat_ddeg = Utils::decode_f64(big_endian, &buf[ptr + 8..ptr + 16])?;
let alt_m = Utils::decode_f64(big_endian, &buf[ptr + 16..ptr + 24])?;
Ok(Self {
long_ddeg,
lat_ddeg,
alt_m,
ellipsoid,
})
}
pub fn new_wgs84(long_ddeg: f64, lat_ddeg: f64, alt_m: f64) -> Self {
Self {
long_ddeg,
lat_ddeg,
alt_m,
ellipsoid: "WGS84".to_string(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct VelocityNED3d {
pub north_m_s: f64,
pub east_m_s: f64,
pub up_m_s: f64,
}