119 lines
3.3 KiB
Rust
119 lines
3.3 KiB
Rust
#[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<GraphWrapper>) -> 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<Route>,
|
|
}
|
|
|
|
#[post("/route", data = "<routequery>")]
|
|
fn route(routequery: Form<RouteQuery<'_>>, graphwrapper: &State<GraphWrapper>) -> Result<Json<RouteResponse>, BadRequest<String>> {
|
|
|
|
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<GridGraph>
|
|
}
|
|
|
|
#[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);}))
|
|
|
|
}
|