Start work on separating out latlon

This commit is contained in:
Austen Adler 2023-03-24 18:42:14 -04:00
parent 72e46a9bfb
commit 2fc2772be9
7 changed files with 51 additions and 10 deletions

1
Cargo.lock generated
View File

@ -1353,6 +1353,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"nom", "nom",
"pluscodes", "pluscodes",
"thiserror",
"utm", "utm",
] ]

View File

@ -21,3 +21,4 @@ edition = "2021"
nom = "7.1.3" nom = "7.1.3"
pluscodes = "0.5.0" pluscodes = "0.5.0"
utm = "0.1.6" utm = "0.1.6"
thiserror = "1.0.38"

View File

@ -19,7 +19,7 @@ pub struct Coordinate {
impl Coordinate { impl Coordinate {
pub fn parse(i: &str) -> IResult<&str, Self> { pub fn parse(i: &str) -> IResult<&str, Self> {
let ret = map_opt( map_opt(
alt(( alt((
map_opt( map_opt(
alt(( alt((
@ -82,9 +82,7 @@ impl Coordinate {
// Ensure this is a north/south then east/west direction // Ensure this is a north/south then east/west direction
Self::from(lat, lon) Self::from(lat, lon)
}, },
)(i); )(i)
eprintln!("{:?}", ret);
ret
} }
pub fn from(lat: f64, lon: f64) -> Option<Self> { pub fn from(lat: f64, lon: f64) -> Option<Self> {

View File

@ -12,7 +12,7 @@ use nom::{
use std::{fmt, str::FromStr}; use std::{fmt, str::FromStr};
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub struct Coordinate(pub DMS, pub DMS); pub struct Coordinate(pub DMS, pub DMS, LatLon);
impl Coordinate { impl Coordinate {
pub fn parse(i: &str) -> IResult<&str, Self> { pub fn parse(i: &str) -> IResult<&str, Self> {
@ -21,7 +21,8 @@ impl Coordinate {
|(lat, _, _, lon)| { |(lat, _, _, lon)| {
// Ensure this is a north/south then east/west direction // Ensure this is a north/south then east/west direction
if lat.direction.is_lat() && lon.direction.is_lon() { if lat.direction.is_lat() && lon.direction.is_lon() {
Some(Coordinate(lat, lon)) let latlon = LatLon::from(lat.to_decimal_degrees(), lon.to_decimal_degrees())?;
Some(Coordinate(lat, lon, latlon))
} else { } else {
None None
} }
@ -172,6 +173,7 @@ impl TryFrom<LatLon> for Coordinate {
Ok(Self( Ok(Self(
DMS::try_from_decimal_degrees(value.lat, true)?, DMS::try_from_decimal_degrees(value.lat, true)?,
DMS::try_from_decimal_degrees(value.lon, false)?, DMS::try_from_decimal_degrees(value.lon, false)?,
value,
)) ))
} }
} }

View File

@ -0,0 +1,35 @@
use thiserror::Error;
#[derive(PartialEq, Debug, Clone)]
pub struct LatLon {
lat: f64,
lon: f64,
}
#[derive(Error, Debug)]
pub enum Error {
#[error("Invalid latitude: {0:?}")]
InvalidLatitude(f64),
#[error("Invalid longitude: {0:?}")]
InvalidLongitude(f64),
}
impl LatLon {
pub fn new(lat: f64, lon: f64) -> Result<Self, Error> {
if !(-90_f64..=90_f64).contains(&lat) {
Err(Error::InvalidLatitude(lat))
} else if !(-180_f64..=180_f64).contains(&lon) {
Err(Error::InvalidLongitude(lon))
} else {
Ok(Self { lat, lon })
}
}
pub fn get_lat(&self) -> f64 {
self.lat
}
pub fn get_lon(&self) -> f64 {
self.lat
}
}

View File

@ -3,6 +3,7 @@ mod common;
pub mod dd; pub mod dd;
pub mod dmm; pub mod dmm;
pub mod dms; pub mod dms;
pub mod latlon;
pub mod plus; pub mod plus;
pub mod utm; pub mod utm;
// pub mod xpin; // pub mod xpin;

View File

@ -10,16 +10,19 @@ const PLUSCODE_CHARS: [char; 23] = [
]; ];
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub struct Coordinate(pub String); pub struct Coordinate(pub String, LatLon);
impl Coordinate { impl Coordinate {
pub fn parse(i: &str) -> IResult<&str, Self> { pub fn parse(i: &str) -> IResult<&str, Self> {
map_opt(pluscode_chars, |c| { map_opt(pluscode_chars, |c| {
// Check if it can be decoded first // Check if it can be decoded first
pluscodes::decode(c).ok()?; let coordinate = pluscodes::decode(c).ok()?;
// It can! Store it // It can! Store it
Some(Coordinate(c.to_string())) Some(Coordinate(
c.to_string(),
LatLon::from(coordinate.latitude, coordinate.longitude)?,
))
})(i) })(i)
} }
} }
@ -69,6 +72,6 @@ impl TryFrom<LatLon> for Coordinate {
}, },
PLUSCODE_LENGTH, PLUSCODE_LENGTH,
) )
.map(Coordinate) .map(|pluscode| Coordinate(pluscode, value))
} }
} }