Start work on separating out latlon
This commit is contained in:
parent
72e46a9bfb
commit
2fc2772be9
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1353,6 +1353,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"nom",
|
||||
"pluscodes",
|
||||
"thiserror",
|
||||
"utm",
|
||||
]
|
||||
|
||||
|
@ -21,3 +21,4 @@ edition = "2021"
|
||||
nom = "7.1.3"
|
||||
pluscodes = "0.5.0"
|
||||
utm = "0.1.6"
|
||||
thiserror = "1.0.38"
|
||||
|
@ -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> {
|
||||
|
@ -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,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
35
spatial-coordinate-systems/src/latlon.rs
Normal file
35
spatial-coordinate-systems/src/latlon.rs
Normal 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
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user