Create spatial-coordinate-systems crate
This commit is contained in:
parent
e7744656b1
commit
f587b15372
235
Cargo.lock
generated
235
Cargo.lock
generated
@ -37,6 +37,30 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.4.0"
|
||||
@ -65,7 +89,7 @@ checksum = "e4655ae1a7b0cdf149156f780c5bf3f1352bc53cbd9e0a361a7ef7b22947e965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -76,7 +100,7 @@ checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -199,6 +223,21 @@ dependencies = [
|
||||
"inout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.16.2"
|
||||
@ -298,7 +337,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"proc-macro2-diagnostics",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -502,6 +541,15 @@ version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
@ -716,6 +764,12 @@ version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.6"
|
||||
@ -748,6 +802,16 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
@ -859,7 +923,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"proc-macro2-diagnostics",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -918,6 +982,17 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pluscodes"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5d3288e02604f234a7071cba77560e6a6e47395268bf80611f7e2347b082efa"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"regex",
|
||||
"structopt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polyval"
|
||||
version = "0.6.0"
|
||||
@ -937,10 +1012,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.50"
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.107",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -953,16 +1052,16 @@ checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
"version_check",
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -1023,7 +1122,7 @@ checksum = "9f9c0c92af03644e4806106281fe2e068ac5bc0ae74a707266d06ea27bccee5f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1032,6 +1131,8 @@ version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
@ -1110,7 +1211,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rocket_http",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
@ -1162,7 +1263,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rust-embed-utils",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
@ -1238,7 +1339,7 @@ checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1312,6 +1413,16 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spatial-coordinate-systems"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"nom",
|
||||
"pluscodes",
|
||||
"thiserror",
|
||||
"utm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.5"
|
||||
@ -1336,6 +1447,36 @@ dependencies = [
|
||||
"loom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"structopt-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
@ -1353,6 +1494,17 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59d3276aee1fa0c33612917969b5172b5be2db051232a6e4826f1a1a9191b045"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.3.0"
|
||||
@ -1368,23 +1520,32 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.38"
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.38"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1451,7 +1612,7 @@ checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1514,7 +1675,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1595,7 +1756,7 @@ checksum = "d337d3be617449165cb4633c8dece429afd83f84051024079f97ad32a9663716"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1620,6 +1781,18 @@ version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.4"
|
||||
@ -1636,12 +1809,24 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utm"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95b09e3b3a0abd1ccb77673a6b7b8875d9d1c80626154add451cf18392dc4c3c"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
@ -1696,7 +1881,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -1718,7 +1903,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.107",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -10,6 +10,7 @@ members = [
|
||||
"./xpin-wasm/",
|
||||
"./web",
|
||||
"./web-frontend/",
|
||||
"./spatial-coordinate-systems/",
|
||||
]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
12
spatial-coordinate-systems/Cargo.toml
Normal file
12
spatial-coordinate-systems/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "spatial-coordinate-systems"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nom = "7.1.3"
|
||||
pluscodes = "0.5.0"
|
||||
thiserror = "1.0.40"
|
||||
utm = "0.1.6"
|
36
spatial-coordinate-systems/src/common.rs
Normal file
36
spatial-coordinate-systems/src/common.rs
Normal file
@ -0,0 +1,36 @@
|
||||
use nom::{
|
||||
branch::alt,
|
||||
bytes::complete::tag_no_case,
|
||||
character::{
|
||||
complete::{space0, space1},
|
||||
*,
|
||||
},
|
||||
combinator::{map, opt},
|
||||
sequence::tuple,
|
||||
IResult,
|
||||
};
|
||||
|
||||
use crate::Direction;
|
||||
|
||||
pub fn optional_separator<'a>(sep: char) -> impl FnMut(&'a str) -> IResult<&'a str, ()> {
|
||||
map(
|
||||
alt((
|
||||
map(tuple((space0, complete::char(sep), space0)), std::mem::drop),
|
||||
map(space1, std::mem::drop),
|
||||
)),
|
||||
std::mem::drop,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_direction(i: &str) -> IResult<&str, Direction> {
|
||||
alt((
|
||||
map(tag_no_case("north"), |_| Direction::North),
|
||||
map(tag_no_case("south"), |_| Direction::South),
|
||||
map(tag_no_case("east"), |_| Direction::East),
|
||||
map(tag_no_case("west"), |_| Direction::West),
|
||||
map(tag_no_case("n"), |_| Direction::North),
|
||||
map(tag_no_case("s"), |_| Direction::South),
|
||||
map(tag_no_case("e"), |_| Direction::East),
|
||||
map(tag_no_case("w"), |_| Direction::West),
|
||||
))(i)
|
||||
}
|
104
spatial-coordinate-systems/src/dm.rs
Normal file
104
spatial-coordinate-systems/src/dm.rs
Normal file
@ -0,0 +1,104 @@
|
||||
use crate::{
|
||||
common::{optional_separator, parse_direction},
|
||||
Direction,
|
||||
};
|
||||
use nom::{
|
||||
branch::alt,
|
||||
character::complete::{self, space0, space1},
|
||||
combinator::{eof, map, map_opt, map_res, opt},
|
||||
number::complete::double,
|
||||
sequence::{pair, tuple},
|
||||
IResult,
|
||||
};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub fn parse_coordinate(i: &str) -> IResult<&str, (DegreeMinute, DegreeMinute)> {
|
||||
map_opt(
|
||||
tuple((parse, optional_separator(','), parse)),
|
||||
|(ns, _, ew)| {
|
||||
// Ensure this is a north/south then east/west direction
|
||||
if ns.direction.is_lat() && ew.direction.is_lon() {
|
||||
Some((ns, ew))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
)(i)
|
||||
}
|
||||
|
||||
pub fn parse(i: &str) -> IResult<&str, DegreeMinute> {
|
||||
map(
|
||||
tuple((
|
||||
// Degrees
|
||||
complete::i16,
|
||||
optional_separator('°'),
|
||||
// Minutes
|
||||
double,
|
||||
optional_separator('\''),
|
||||
// Direction
|
||||
parse_direction,
|
||||
)),
|
||||
|(degrees, (), minutes, (), direction)| DegreeMinute {
|
||||
degrees,
|
||||
minutes,
|
||||
direction,
|
||||
},
|
||||
)(i)
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct DegreeMinute {
|
||||
pub degrees: i16,
|
||||
pub minutes: f64,
|
||||
pub direction: Direction,
|
||||
}
|
||||
|
||||
impl FromStr for DegreeMinute {
|
||||
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::dm::DegreeMinute;
|
||||
/// use spatial_coordinate_systems::Direction;
|
||||
/// use std::str::FromStr;
|
||||
///
|
||||
/// assert_eq!(DegreeMinute::from_str("40 31.3 N").unwrap(), DegreeMinute {
|
||||
/// degrees: 40,
|
||||
/// minutes: 31.3_f64,
|
||||
/// direction: Direction::North,
|
||||
/// });
|
||||
/// assert_eq!(DegreeMinute::from_str("40°31' N").unwrap(), DegreeMinute {
|
||||
/// degrees: 40,
|
||||
/// minutes: 31_f64,
|
||||
/// direction: Direction::North,
|
||||
/// });
|
||||
/// ```
|
||||
fn from_str(i: &str) -> Result<Self, Self::Err> {
|
||||
map(
|
||||
tuple((
|
||||
space0,
|
||||
// Degrees
|
||||
complete::i16,
|
||||
optional_separator('°'),
|
||||
// Minutes
|
||||
double,
|
||||
optional_separator('\''),
|
||||
// Direction
|
||||
parse_direction,
|
||||
// Ensure no other characters can be read
|
||||
eof,
|
||||
)),
|
||||
|(_, degrees, (), minutes, (), direction, _)| DegreeMinute {
|
||||
degrees,
|
||||
minutes,
|
||||
direction,
|
||||
},
|
||||
)(i)
|
||||
.map_err(|_| ())
|
||||
.map(|(_, ret)| ret)
|
||||
}
|
||||
}
|
115
spatial-coordinate-systems/src/dms.rs
Normal file
115
spatial-coordinate-systems/src/dms.rs
Normal file
@ -0,0 +1,115 @@
|
||||
use crate::{
|
||||
common::{optional_separator, parse_direction},
|
||||
Direction,
|
||||
};
|
||||
use nom::{
|
||||
branch::alt,
|
||||
character::complete::{self, space0, space1},
|
||||
combinator::{eof, map, map_opt, map_res, opt},
|
||||
number::complete::double,
|
||||
sequence::{pair, tuple},
|
||||
IResult,
|
||||
};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub fn parse_coordinate(i: &str) -> IResult<&str, (DegreeMinuteSecond, DegreeMinuteSecond)> {
|
||||
map_opt(
|
||||
tuple((parse, optional_separator(','), parse)),
|
||||
|(ns, _, ew)| {
|
||||
// Ensure this is a north/south then east/west direction
|
||||
if ns.direction.is_lat() && ew.direction.is_lon() {
|
||||
Some((ns, ew))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
)(i)
|
||||
}
|
||||
|
||||
pub fn parse(i: &str) -> IResult<&str, DegreeMinuteSecond> {
|
||||
map(
|
||||
tuple((
|
||||
// Degrees
|
||||
complete::i16,
|
||||
optional_separator('°'),
|
||||
// Minutes
|
||||
complete::i16,
|
||||
optional_separator('\''),
|
||||
// Seconds
|
||||
double,
|
||||
optional_separator('"'),
|
||||
// Direction
|
||||
parse_direction,
|
||||
)),
|
||||
|(degrees, (), minutes, (), seconds, (), direction)| DegreeMinuteSecond {
|
||||
degrees,
|
||||
minutes,
|
||||
seconds,
|
||||
direction,
|
||||
},
|
||||
)(i)
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct DegreeMinuteSecond {
|
||||
pub degrees: i16,
|
||||
pub minutes: i16,
|
||||
pub seconds: f64,
|
||||
pub direction: Direction,
|
||||
}
|
||||
|
||||
impl FromStr for DegreeMinuteSecond {
|
||||
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::DegreeMinuteSecond;
|
||||
/// use spatial_coordinate_systems::Direction;
|
||||
/// use std::str::FromStr;
|
||||
///
|
||||
/// assert_eq!(DegreeMinuteSecond::from_str("40 31 21 N").unwrap(), DegreeMinuteSecond {
|
||||
/// degrees: 40,
|
||||
/// minutes: 31,
|
||||
/// seconds: 21_f64,
|
||||
/// direction: Direction::North,
|
||||
/// });
|
||||
/// assert_eq!(DegreeMinuteSecond::from_str("40°31' 21 \" N").unwrap(), DegreeMinuteSecond {
|
||||
/// degrees: 40,
|
||||
/// minutes: 31,
|
||||
/// seconds: 21_f64,
|
||||
/// direction: Direction::North,
|
||||
/// });
|
||||
/// ```
|
||||
fn from_str(i: &str) -> Result<Self, Self::Err> {
|
||||
map(
|
||||
tuple((
|
||||
space0,
|
||||
// Degrees
|
||||
complete::i16,
|
||||
optional_separator('°'),
|
||||
// Minutes
|
||||
complete::i16,
|
||||
optional_separator('\''),
|
||||
// Seconds
|
||||
double,
|
||||
optional_separator('"'),
|
||||
// Direction
|
||||
parse_direction,
|
||||
// Ensure no other characters can be read
|
||||
eof,
|
||||
)),
|
||||
|(_, degrees, (), minutes, (), seconds, (), direction, _)| DegreeMinuteSecond {
|
||||
degrees,
|
||||
minutes,
|
||||
seconds,
|
||||
direction,
|
||||
},
|
||||
)(i)
|
||||
.map_err(|_| ())
|
||||
.map(|(_, ret)| ret)
|
||||
}
|
||||
}
|
71
spatial-coordinate-systems/src/lib.rs
Normal file
71
spatial-coordinate-systems/src/lib.rs
Normal file
@ -0,0 +1,71 @@
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use std::str::FromStr;
|
||||
mod common;
|
||||
pub mod dm;
|
||||
pub mod dms;
|
||||
|
||||
use dm::DegreeMinute;
|
||||
use dms::DegreeMinuteSecond;
|
||||
use nom::{
|
||||
branch::alt,
|
||||
character::complete::space0,
|
||||
combinator::{eof, map},
|
||||
sequence::tuple,
|
||||
IResult,
|
||||
};
|
||||
|
||||
pub struct LatLon {
|
||||
pub lat: f64,
|
||||
pub lon: f64,
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error("Unknown")]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Direction {
|
||||
North,
|
||||
South,
|
||||
East,
|
||||
West,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
/// True if this is north/south
|
||||
pub fn is_lat(&self) -> bool {
|
||||
self == &Direction::North || self == &Direction::South
|
||||
}
|
||||
/// True if this is east/west
|
||||
pub fn is_lon(&self) -> bool {
|
||||
self == &Direction::East || self == &Direction::West
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Coordinate {
|
||||
LatLon((f64, f64)),
|
||||
DegreeMinuteSecond((DegreeMinuteSecond, DegreeMinuteSecond)),
|
||||
DegreeMinute((DegreeMinute, DegreeMinute)),
|
||||
}
|
||||
|
||||
pub enum CoordinateSystem {
|
||||
LatLon,
|
||||
}
|
||||
|
||||
impl FromStr for Coordinate {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(i: &str) -> Result<Self, Self::Err> {
|
||||
tuple((
|
||||
space0,
|
||||
alt((map(dms::parse_coordinate, Coordinate::DegreeMinuteSecond),)),
|
||||
space0,
|
||||
eof,
|
||||
))(i)
|
||||
.map(|(_, (_, coordinate, _, _))| coordinate)
|
||||
.map_err(|_| ())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user