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 = [
"nom",
"pluscodes",
"thiserror",
"utm",
]

View File

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

View File

@ -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<Self> {

View File

@ -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<LatLon> for Coordinate {
Ok(Self(
DMS::try_from_decimal_degrees(value.lat, true)?,
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 dmm;
pub mod dms;
pub mod latlon;
pub mod plus;
pub mod utm;
// pub mod xpin;

View File

@ -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<LatLon> for Coordinate {
},
PLUSCODE_LENGTH,
)
.map(Coordinate)
.map(|pluscode| Coordinate(pluscode, value))
}
}