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)
|
))(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> {
|
pub fn parse_f64(i: &str) -> IResult<&str, f64> {
|
||||||
map_opt(
|
map_opt(
|
||||||
tuple((
|
tuple((
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
common::{optional_separator, parse_direction, parse_f64},
|
common::{normalize_degrees_direction, optional_separator, parse_direction, parse_f64},
|
||||||
Direction, Error, LatLon,
|
Direction, Error, LatLon,
|
||||||
};
|
};
|
||||||
use nom::{
|
use nom::{
|
||||||
@ -95,16 +95,12 @@ impl DMM {
|
|||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
|((degrees, minutes), _, direction)| {
|
|((degrees, minutes), _, direction)| {
|
||||||
let negate = direction == Direction::West || direction == Direction::South;
|
let (degrees, direction) = normalize_degrees_direction(degrees, direction);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
degrees: degrees * if negate { -1 } else { 1 },
|
degrees,
|
||||||
minutes,
|
minutes,
|
||||||
direction: if direction.is_lat() {
|
direction,
|
||||||
Direction::North
|
|
||||||
} else {
|
|
||||||
Direction::East
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)(i)
|
)(i)
|
||||||
@ -114,14 +110,19 @@ impl DMM {
|
|||||||
let degrees = d as i16;
|
let degrees = d as i16;
|
||||||
let minutes = d.fract() * 60_f64;
|
let minutes = d.fract() * 60_f64;
|
||||||
|
|
||||||
Self {
|
let (degrees, direction) = normalize_degrees_direction(
|
||||||
degrees,
|
degrees,
|
||||||
minutes,
|
if is_latitude {
|
||||||
direction: if is_latitude {
|
|
||||||
Direction::North
|
Direction::North
|
||||||
} else {
|
} else {
|
||||||
Direction::East
|
Direction::East
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
degrees,
|
||||||
|
minutes,
|
||||||
|
direction,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
common::{optional_separator, parse_direction, parse_f64},
|
common::{normalize_degrees_direction, optional_separator, parse_direction, parse_f64},
|
||||||
Direction, Error, LatLon,
|
Direction, Error, LatLon,
|
||||||
};
|
};
|
||||||
use nom::{
|
use nom::{
|
||||||
@ -94,17 +94,13 @@ impl DMS {
|
|||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
|((degrees, minutes, seconds), _, direction)| {
|
|((degrees, minutes, seconds), _, direction)| {
|
||||||
let negate = direction == Direction::West || direction == Direction::South;
|
let (degrees, direction) = normalize_degrees_direction(degrees, direction);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
degrees: degrees * if negate { -1 } else { 1 },
|
degrees,
|
||||||
minutes,
|
minutes,
|
||||||
seconds,
|
seconds,
|
||||||
direction: if direction.is_lat() {
|
direction,
|
||||||
Direction::North
|
|
||||||
} else {
|
|
||||||
Direction::East
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)(i)
|
)(i)
|
||||||
@ -116,15 +112,20 @@ impl DMS {
|
|||||||
let seconds = minutes.fract() * 60_f64;
|
let seconds = minutes.fract() * 60_f64;
|
||||||
let minutes = minutes as i16;
|
let minutes = minutes as i16;
|
||||||
|
|
||||||
Self {
|
let (degrees, direction) = normalize_degrees_direction(
|
||||||
degrees,
|
degrees,
|
||||||
minutes,
|
if is_latitude {
|
||||||
seconds,
|
|
||||||
direction: if is_latitude {
|
|
||||||
Direction::North
|
Direction::North
|
||||||
} else {
|
} else {
|
||||||
Direction::East
|
Direction::East
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
degrees,
|
||||||
|
minutes,
|
||||||
|
seconds,
|
||||||
|
direction,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,16 @@ impl Direction {
|
|||||||
pub fn is_positive(&self) -> bool {
|
pub fn is_positive(&self) -> bool {
|
||||||
self == &Self::North || self == &Self::East
|
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)]
|
#[derive(Debug, PartialEq, Clone, EnumDiscriminants)]
|
||||||
|
@ -149,6 +149,16 @@ mod tests {
|
|||||||
"120000N1000000E"
|
"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!("0° 0'N", DMS);
|
// p!("0° 0'N", DMS);
|
||||||
// p!("N 0° 0'", DMS);
|
// p!("N 0° 0'", DMS);
|
||||||
|
Loading…
Reference in New Issue
Block a user