use std::{net::SocketAddr, path::Path, sync::Arc};
use axum::{extract::Query, routing::get, Router};
use datasets::{
load_or_compute_country_label_tree, load_or_compute_province_label_tree, lazy_download_map_data,
};
use geo::Point;
mod datasets;
mod labeling;
use serde::Deserialize;
use crate::labeling::LabeledPartitionTree;
#[derive(Deserialize, Debug)]
struct LatLon {
lat: f64,
lon: f64,
}
async fn lat_lon_to_label(
lat_lon: LatLon,
label_tree: Arc<LabeledPartitionTree<String>>,
) -> String {
label_tree
.label(&Point::new(lat_lon.lon, lat_lon.lat))
.unwrap_or(String::from("-99"))
}
#[tokio::main]
async fn main() {
lazy_download_map_data().expect("Could not load or download map data.");
let country_label_tree = load_or_compute_country_label_tree(
Path::new("data"),
Path::new("data\\ne_10m_admin_0_countries_lakes.geojson"),
6
);
let country_label_tree_arc = Arc::new(country_label_tree);
let province_label_tree = load_or_compute_province_label_tree(
Path::new("data"),
Path::new("data\\ne_10m_admin_1_states_provinces_lakes.geojson"),
6
);
let province_label_tree_arc = Arc::new(province_label_tree);
let app = Router::new()
.route(
"/lat_lon_to_country",
get(move |lat_lon: Query<LatLon>| {
lat_lon_to_label(
LatLon {
lat: lat_lon.lat,
lon: lat_lon.lon,
},
country_label_tree_arc.clone(),
)
}),
)
.route(
"/lat_lon_to_province",
get(move |lat_lon: Query<LatLon>| {
lat_lon_to_label(
LatLon {
lat: lat_lon.lat,
lon: lat_lon.lon,
},
province_label_tree_arc.clone(),
)
}),
);
let addr = SocketAddr::from(([127, 0, 0, 1], 8000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}