From c9cc54480277718974aa96c93cf5921c6e4a10ee Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Sun, 19 Mar 2023 23:10:39 -0400 Subject: [PATCH] Continue normalizing coordinate systems --- Cargo.lock | 336 ++++++++++++++++++++++- spatial-coordinate-systems/Cargo.toml | 1 + spatial-coordinate-systems/src/common.rs | 17 +- spatial-coordinate-systems/src/dmm.rs | 122 ++++---- spatial-coordinate-systems/src/dms.rs | 183 ++++++------ spatial-coordinate-systems/src/lib.rs | 8 +- 6 files changed, 520 insertions(+), 147 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 188a06e..07a10a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aead" version = "0.5.1" @@ -70,6 +85,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "assert_approx_eq" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c07dab4369547dbe5114677b33fbbf724971019f3818172d59a97a61c774ffd" + [[package]] name = "async-stream" version = "0.3.4" @@ -129,6 +150,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.20.0" @@ -141,7 +177,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aaf33151a6429fe9211d1b276eafdf70cdff28b071e76c0b0e1503221ea3744" dependencies = [ - "num-bigint", + "num-bigint 0.4.3", "num-integer", "num-traits", ] @@ -158,6 +194,16 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -237,7 +283,7 @@ dependencies = [ "hkdf", "hmac", "percent-encoding", - "rand", + "rand 0.8.5", "sha2", "subtle", "time", @@ -260,7 +306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "typenum", ] @@ -338,6 +384,22 @@ dependencies = [ "subtle", ] +[[package]] +name = "dms-coordinates" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec6b438cc34e673063a715ff761392e195278759fa5d882d6bc6b78e2e30d90d" +dependencies = [ + "geo-types", + "gpx", + "initial_conditions", + "map_3d", + "rust-3d", + "serde", + "serde_derive", + "thiserror", +] + [[package]] name = "either" version = "1.8.1" @@ -374,6 +436,16 @@ dependencies = [ "libc", ] +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "backtrace", + "version_check", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -403,6 +475,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "futures" version = "0.3.27" @@ -491,6 +569,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "geo-types" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5f0b3068e1537a4b861ec3734f4aa9c317d537cf0845bf6fb6221973499d26c" +dependencies = [ + "approx", + "num-traits", + "serde", +] + [[package]] name = "geoutils" version = "0.5.1" @@ -518,12 +607,32 @@ dependencies = [ "polyval", ] +[[package]] +name = "gimli" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" + [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "gpx" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b03599b85866c88fd0125db7ca7a683be1550724918682c736c7893a399dc5e" +dependencies = [ + "assert_approx_eq", + "error-chain", + "geo-types", + "thiserror", + "time", + "xml-rs", +] + [[package]] name = "h2" version = "0.3.16" @@ -669,6 +778,15 @@ dependencies = [ "serde", ] +[[package]] +name = "initial_conditions" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ddf16659f435e5c98d948694a97c33b6660c35adad199ab10362092a45ce921" +dependencies = [ + "num 0.1.42", +] + [[package]] name = "inlinable_string" version = "0.1.15" @@ -768,6 +886,12 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "map_3d" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fc1b6107fbd06c96e5e481fcf3e6575b873eb84f5b68f1f5706cde0fed42c4" + [[package]] name = "matchers" version = "0.1.0" @@ -795,6 +919,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.6" @@ -847,6 +980,57 @@ dependencies = [ "winapi", ] +[[package]] +name = "num" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +dependencies = [ + "num-bigint 0.1.44", + "num-complex 0.1.43", + "num-integer", + "num-iter", + "num-rational 0.1.42", + "num-traits", +] + +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint 0.2.6", + "num-complex 0.2.4", + "num-integer", + "num-iter", + "num-rational 0.2.4", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" +dependencies = [ + "num-integer", + "num-traits", + "rand 0.4.6", + "rustc-serialize", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.3" @@ -858,6 +1042,26 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-complex" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656" +dependencies = [ + "num-traits", + "rustc-serialize", +] + +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -868,6 +1072,41 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" +dependencies = [ + "num-bigint 0.1.44", + "num-integer", + "num-traits", + "rustc-serialize", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint 0.2.6", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -875,6 +1114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -887,6 +1127,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.30.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.17.1" @@ -983,7 +1232,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" dependencies = [ "phf_shared", - "rand", + "rand 0.8.5", ] [[package]] @@ -1091,6 +1340,25 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + [[package]] name = "rand" version = "0.8.5" @@ -1099,7 +1367,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1109,9 +1377,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.6.4" @@ -1121,6 +1404,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1198,7 +1490,7 @@ dependencies = [ "num_cpus", "parking_lot", "pin-project-lite", - "rand", + "rand 0.8.5", "ref-cast", "rocket_codegen", "rocket_http", @@ -1258,6 +1550,17 @@ dependencies = [ "uncased", ] +[[package]] +name = "rust-3d" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce1e81ec1eec57188d13fdeb9fcdf961914eb0f57e3b40c723be3b9245de9bb" +dependencies = [ + "bitvec", + "fnv", + "num 0.2.1", +] + [[package]] name = "rust-embed" version = "6.6.0" @@ -1293,6 +1596,18 @@ dependencies = [ "walkdir", ] +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" + [[package]] name = "rustix" version = "0.36.10" @@ -1447,6 +1762,7 @@ dependencies = [ name = "spatial-coordinate-systems" version = "0.1.0" dependencies = [ + "dms-coordinates", "nom", "pluscodes", "thiserror", @@ -2095,6 +2411,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" + [[package]] name = "xpin" version = "0.1.0" diff --git a/spatial-coordinate-systems/Cargo.toml b/spatial-coordinate-systems/Cargo.toml index 248b085..339a07d 100644 --- a/spatial-coordinate-systems/Cargo.toml +++ b/spatial-coordinate-systems/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +dms-coordinates = "1.1.0" nom = "7.1.3" pluscodes = "0.5.0" thiserror = "1.0.40" diff --git a/spatial-coordinate-systems/src/common.rs b/spatial-coordinate-systems/src/common.rs index 7796a22..1774672 100644 --- a/spatial-coordinate-systems/src/common.rs +++ b/spatial-coordinate-systems/src/common.rs @@ -1,3 +1,4 @@ +use dms_coordinates::{Bearing, DMS}; use nom::{ branch::alt, bytes::complete::{tag_no_case, take_while1}, @@ -37,12 +38,20 @@ pub fn parse_direction(i: &str) -> IResult<&str, Direction> { pub fn parse_f64(i: &str) -> IResult<&str, f64> { map_opt( - take_while1(|c: char| c.is_ascii_digit() || c == '-' || c == '.'), - |n: &str| n.parse::().ok(), + tuple(( + opt(complete::char('-')), + take_while1(|c: char| c.is_ascii_digit() || c == '.'), + )), + |(neg, n_str): (Option, &str)| { + n_str + .parse::() + .map(|n| n * if neg.is_some() { -1.0_f64 } else { 1.0_f64 }) + .ok() + }, )(i) } -#[cfg(tests)] +#[cfg(test)] mod tests { use super::*; @@ -52,5 +61,7 @@ mod tests { assert_eq!(parse_f64("1.0"), Ok(("", 1.0_f64))); assert_eq!(parse_f64("1.0e2"), Ok(("e2", 1.0_f64))); assert_eq!(parse_f64("1.0x"), Ok(("x", 1.0_f64))); + assert_eq!(parse_f64("-1.0x"), Ok(("x", -1.0_f64))); + assert_eq!(parse_f64("-1.0-x"), Ok(("-x", -1.0_f64))); } } diff --git a/spatial-coordinate-systems/src/dmm.rs b/spatial-coordinate-systems/src/dmm.rs index 1dc1ef8..2c19b1f 100644 --- a/spatial-coordinate-systems/src/dmm.rs +++ b/spatial-coordinate-systems/src/dmm.rs @@ -1,7 +1,8 @@ use crate::{ - common::{optional_separator, parse_direction}, + common::{optional_separator, parse_direction, parse_f64}, Direction, LatLon, }; +use dms_coordinates::{Bearing, DMS}; use nom::{ branch::alt, character::complete::{self, space0, space1}, @@ -46,56 +47,85 @@ pub struct DMM { pub direction: Direction, } -impl DMM { - pub fn parse(i: &str) -> IResult<&str, DMM> { - map( - tuple(( - // Degrees - complete::i16, - optional_separator('°'), - // Minutes - double, - optional_separator('\''), - // Direction - parse_direction, - )), - |(degrees, (), minutes, (), direction)| DMM { +fn parse_dmm(i: &str) -> IResult<&str, DMM> { + map( + tuple(( + // Degrees + complete::i32, + optional_separator('°'), + // Minutes + parse_f64, + optional_separator('\''), + // Direction + parse_direction, + )), + |(degrees, (), minutes, (), direction)| { + let seconds = minutes.fract() * 60_f64; + let dms = DMS::new( degrees, minutes, - direction, - }, - )(i) - } + seconds, + match direction { + Direction::North => Bearing::North, + Direction::South => Bearing::South, + Direction::East => Bearing::East, + Direction::West => Bearing::West, + }, + ); + }, + )(i) } -impl FromStr for DMM { - type Err = (); +// impl DMM { +// pub fn parse(i: &str) -> IResult<&str, DMM> { +// map( +// tuple(( +// // Degrees +// complete::i16, +// optional_separator('°'), +// // Minutes +// double, +// optional_separator('\''), +// // Direction +// parse_direction, +// )), +// |(degrees, (), minutes, (), direction)| DMM { +// degrees, +// minutes, +// direction, +// }, +// )(i) +// } +// } - /// Recognizes DMS in the formats: - /// - /// * `40° 31' 21" N, 105° 5' 39" W` - /// * `40 31 21 N, 105 5 39 W` - /// - /// ```rust - /// use spatial_coordinate_systems::dmm::DMM; - /// use spatial_coordinate_systems::Direction; - /// use std::str::FromStr; - /// - /// assert_eq!(DMM::from_str("40 31.3 N").unwrap(), DMM { - /// degrees: 40, - /// minutes: 31.3_f64, - /// direction: Direction::North, - /// }); - /// assert_eq!(DMM::from_str("40°31' N").unwrap(), DMM { - /// degrees: 40, - /// minutes: 31_f64, - /// direction: Direction::North, - /// }); - /// ``` - fn from_str(i: &str) -> Result { - DMM::parse(i).map_err(|_| ()).map(|(_, ret)| ret) - } -} +// impl FromStr for DMM { +// type Err = (); + +// /// Recognizes DMS in the formats: +// /// +// /// * `40° 31' 21" N, 105° 5' 39" W` +// /// * `40 31 21 N, 105 5 39 W` +// /// +// /// ```rust +// /// use spatial_coordinate_systems::dmm::DMM; +// /// use spatial_coordinate_systems::Direction; +// /// use std::str::FromStr; +// /// +// /// assert_eq!(DMM::from_str("40 31.3 N").unwrap(), DMM { +// /// degrees: 40, +// /// minutes: 31.3_f64, +// /// direction: Direction::North, +// /// }); +// /// assert_eq!(DMM::from_str("40°31' N").unwrap(), DMM { +// /// degrees: 40, +// /// minutes: 31_f64, +// /// direction: Direction::North, +// /// }); +// /// ``` +// fn from_str(i: &str) -> Result { +// DMM::parse(i).map_err(|_| ()).map(|(_, ret)| ret) +// } +// } impl TryInto for Coordinate { type Error = (); diff --git a/spatial-coordinate-systems/src/dms.rs b/spatial-coordinate-systems/src/dms.rs index 735d8ea..0d35fdc 100644 --- a/spatial-coordinate-systems/src/dms.rs +++ b/spatial-coordinate-systems/src/dms.rs @@ -1,7 +1,9 @@ use crate::{ - common::{optional_separator, parse_direction}, + common::{optional_separator, parse_direction, parse_f64}, Direction, LatLon, }; +use dms_coordinates::Bearing; +pub use dms_coordinates::DMS; use nom::{ branch::alt, character::complete::{self, space0, space1}, @@ -18,10 +20,13 @@ pub struct Coordinate(pub DMS, pub DMS); impl Coordinate { pub fn parse(i: &str) -> IResult<&str, Self> { map_opt( - tuple((DMS::parse, optional_separator(','), DMS::parse)), + tuple((parse_dms, optional_separator(','), parse_dms)), |(ns, _, ew)| { // Ensure this is a north/south then east/west direction - if ns.direction.is_lat() && ew.direction.is_lon() { + if ns.bearing.is_northern() + || ns.bearing.is_southern() && ew.bearing.is_eastern() + || ew.bearing.is_western() + { Some(Coordinate(ns, ew)) } else { None @@ -31,6 +36,37 @@ impl Coordinate { } } +fn parse_dms(i: &str) -> IResult<&str, DMS> { + map( + tuple(( + // Degrees + complete::i32, + optional_separator('°'), + // Minutes + complete::i32, + optional_separator('\''), + // Seconds + parse_f64, + optional_separator('"'), + // Direction + parse_direction, + )), + |(degrees, (), minutes, (), seconds, (), direction)| { + DMS::new( + degrees, + minutes, + seconds, + match direction { + Direction::North => Bearing::North, + Direction::South => Bearing::South, + Direction::East => Bearing::East, + Direction::West => Bearing::West, + }, + ) + }, + )(i) +} + impl FromStr for Coordinate { type Err = (); @@ -39,82 +75,66 @@ impl FromStr for Coordinate { } } -#[derive(PartialEq, Debug)] -pub struct DMS { - pub degrees: i16, - pub minutes: i16, - pub seconds: f64, - pub direction: Direction, -} +// pub fn parse(i: &str) -> IResult<&str, DMS> { +// map( +// tuple(( +// // Degrees +// complete::i16, +// optional_separator('°'), +// // Minutes +// complete::i16, +// optional_separator('\''), +// // Seconds +// double, +// optional_separator('"'), +// // Direction +// parse_direction, +// )), +// |(degrees, (), minutes, (), seconds, (), direction)| DMS { +// degrees, +// minutes, +// seconds, +// direction, +// }, +// )(i) +// } -impl DMS { - pub fn parse(i: &str) -> IResult<&str, DMS> { - map( - tuple(( - // Degrees - complete::i16, - optional_separator('°'), - // Minutes - complete::i16, - optional_separator('\''), - // Seconds - double, - optional_separator('"'), - // Direction - parse_direction, - )), - |(degrees, (), minutes, (), seconds, (), direction)| DMS { - degrees, - minutes, - seconds, - direction, - }, - )(i) - } -} +// impl FromStr for DMS { +// type Err = (); -impl FromStr for DMS { - type Err = (); - - /// Recognizes DMS in the formats: - /// - /// * `40° 31' 21" N, 105° 5' 39" W` - /// * `40 31 21 N, 105 5 39 W` - /// - /// ```rust - /// use spatial_coordinate_systems::dms::DMS; - /// use spatial_coordinate_systems::Direction; - /// use std::str::FromStr; - /// - /// assert_eq!(DMS::from_str("40 31 21 N").unwrap(), DMS { - /// degrees: 40, - /// minutes: 31, - /// seconds: 21_f64, - /// direction: Direction::North, - /// }); - /// assert_eq!(DMS::from_str("40°31' 21 \" N").unwrap(), DMS { - /// degrees: 40, - /// minutes: 31, - /// seconds: 21_f64, - /// direction: Direction::North, - /// }); - /// ``` - fn from_str(i: &str) -> Result { - DMS::parse(i).map_err(|_| ()).map(|(_, ret)| ret) - } -} +// /// Recognizes DMS in the formats: +// /// +// /// * `40° 31' 21" N, 105° 5' 39" W` +// /// * `40 31 21 N, 105 5 39 W` +// /// +// /// ```rust +// /// use spatial_coordinate_systems::dms::DMS; +// /// use spatial_coordinate_systems::Direction; +// /// use std::str::FromStr; +// /// +// /// assert_eq!(DMS::from_str("40 31 21 N").unwrap(), DMS { +// /// degrees: 40, +// /// minutes: 31, +// /// seconds: 21_f64, +// /// direction: Direction::North, +// /// }); +// /// assert_eq!(DMS::from_str("40°31' 21 \" N").unwrap(), DMS { +// /// degrees: 40, +// /// minutes: 31, +// /// seconds: 21_f64, +// /// direction: Direction::North, +// /// }); +// /// ``` +// fn from_str(i: &str) -> Result { +// DMS::parse(i).map_err(|_| ()).map(|(_, ret)| ret) +// } +// } impl TryInto for Coordinate { type Error = (); fn try_into(self) -> Result { - Err(()) - - // LatLon::from( - // self.0.degrees as f64 + self.0.minutes * 60.0_f64, - // self.1.degrees as f64 + self.1.minutes * 60.0_f64, - // ) - // .ok_or(()) + LatLon::from(self.0.to_decimal_degrees(), self.1.to_decimal_degrees()).ok_or(()) } } @@ -122,20 +142,9 @@ impl TryFrom for Coordinate { type Error = (); fn try_from(value: LatLon) -> Result { - Err(()) - // Ok(Self( - // DMS { - // degrees: value.lat as i16, - // minutes: value.lat.fract() * 60_f64 as i16, - // seconds: value.lat.fract() * 3600_f64, - // direction: Direction::North, - // }, - // DMS { - // degrees: value.lon as i16, - // minutes: value.lon.fract() * 60_f64 as i16, - // seconds: value.lon.fract() * 3600_f64, - // direction: Direction::North, - // }, - // )) + Ok(Self( + DMS::from_decimal_degrees(value.lat, true), + DMS::from_decimal_degrees(value.lon, false), + )) } } diff --git a/spatial-coordinate-systems/src/lib.rs b/spatial-coordinate-systems/src/lib.rs index c2231e5..e079c94 100644 --- a/spatial-coordinate-systems/src/lib.rs +++ b/spatial-coordinate-systems/src/lib.rs @@ -3,12 +3,12 @@ use std::str::FromStr; mod common; pub mod dd; -pub mod dmm; +// pub mod dmm; pub mod dms; pub mod plus; pub mod utm; -use dmm::DMM; +// use dmm::DMM; use dms::DMS; use nom::{ branch::alt, @@ -42,7 +42,7 @@ impl Direction { pub enum Coordinate { DD(dd::Coordinate), DMS(dms::Coordinate), - DM(dmm::Coordinate), + // DM(dmm::Coordinate), UTM(utm::Coordinate), Plus(plus::Coordinate), } @@ -55,7 +55,7 @@ impl Coordinate { alt(( map(dd::Coordinate::parse, Coordinate::DD), map(dms::Coordinate::parse, Coordinate::DMS), - map(dmm::Coordinate::parse, Coordinate::DM), + // map(dmm::Coordinate::parse, Coordinate::DM), map(utm::Coordinate::parse, Coordinate::UTM), map(plus::Coordinate::parse, Coordinate::Plus), )),