From ab4e669f553858284ccd2234e6ebea152d158de6 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Sun, 18 Feb 2024 08:27:47 -0500 Subject: [PATCH] seemingly finished state --- BBB_frontend/index.html | 8 ----- BBB_frontend/main.js | 61 +++++++++++++++++++++++++++++++--- BBB_frontend/package-lock.json | 16 +++++++++ BBB_frontend/package.json | 3 ++ README.md | 8 +++-- src/google.rs | 2 +- src/main.rs | 19 ++++++++--- src/path_calc.rs | 7 ++-- src/types.rs | 15 ++++++--- 9 files changed, 111 insertions(+), 28 deletions(-) diff --git a/BBB_frontend/index.html b/BBB_frontend/index.html index 0c9386f..38732d6 100644 --- a/BBB_frontend/index.html +++ b/BBB_frontend/index.html @@ -7,14 +7,6 @@ -
diff --git a/BBB_frontend/main.js b/BBB_frontend/main.js index 802ddb4..dcf0e40 100644 --- a/BBB_frontend/main.js +++ b/BBB_frontend/main.js @@ -1,5 +1,13 @@ import './style.css' +window.main = main; + +var script = document.createElement('script'); +script.src = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyBa1wDqAMfKv30BSzSdXB-AEsk4BRD9xTw&callback=main&libraries=geometry'; +script.async = true; + +document.head.appendChild(script); + async function main(){ const {Map} = await google.maps.importLibrary("maps"); const map = new Map(document.getElementById("map"),{ @@ -34,11 +42,13 @@ async function main(){ const to_lattitude_input = document.createElement("input"); to_lattitude_input.placeholder = "42.10125081757972"; to_lattitude_input.type = "number"; + to_lattitude_input.id = "to_lattitude_input"; UI.appendChild(to_lattitude_input); const to_longitude_input = document.createElement("input"); to_longitude_input.type = "number"; to_longitude_input.placeholder = "-75.94181323552698"; + to_longitude_input.id = "to_longitude_input"; UI.appendChild(to_longitude_input); const to_pos_button = document.createElement("button"); @@ -57,6 +67,13 @@ async function main(){ sub_button.innerText = "Submit"; UI.appendChild(sub_button); + window.paths = []; + let clear_button = document.createElement("button"); + clear_button.addEventListener("click", clear_lines); + clear_button.id = "clear_button"; + clear_button.innerText = "Clear"; + UI.appendChild(clear_button) + map.addListener("click", e=>{ const {lat, lng} = e.latLng; if(from_pos_toggle){ @@ -75,10 +92,46 @@ async function main(){ function submit_func(map){ //TODO: grab the path and show the poly lines and the bus route name async function submit(clickEvent){ - let from_lat = document.getElementById("from_lattitude_input"); - let from_lon = document.getElementById("from_longitude_input"); -} + let from_lat = document.getElementById("from_lattitude_input").value; + let from_lon = document.getElementById("from_longitude_input").value; + let to_lat = document.getElementById("to_lattitude_input").value; + let to_lon = document.getElementById("to_longitude_input").value; + let path = await fetch(`http://localhost:8080/path?time=e&from_lat=${from_lat}&from_lon=${from_lon}&to_lat=${to_lat}&to_lon=${to_lon}`).then(r=>r.json()); + let secs = []; + for(let route of path.path){ + console.log(route.route_name); + secs.push(fetch(`http://localhost:8080/time_to_arrive?service=${route.service}&from=${route.enter_stop_id}&to=${route.exit_stop_id}&route=${route.route_id}`).then(r=>r.json())); + fetch(`http://localhost:8080/route_draw?service=${route.service}&id=${route.route_id}`).then(r=>r.json()).then(v=>{ + return {path:google.maps.geometry.encoding.decodePath(v.poly_line), color:v.color} + }) + .then(o=>{ + let line = new google.maps.Polyline({ + path:o.path, + strokeColor: o.color, + strokeOpacity: 1.0, + strokeWeight: 3, + }); + line.setMap(map); + window.paths.push(line); + //setTimeout(()=>line.setVisible(false), 5000); + }) + } + Promise.all(secs).then(l=>l.reduce((a,b)=>a+b)).then(v=>alert(`bus ride will take ${display_time(v)}`)); +} return submit; } -main(); +function display_time(secs){ + if(secs > 60){ + return `${Math.floor(secs/60)} minutes and ${secs%60} seconds`; + } + else{ + return `${secs%60} seconds`; + + } +} +async function clear_lines(){ + for (let path of window.paths) path.setMap(null); + window.paths = []; + console.clear(); +} diff --git a/BBB_frontend/package-lock.json b/BBB_frontend/package-lock.json index ea4e8d3..476f4e8 100644 --- a/BBB_frontend/package-lock.json +++ b/BBB_frontend/package-lock.json @@ -7,6 +7,9 @@ "": { "name": "bbb-frontend", "version": "0.0.0", + "dependencies": { + "@googlemaps/js-api-loader": "^1.16.6" + }, "devDependencies": { "vite": "^5.1.0" } @@ -379,6 +382,14 @@ "node": ">=12" } }, + "node_modules/@googlemaps/js-api-loader": { + "version": "1.16.6", + "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.6.tgz", + "integrity": "sha512-V8p5W9DbPQx74jWUmyYJOerhiB4C+MHekaO0ZRmc6lrOYrvY7+syLhzOWpp55kqSPeNb+qbC2h8i69aLIX6krQ==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", @@ -592,6 +603,11 @@ "@esbuild/win32-x64": "0.19.12" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", diff --git a/BBB_frontend/package.json b/BBB_frontend/package.json index b411c8e..a913778 100644 --- a/BBB_frontend/package.json +++ b/BBB_frontend/package.json @@ -10,5 +10,8 @@ }, "devDependencies": { "vite": "^5.1.0" + }, + "dependencies": { + "@googlemaps/js-api-loader": "^1.16.6" } } diff --git a/README.md b/README.md index 7eedefe..0ae9484 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,13 @@ to run you need a file called GOOGLE_API_KEY in the dir the app is run in which ## TODO: -- test with OCCT buses +- test with BC buses +- Make buttons change color to indicate toggle +- Prevent buses from going backwards +- make time estimate accurate (beyond hack divide by 3) - Change api to give a not shitty poly line for Broome county buses +- Trim poly lines down to the bit between bus stops +- Fix the UI so console and alert aren't needed - refactor to work within docker and setup within docker-compose - make route checking more advanced with better walking heuristic - make route checking more advanced by allowing multiple factors with multiple weights including @@ -14,6 +19,5 @@ to run you need a file called GOOGLE_API_KEY in the dir the app is run in which - bus travel time - layover time - ultimate arrival time -- Test for Broome county buses (can't at night due to being too late) - use a DB via SeaORM to avoid spaming APIs - use info in db to try and predict bus schedules in future diff --git a/src/google.rs b/src/google.rs index b34c564..96ab9fa 100644 --- a/src/google.rs +++ b/src/google.rs @@ -59,7 +59,7 @@ struct LocIn{ } fn build_route_body_pain(path:&[crate::types::Coords])->serde_json::Value{ let inter = if path.len() >= 2 { - &path[1..25]//path.len()-1] + &path[1..25.min(path.len()-1)]//] }else {[].as_slice()}; let inter = inter.iter().map(|v|{ serde_json::json!({ diff --git a/src/main.rs b/src/main.rs index b928806..817e583 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,11 @@ async fn main() -> anyhow::Result<()> { app.at("/route_draw").get(bus_route_draw); app.at("/").get(|_|async { println!("get"); - Ok(tide::Response::from("OK")) + let resp = tide::Response::builder(200) + .body("OK") + .header("Access-Control-Allow-Origin", "*") + .build(); + Ok(resp) }); app.at("/*").get(|_|async{ Ok(tide::Response::from("???")) @@ -61,7 +65,8 @@ async fn transit_path(req: tide::Request)->tide::Result{ route_name:route.name, route_id: route.id, enter_stop_id:enter, - exit_stop_id:exit + exit_stop_id:exit, + service: route.service.into() } }).collect(); let ret = TransitPathResult{ @@ -71,6 +76,7 @@ async fn transit_path(req: tide::Request)->tide::Result{ let resp = tide::Response::builder(200) .body(resp_body) .header("Content-Type","application/json") + .header("Access-Control-Allow-Origin", "*") .build(); Ok(resp) } @@ -85,14 +91,15 @@ struct TransitPathQuery{ } #[derive(serde::Serialize)] struct TransitPathResult{ - path:Vec, + path:Vec>, } #[derive(serde::Serialize)] -struct RetRoute{ +struct RetRoute>{ route_name:String, route_id: u32, enter_stop_id:u32, exit_stop_id:u32, + service: S //enter_stop_coords: types::Coords } @@ -122,10 +129,11 @@ async fn transit_estimate(req: tide::Request)->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())}; - let resp_body = format!("{}", path_calc::bus_travel_time(route, from_idx, to_idx).await?.num_seconds()); + let resp_body = format!("{}", path_calc::bus_travel_time(route, from_idx, to_idx).await?.num_seconds()/3); let resp = tide::Response::builder(200) .body(resp_body) .header("Content-Type","application/json") + .header("Access-Control-Allow-Origin", "*") .build(); Ok(resp) } @@ -166,6 +174,7 @@ async fn bus_route_draw(req: tide::Request)->tide::Result{ let resp = tide::Response::builder(200) .body(resp_body) .header("Content-Type","application/json") + .header("Access-Control-Allow-Origin", "*") .build(); Ok(resp) } diff --git a/src/path_calc.rs b/src/path_calc.rs index 44c7ea2..0444035 100644 --- a/src/path_calc.rs +++ b/src/path_calc.rs @@ -1,5 +1,6 @@ pub async fn bus_travel_time(route:crate::route::Route, from_idx:usize, to_idx:usize)->anyhow::Result{ - let coords:Vec = route.stops[from_idx..=to_idx].iter() + // TODO: taking the min allows the bus to go backwards for travel time which is illegal + let coords:Vec = route.stops[from_idx.min(to_idx)..=to_idx.max(from_idx)].iter() .map(|stop|crate::types::Coords{lat:stop.lat, lon:stop.lon}) .collect(); let travel_time = crate::google::calc_travel_path(&coords).await?; @@ -62,10 +63,10 @@ pub async fn calc_route(routes:&mut [crate::route::Route], from:crate::types::Co let bc_route_cost = u64::MAX; let min = *[direct_route_cost,bu_route_cost,bc_route_cost].iter().min().unwrap(); - if min == direct_route_cost{ + if direct_route_cost <= min{ 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{ + 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)]) } diff --git a/src/types.rs b/src/types.rs index 7f6a1b8..651686d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -5,11 +5,16 @@ pub struct Coords{ pub lon:f64 } -#[derive(Clone, Copy, Debug, Hash)] -pub enum Service{OCCT, BC} +#[derive(Clone, Copy, Debug, Hash, Default)] +pub enum Service{OCCT, #[default]BC} -impl Default for Service{ - fn default() -> Self { - Service::BC + +impl From for &'static str{ + fn from(value: Service) -> Self { + match value { + Service::OCCT => "OCCT", + Service::BC => "BC" + } } } +