Start work on generating urls
This commit is contained in:
parent
432f7259ac
commit
773063daf0
61
Cargo.lock
generated
61
Cargo.lock
generated
@ -350,6 +350,15 @@ version = "1.0.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "form_urlencoded"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.27"
|
version = "0.3.27"
|
||||||
@ -577,6 +586,16 @@ dependencies = [
|
|||||||
"want",
|
"want",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.2"
|
version = "1.9.2"
|
||||||
@ -1354,6 +1373,7 @@ dependencies = [
|
|||||||
"nom",
|
"nom",
|
||||||
"pluscodes",
|
"pluscodes",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"url",
|
||||||
"utm",
|
"utm",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1512,6 +1532,21 @@ dependencies = [
|
|||||||
"time-core",
|
"time-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.26.0"
|
version = "1.26.0"
|
||||||
@ -1702,12 +1737,27 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-bidi"
|
||||||
|
version = "0.3.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.8"
|
version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
@ -1726,6 +1776,17 @@ version = "0.2.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "url"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"idna",
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utm"
|
name = "utm"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
@ -22,3 +22,4 @@ nom = "7.1.3"
|
|||||||
pluscodes = "0.5.0"
|
pluscodes = "0.5.0"
|
||||||
utm = "0.1.6"
|
utm = "0.1.6"
|
||||||
thiserror = "1.0.38"
|
thiserror = "1.0.38"
|
||||||
|
url = "2.3.1"
|
||||||
|
@ -21,6 +21,13 @@ pub enum Error {
|
|||||||
NomErr(String),
|
NomErr(String),
|
||||||
#[error("No UTM zone letter")]
|
#[error("No UTM zone letter")]
|
||||||
NoUtmZoneLetter,
|
NoUtmZoneLetter,
|
||||||
|
/// The url could not be parsed at all
|
||||||
|
#[error("Could not parse URL: {0}")]
|
||||||
|
UrlParseError(url::ParseError),
|
||||||
|
|
||||||
|
/// A latitude/longitude could not be extracted from the url
|
||||||
|
#[error("Could not find lat/lon in URL: {0}")]
|
||||||
|
NoUrlLatLon(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<pluscodes::Error> for Error {
|
impl From<pluscodes::Error> for Error {
|
||||||
@ -35,6 +42,12 @@ impl From<utm::WSG84ToLatLonError> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<url::ParseError> for Error {
|
||||||
|
fn from(e: url::ParseError) -> Self {
|
||||||
|
Self::UrlParseError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: std::fmt::Debug> From<nom::Err<E>> for Error {
|
impl<E: std::fmt::Debug> From<nom::Err<E>> for Error {
|
||||||
fn from(e: nom::Err<E>) -> Self {
|
fn from(e: nom::Err<E>) -> Self {
|
||||||
Self::NomErr(format!("{e:?}"))
|
Self::NomErr(format!("{e:?}"))
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::Error;
|
use nom::{
|
||||||
|
character::complete::space0,
|
||||||
|
combinator::{eof, map_res},
|
||||||
|
sequence::tuple,
|
||||||
|
IResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
common::{optional_separator, parse_f64},
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone, Copy)]
|
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||||
pub struct LatLon {
|
pub struct LatLon {
|
||||||
@ -26,6 +36,23 @@ impl LatLon {
|
|||||||
pub fn get_lon(&self) -> f64 {
|
pub fn get_lon(&self) -> f64 {
|
||||||
self.lon
|
self.lon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse a latitude and longitude as two floating point numbers separated by a comma and/or whitespace only (no bearings)
|
||||||
|
/// Parse only the entire string
|
||||||
|
pub fn parse_full(i: &str) -> IResult<&str, Self> {
|
||||||
|
map_res(
|
||||||
|
tuple((
|
||||||
|
space0,
|
||||||
|
parse_f64,
|
||||||
|
optional_separator(','),
|
||||||
|
space0,
|
||||||
|
parse_f64,
|
||||||
|
space0,
|
||||||
|
eof,
|
||||||
|
)),
|
||||||
|
|(_, lat, _, _, lon, _, _)| Self::new(lat, lon),
|
||||||
|
)(i)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for LatLon {
|
impl fmt::Display for LatLon {
|
||||||
|
@ -6,6 +6,7 @@ pub mod dmm;
|
|||||||
pub mod dms;
|
pub mod dms;
|
||||||
pub mod latlon;
|
pub mod latlon;
|
||||||
pub mod plus;
|
pub mod plus;
|
||||||
|
pub mod urls;
|
||||||
pub mod utm;
|
pub mod utm;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
// pub mod xpin;
|
// pub mod xpin;
|
||||||
|
72
spatial-coordinate-systems/src/urls.rs
Normal file
72
spatial-coordinate-systems/src/urls.rs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
use crate::{Error, LatLon};
|
||||||
|
use std::str::FromStr;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
|
pub struct CoordinateUrls {
|
||||||
|
google_maps: String,
|
||||||
|
latlon: LatLon,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CoordinateUrls {
|
||||||
|
pub fn parse(i: &str) -> Result<Self, Error> {
|
||||||
|
let url = Url::parse(i.trim())?;
|
||||||
|
|
||||||
|
// Try to parse a url from google maps
|
||||||
|
url.query_pairs()
|
||||||
|
.find_map(|(key, value)| {
|
||||||
|
if key != "query" {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
LatLon::parse_full(value.as_ref())
|
||||||
|
.map(|(_, ret)| ret)
|
||||||
|
.ok()
|
||||||
|
.map(Self::try_from)
|
||||||
|
})
|
||||||
|
.ok_or_else(|| Error::NoUrlLatLon(i.to_string()))?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&CoordinateUrls> for LatLon {
|
||||||
|
fn from(coordinate: &CoordinateUrls) -> LatLon {
|
||||||
|
coordinate.latlon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<LatLon> for CoordinateUrls {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(latlon: LatLon) -> Result<Self, Self::Error> {
|
||||||
|
let latlon_str = format!("{},{}", latlon.get_lat(), latlon.get_lon());
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
google_maps: String::from(Url::parse_with_params(
|
||||||
|
"https://www.google.com/maps/search/",
|
||||||
|
&[("api", "1"), ("query", &latlon_str)],
|
||||||
|
)?),
|
||||||
|
latlon,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for CoordinateUrls {
|
||||||
|
type Err = Error;
|
||||||
|
|
||||||
|
fn from_str(i: &str) -> Result<Self, Self::Err> {
|
||||||
|
Self::parse(i).map_err(Into::into)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_general() {
|
||||||
|
assert!(dbg!(CoordinateUrls::parse(
|
||||||
|
"https://www.google.com/maps/search/?query=27,23"
|
||||||
|
))
|
||||||
|
.is_ok());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user