#[macro_use] extern crate rocket; use clap::Parser; use std::process::exit; use std::fs::File; use fapra_osm_2::gridgraph::{GridGraph, Route}; use fapra_osm_2::coordinates::{RadianCoordinate, DegreeCoordinate}; use rand::seq::SliceRandom; use serde::Serialize; use rocket::State; use rocket::response::status::BadRequest; use rocket::form::Form; use rocket::fs::FileServer; use rocket::serde::json::Json; use rocket_dyn_templates::{Template, context, Engines}; #[derive(Parser, Debug)] #[clap(author, version, about, long_about=None)] struct Args { /// name of the FMI file to read #[clap(short, long)] filename: String, } #[get("/")] fn index() -> Template { Template::render("index", context! {}) } #[get("/random")] fn random_route(graphwrapper: &State) -> String { let graph = &graphwrapper.graph; let mut rng = rand::thread_rng(); let mut route = None; while route.is_none() { let start = graph.nodes.choose(&mut rng).unwrap(); let end = graph.nodes.choose(&mut rng).unwrap(); route = graph.shortest_path(&start, &end); } format!("{}", route.unwrap().to_geojson().to_string()) } #[derive(FromForm)] struct RouteQuery<'r> { r#from: &'r str, r#to: &'r str, } #[derive(Debug)] #[derive(Serialize)] pub struct RouteResponse { success: bool, route: Option, } #[post("/route", data = "")] fn route(routequery: Form>, graphwrapper: &State) -> Result, BadRequest> { let from = match DegreeCoordinate::from_string_tuple(routequery.from) { Ok(from) => RadianCoordinate::from(from), Err(e) => {return Result::Err(BadRequest(Some(format!("Error while parsing from field: {:?}", e))));} }; let to = match DegreeCoordinate::from_string_tuple(routequery.to) { Ok(to) => RadianCoordinate::from(to), Err(e) => {return Result::Err(BadRequest(Some(format!("Error while parsing to field: {:?}", e))));} }; let from = graphwrapper.graph.get_nearest_node(from).unwrap(); let to = graphwrapper.graph.get_nearest_node(to).unwrap(); let route = graphwrapper.graph.shortest_path(from, to); println!("from: {:?}, to: {:?}", from, to); let response = RouteResponse{success: route.is_some(), route}; Ok(Json(response)) } struct GraphWrapper { graph: Box } #[launch] fn rocket() -> _ { let args = Args::parse(); println!("Loading file from {}", args.filename); let file = match File::open(args.filename.clone()) { Ok(f) => f, Err(e) => { println!("Error while opening the file {}: {}", args.filename, e); exit(1) } }; let graph = match GridGraph::from_fmi_file(file) { Ok(g) => g, Err(e) => { println!("Error while reading the graph: {:?}", e); exit(1); } }; println!("Loaded graph file"); // let graph = GridGraph::generate_regular_grid(10,10); rocket::build() .manage(GraphWrapper{graph: graph}) .mount("/", routes![index]) .mount("/", routes![random_route]) .mount("/", routes![route]) .mount("/static", FileServer::from("static")) .attach(Template::custom(|engines: &mut Engines| {engines.handlebars.set_dev_mode(true);})) }