From 2fc2772be9c34008d8595b8a1e86e679cb8fea35 Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Fri, 24 Mar 2023 18:42:14 -0400 Subject: [PATCH] Start work on separating out latlon --- Cargo.lock | 1 + spatial-coordinate-systems/Cargo.toml | 1 + spatial-coordinate-systems/src/dd.rs | 6 ++-- spatial-coordinate-systems/src/dms.rs | 6 ++-- spatial-coordinate-systems/src/latlon.rs | 35 ++++++++++++++++++++++++ spatial-coordinate-systems/src/lib.rs | 1 + spatial-coordinate-systems/src/plus.rs | 11 +++++--- 7 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 spatial-coordinate-systems/src/latlon.rs diff --git a/Cargo.lock b/Cargo.lock index c0e8fc0..d3c5116 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1353,6 +1353,7 @@ version = "0.1.0" dependencies = [ "nom", "pluscodes", + "thiserror", "utm", ] diff --git a/spatial-coordinate-systems/Cargo.toml b/spatial-coordinate-systems/Cargo.toml index 942b95d..444ffbf 100644 --- a/spatial-coordinate-systems/Cargo.toml +++ b/spatial-coordinate-systems/Cargo.toml @@ -21,3 +21,4 @@ edition = "2021" nom = "7.1.3" pluscodes = "0.5.0" utm = "0.1.6" +thiserror = "1.0.38" diff --git a/spatial-coordinate-systems/src/dd.rs b/spatial-coordinate-systems/src/dd.rs index c5a622e..7ca721a 100644 --- a/spatial-coordinate-systems/src/dd.rs +++ b/spatial-coordinate-systems/src/dd.rs @@ -19,7 +19,7 @@ pub struct Coordinate { impl Coordinate { pub fn parse(i: &str) -> IResult<&str, Self> { - let ret = map_opt( + map_opt( alt(( map_opt( alt(( @@ -82,9 +82,7 @@ impl Coordinate { // Ensure this is a north/south then east/west direction Self::from(lat, lon) }, - )(i); - eprintln!("{:?}", ret); - ret + )(i) } pub fn from(lat: f64, lon: f64) -> Option { diff --git a/spatial-coordinate-systems/src/dms.rs b/spatial-coordinate-systems/src/dms.rs index ee82811..8387e7f 100644 --- a/spatial-coordinate-systems/src/dms.rs +++ b/spatial-coordinate-systems/src/dms.rs @@ -12,7 +12,7 @@ use nom::{ use std::{fmt, str::FromStr}; #[derive(PartialEq, Debug, Clone)] -pub struct Coordinate(pub DMS, pub DMS); +pub struct Coordinate(pub DMS, pub DMS, LatLon); impl Coordinate { pub fn parse(i: &str) -> IResult<&str, Self> { @@ -21,7 +21,8 @@ impl Coordinate { |(lat, _, _, lon)| { // Ensure this is a north/south then east/west direction 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 { None } @@ -172,6 +173,7 @@ impl TryFrom for Coordinate { Ok(Self( DMS::try_from_decimal_degrees(value.lat, true)?, DMS::try_from_decimal_degrees(value.lon, false)?, + value, )) } } diff --git a/spatial-coordinate-systems/src/latlon.rs b/spatial-coordinate-systems/src/latlon.rs new file mode 100644 index 0000000..801819b --- /dev/null +++ b/spatial-coordinate-systems/src/latlon.rs @@ -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 { + 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 + } +} diff --git a/spatial-coordinate-systems/src/lib.rs b/spatial-coordinate-systems/src/lib.rs index 3343c70..05821e9 100644 --- a/spatial-coordinate-systems/src/lib.rs +++ b/spatial-coordinate-systems/src/lib.rs @@ -3,6 +3,7 @@ mod common; pub mod dd; pub mod dmm; pub mod dms; +pub mod latlon; pub mod plus; pub mod utm; // pub mod xpin; diff --git a/spatial-coordinate-systems/src/plus.rs b/spatial-coordinate-systems/src/plus.rs index b0e0002..d831be6 100644 --- a/spatial-coordinate-systems/src/plus.rs +++ b/spatial-coordinate-systems/src/plus.rs @@ -10,16 +10,19 @@ const PLUSCODE_CHARS: [char; 23] = [ ]; #[derive(PartialEq, Debug, Clone)] -pub struct Coordinate(pub String); +pub struct Coordinate(pub String, LatLon); impl Coordinate { pub fn parse(i: &str) -> IResult<&str, Self> { map_opt(pluscode_chars, |c| { // Check if it can be decoded first - pluscodes::decode(c).ok()?; + let coordinate = pluscodes::decode(c).ok()?; // It can! Store it - Some(Coordinate(c.to_string())) + Some(Coordinate( + c.to_string(), + LatLon::from(coordinate.latitude, coordinate.longitude)?, + )) })(i) } } @@ -69,6 +72,6 @@ impl TryFrom for Coordinate { }, PLUSCODE_LENGTH, ) - .map(Coordinate) + .map(|pluscode| Coordinate(pluscode, value)) } }