api gives responses

This commit is contained in:
Pagwin 2024-02-18 06:01:09 -05:00
parent dec8ab4334
commit eab76d8787
5 changed files with 89 additions and 36 deletions

View file

@ -10,11 +10,16 @@ pub async fn calc_travel_path(path:&[crate::types::Coords])->anyhow::Result<Trav
let response = client.post("https://routes.googleapis.com/directions/v2:computeRoutes")
.body(serde_json::to_string(&build_route_body_pain(path))?)
.header("Content-Type","application/json")
.header("X-Goog-Api-Key:", google_api_key)
.header("X-Goog-Api-Key", google_api_key.bytes().filter(|b|*b >= 32 && *b != 127 || *b == b'\t').map(|n|char::from_u32(n as u32).unwrap()).collect::<String>())
.header("X-Goog-FieldMask", "routes.duration,routes.polyline.encodedPolyline,routes.legs")
.send().await?;
let response = serde_json::from_str::<RouteResponse>(response.text().await?.as_str())?;
.send().await;
let response = match response {
Ok(res) => res,
Err(e) => panic!("{:?}",e)
};
let t = response.text().await?;
//println!("{}",t);
let response = serde_json::from_str::<RouteResponse>(t.as_str())?;
Ok(response.into())
}
impl From<RouteResponse> for TravelPathInfo{
@ -53,14 +58,36 @@ struct LocIn{
longitude: f64
}
fn build_route_body_pain(path:&[crate::types::Coords])->serde_json::Value{
let inter = &path[1..path.len()-1];
let inter = if path.len() >= 2 {
&path[1..25]//path.len()-1]
}else {[].as_slice()};
let inter = inter.iter().map(|v|{
serde_json::json!({
"location": {
"latLng":{
"latitude": v.lat,
"longitude": v.lon
}
}
})
}).collect::<Vec<serde_json::Value>>();
let val = serde_json::json!({
"origin":{
"location": path[0],
"location":{
"latLng":{
"latitude": path[0].lat,
"longitude": path[0].lon,
}
},
"sideOfRoad": true
},
"destination":{
"location":path[path.len()-1]
"location":{
"latLng":{
"latitude":path[path.len()-1].lat,
"longitude":path[path.len()-1].lon
}
}
},
"intermediates": inter,
"travelMode": "DRIVE",

View file

@ -55,9 +55,17 @@ async fn transit_path(req: tide::Request<state::State>)->tide::Result{
routes.append(&mut route::broome_county_routes_get().await?);
let route = path_calc::calc_route(&mut routes,from,to).await?;
let path = route.into_iter().map(|(route,enter,exit)|{
RetRoute{
route_name:route.name,
route_id: route.id,
enter_stop_id:enter,
exit_stop_id:exit
}
}).collect();
let ret = TransitPathResult{
path: route.into_iter().map(RetRoute::from).collect()
path
};
let resp_body:String = serde_json::to_string(&ret)?.into();
let resp = tide::Response::builder(200)
@ -77,22 +85,16 @@ struct TransitPathQuery{
}
#[derive(serde::Serialize)]
struct TransitPathResult{
path:Vec<RetRoute>
path:Vec<RetRoute>,
}
#[derive(serde::Serialize)]
struct RetRoute{
route_name:String,
//enter_stop_id:u32,
//exit_stop_id:u32,
route_id: u32,
enter_stop_id:u32,
exit_stop_id:u32,
//enter_stop_coords: types::Coords
}
impl From<route::Route> for RetRoute{
fn from(route: route::Route) -> Self {
Self{
route_name: route.name,
}
}
}
/// return the num of estimated seconds for stop ids given in query params, also need to specify
/// service and route id
@ -120,7 +122,12 @@ async fn transit_estimate(req: tide::Request<state::State>)->tide::Result{
let Some((to_idx,_)) = route.stops.iter().enumerate().find(|(_,stop)|stop.id == query.to)
else {return Ok(tide::Response::builder(400).body("Error: invalid id").into())};
Ok(format!("{}", path_calc::bus_travel_time(route, from_idx, to_idx).await?).into())
let resp_body = format!("{}", path_calc::bus_travel_time(route, from_idx, to_idx).await?.num_seconds());
let resp = tide::Response::builder(200)
.body(resp_body)
.header("Content-Type","application/json")
.build();
Ok(resp)
}
#[derive(serde::Deserialize)]
struct TransitEstimateQuery{
@ -152,12 +159,18 @@ async fn bus_route_draw(req: tide::Request<state::State>)->tide::Result{
};
let ret = stop::RouteDraw {
color: route.color,
stops: route.stops.into_iter().map(|stop|{types::Coords{lat:stop.lat,lon:stop.lon}}).collect()
poly_line: route.poly_line
//stops: route.stops.into_iter().map(|stop|{types::Coords{lat:stop.lat,lon:stop.lon}}).collect()
};
Ok(serde_json::to_string(&ret)?.into())
let resp_body:String = serde_json::to_string(&ret)?.into();
let resp = tide::Response::builder(200)
.body(resp_body)
.header("Content-Type","application/json")
.build();
Ok(resp)
}
#[derive(serde::Deserialize)]
#[derive(serde::Deserialize, Debug, Clone)]
struct RouteDrawQuery{
id: u32,
service: String

View file

@ -22,7 +22,7 @@ fn sort_routes_by_measure<F:Fn(&&crate::stop::Stop)->u64+Clone>(measure: F, rout
const BU: crate::types::Coords = crate::types::Coords{lat:42.08707019482314, lon:-75.96706048564714};
const BC_BUS_HUB: crate::types::Coords = crate::types::Coords{lat:42.10156942719183, lon:-75.91073683134701};
// return a list indicating the bus routes to take in order
pub async fn calc_route(routes:&mut [crate::route::Route], from:crate::types::Coords, to: crate::types::Coords)->anyhow::Result<Vec<crate::route::Route>>{
pub async fn calc_route(routes:&mut [crate::route::Route], from:crate::types::Coords, to: crate::types::Coords)->anyhow::Result<Vec<(crate::route::Route,u32,u32)>>{
if routes.len() == 0 {
return Ok(Vec::new())
}
@ -31,17 +31,21 @@ pub async fn calc_route(routes:&mut [crate::route::Route], from:crate::types::Co
let measure_distance_from = walk_distance_measure(from);
let measure_distance_bu = walk_distance_measure(BU);
let measure_distance_bc_hub = walk_distance_measure(BC_BUS_HUB);
let tmp = measure_distance_to.clone();
let route_measure_dist_to = move |route: &crate::route::Route|{
measure_distance_to(&route.stops.iter().min_by_key(measure_distance_to.clone()).unwrap())
tmp(&route.stops.iter().min_by_key(tmp.clone()).unwrap())
};
let tmp = measure_distance_from.clone();
let route_measure_dist_from = move |route: &crate::route::Route|{
measure_distance_from(&route.stops.iter().min_by_key(measure_distance_from.clone()).unwrap())
tmp(&route.stops.iter().min_by_key(tmp.clone()).unwrap())
};
let tmp = measure_distance_bu.clone();
let route_measure_dist_bu = move |route: &crate::route::Route|{
measure_distance_bu(&route.stops.iter().min_by_key(measure_distance_bu.clone()).unwrap())
tmp.clone()(&route.stops.iter().min_by_key(tmp.clone()).unwrap())
};
let tmp = measure_distance_bc_hub.clone();
let route_measure_dist_bc_hub = move |route: &crate::route::Route|{
measure_distance_bc_hub(&route.stops.iter().min_by_key(measure_distance_bc_hub.clone()).unwrap())
tmp(&route.stops.iter().min_by_key(tmp.clone()).unwrap())
};
let min_direct_route = routes.iter().min_by_key(|route|route_measure_dist_to(route)+route_measure_dist_from(route)).unwrap();
@ -56,7 +60,21 @@ pub async fn calc_route(routes:&mut [crate::route::Route], from:crate::types::Co
let min_to_bc_hub = crate::route::Route::default();
let min_from_bc_hub = crate::route::Route::default();
let bc_route_cost = u64::MAX;
Ok(select_min(vec![(direct_route_cost,vec![min_direct_route.clone()]), (bu_route_cost,vec![min_to_bu_route.clone(),min_from_bu_route.clone()]), (bc_route_cost, vec![min_to_bc_hub.clone(), min_from_bc_hub.clone()])]))
let min = *[direct_route_cost,bu_route_cost,bc_route_cost].iter().min().unwrap();
if min == direct_route_cost{
Ok(vec![(min_direct_route.clone(), min_direct_route.stops.iter().min_by_key(measure_distance_from).unwrap().id, min_direct_route.stops.iter().min_by_key(measure_distance_to).unwrap().id)])
}
else if min == bu_route_cost{
Ok(vec![(min_to_bu_route.clone(), min_to_bu_route.stops.iter().min_by_key(measure_distance_from).unwrap().id, min_to_bu_route.stops.iter().min_by_key(measure_distance_bu.clone()).unwrap().id),(min_from_bu_route.clone(), min_from_bu_route.stops.iter().min_by_key(measure_distance_bu).unwrap().id, min_from_bu_route.stops.iter().min_by_key(measure_distance_to).unwrap().id)])
}
else {
Ok(vec![(min_to_bc_hub.clone(), min_to_bc_hub.stops.iter().min_by_key(measure_distance_from).unwrap().id, min_to_bc_hub.stops.iter().min_by_key(measure_distance_bc_hub.clone()).unwrap().id),(min_from_bc_hub.clone(), min_from_bc_hub.stops.iter().min_by_key(measure_distance_bc_hub).unwrap().id, min_from_bc_hub.stops.iter().min_by_key(measure_distance_to).unwrap().id)])
}
//let min = select_min(vec![(direct_route_cost,vec![min_direct_route.clone()]), (bu_route_cost,vec![min_to_bu_route.clone(),min_from_bu_route.clone()]), (bc_route_cost, vec![min_to_bc_hub.clone(), min_from_bc_hub.clone()])]);
}
fn walk_distance_measure(pos: crate::types::Coords)->impl Fn(&&crate::stop::Stop)->u64+Clone{
@ -65,8 +83,3 @@ fn walk_distance_measure(pos: crate::types::Coords)->impl Fn(&&crate::stop::Stop
(((stop.lat-pos.lat).powi(2) + (stop.lon - pos.lon).powi(2)).powf(0.5)*1_000_000.0) as u64
}
}
fn select_min(dist_route_pairs:Vec<(u64,Vec<crate::route::Route>)>)->Vec<crate::route::Route>{
let (_, ret) = dist_route_pairs.into_iter().min_by_key(|(dist,_)|dist.clone()).unwrap();
ret
}

View file

@ -1,5 +1,5 @@
#[derive(Hash, Clone, Default)]
#[derive(Hash, Clone, Default, Debug)]
pub struct Route {
pub id:u32,
pub name: String,

View file

@ -106,6 +106,6 @@ fn enc_float(num:f64)->String{
#[derive(serde::Serialize)]
pub struct RouteDraw{
pub color:String,
pub stops:Vec<crate::types::Coords>
pub poly_line:String
}