use axum::extract::Path;
use keshvar::CountryIterator;
use s2::{cellid::CellID, latlng::LatLng, point::Point};
pub async fn coords(Path(binary): Path<String>) -> String {
let latlng = s2_to_latlng(&binary);
latlng_to_dms(latlng)
}
pub async fn country(Path(binary): Path<String>) -> String {
dbg!(&binary);
let latlng = s2_to_latlng(&binary);
latlng_to_country(latlng)
}
fn latlng_to_country(latlng: LatLng) -> String {
let lat = latlng.lat.deg();
let lon = latlng.lng.deg();
dbg!(lat, lon);
let mut country = None;
let cs = CountryIterator::new();
for c in cs{
let g = c.geo()
; if g.min_latitude() < lat
&& lat < g.max_latitude()
&& g.min_longitude() < lon
&& lon < g.max_longitude()
{
country = Some(c);
break;
}
}
dbg!(country
.expect("bounding country")
.unofficial_name_list()[0]
.to_string())
}
fn s2_to_latlng(binary: &str) -> LatLng {
let cellid = u64::from_str_radix(binary, 2).expect("64 bigits");
let token = format!("{cellid:x}");
let cellid = CellID::from_token(&token);
let point: Point = cellid.into();
point.into()
}
fn latlng_to_dms(latlng: LatLng) -> String {
let lat = latlng.lat;
let ns = if lat.deg() < 0.0 { "S" } else { "N" };
let (lad, lam, las) = float_to_dms(lat.abs().deg());
let lon = latlng.lng;
let ew = if lon.deg() < 0.0 { "W" } else { "E" };
let (lod, lom, los) = float_to_dms(lon.abs().deg());
format!("{lad}°{lam}'{las:.3}''{ns} {lod}°{lom}'{los:.3}''{ew}")
}
fn float_to_dms(f: f64) -> (f64, f64, f64) {
let d = f.floor();
let m = ((f - d) * 60.0).floor();
let s = ((f - d) * 3600.0) - m * 60.0;
(d, m, s)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn c83() {
assert_eq!(
"83°39'54.324''N 30°37'40.584''W",
latlng_to_dms(s2_to_latlng(
"0100111110010011000110011001010101011111000010100011110001011011"
))
)
}
#[test]
fn c18() {
assert_eq!(
"18°54'55.944''S 47°31'17.976''E",
latlng_to_dms(s2_to_latlng(
"0010000111110000011111100000111010111100000100111101111011000101"
))
)
}
#[test]
fn mada() {
assert_eq!(
"Madagascar",
latlng_to_country(s2_to_latlng(
"0010000111110000011111100000111010111100000100111101111011000101"
))
)
}
}