Normalize dms and dmm to always have positive degrees
This commit is contained in:
parent
80ca551fa9
commit
c5b8b360ed
@ -36,6 +36,15 @@ pub fn parse_direction(i: &str) -> IResult<&str, Direction> {
|
||||
))(i)
|
||||
}
|
||||
|
||||
/// Changes degrees to a positive number and flips the direction if required
|
||||
pub fn normalize_degrees_direction(degrees: i16, direction: Direction) -> (i16, Direction) {
|
||||
if degrees < 0 {
|
||||
(-degrees, direction.inverse())
|
||||
} else {
|
||||
(degrees, direction)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_f64(i: &str) -> IResult<&str, f64> {
|
||||
map_opt(
|
||||
tuple((
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
common::{optional_separator, parse_direction, parse_f64},
|
||||
common::{normalize_degrees_direction, optional_separator, parse_direction, parse_f64},
|
||||
Direction, Error, LatLon,
|
||||
};
|
||||
use nom::{
|
||||
@ -95,16 +95,12 @@ impl DMM {
|
||||
),
|
||||
)),
|
||||
|((degrees, minutes), _, direction)| {
|
||||
let negate = direction == Direction::West || direction == Direction::South;
|
||||
let (degrees, direction) = normalize_degrees_direction(degrees, direction);
|
||||
|
||||
Self {
|
||||
degrees: degrees * if negate { -1 } else { 1 },
|
||||
degrees,
|
||||
minutes,
|
||||
direction: if direction.is_lat() {
|
||||
Direction::North
|
||||
} else {
|
||||
Direction::East
|
||||
},
|
||||
direction,
|
||||
}
|
||||
},
|
||||
)(i)
|
||||
@ -114,14 +110,19 @@ impl DMM {
|
||||
let degrees = d as i16;
|
||||
let minutes = d.fract() * 60_f64;
|
||||
|
||||
Self {
|
||||
let (degrees, direction) = normalize_degrees_direction(
|
||||
degrees,
|
||||
minutes,
|
||||
direction: if is_latitude {
|
||||
if is_latitude {
|
||||
Direction::North
|
||||
} else {
|
||||
Direction::East
|
||||
},
|
||||
);
|
||||
|
||||
Self {
|
||||
degrees,
|
||||
minutes,
|
||||
direction,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
common::{optional_separator, parse_direction, parse_f64},
|
||||
common::{normalize_degrees_direction, optional_separator, parse_direction, parse_f64},
|
||||
Direction, Error, LatLon,
|
||||
};
|
||||
use nom::{
|
||||
@ -94,17 +94,13 @@ impl DMS {
|
||||
),
|
||||
)),
|
||||
|((degrees, minutes, seconds), _, direction)| {
|
||||
let negate = direction == Direction::West || direction == Direction::South;
|
||||
let (degrees, direction) = normalize_degrees_direction(degrees, direction);
|
||||
|
||||
Self {
|
||||
degrees: degrees * if negate { -1 } else { 1 },
|
||||
degrees,
|
||||
minutes,
|
||||
seconds,
|
||||
direction: if direction.is_lat() {
|
||||
Direction::North
|
||||
} else {
|
||||
Direction::East
|
||||
},
|
||||
direction,
|
||||
}
|
||||
},
|
||||
)(i)
|
||||
@ -116,15 +112,20 @@ impl DMS {
|
||||
let seconds = minutes.fract() * 60_f64;
|
||||
let minutes = minutes as i16;
|
||||
|
||||
Self {
|
||||
let (degrees, direction) = normalize_degrees_direction(
|
||||
degrees,
|
||||
minutes,
|
||||
seconds,
|
||||
direction: if is_latitude {
|
||||
if is_latitude {
|
||||
Direction::North
|
||||
} else {
|
||||
Direction::East
|
||||
},
|
||||
);
|
||||
|
||||
Self {
|
||||
degrees,
|
||||
minutes,
|
||||
seconds,
|
||||
direction,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,16 @@ impl Direction {
|
||||
pub fn is_positive(&self) -> bool {
|
||||
self == &Self::North || self == &Self::East
|
||||
}
|
||||
|
||||
/// Flips the direction
|
||||
pub fn inverse(&self) -> Self {
|
||||
match self {
|
||||
Direction::North => Direction::South,
|
||||
Direction::South => Direction::North,
|
||||
Direction::East => Direction::West,
|
||||
Direction::West => Direction::East,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, EnumDiscriminants)]
|
||||
|
@ -149,6 +149,16 @@ mod tests {
|
||||
"120000N1000000E"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Coordinate::from(LatLon::new(90.0_f64, 100.0_f64).unwrap()).0,
|
||||
"900000N1000000E"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Coordinate::from(LatLon::new(-90.0_f64, 100.0_f64).unwrap()).0,
|
||||
"900000S1000000E"
|
||||
);
|
||||
|
||||
// p!("0° 0' N", DMS);
|
||||
// p!("0° 0'N", DMS);
|
||||
// p!("N 0° 0'", DMS);
|
||||
|
Loading…
Reference in New Issue
Block a user