seemingly finished state

This commit is contained in:
Pagwin 2024-02-18 08:27:47 -05:00
parent eab76d8787
commit ab4e669f55
9 changed files with 111 additions and 28 deletions

View file

@ -7,14 +7,6 @@
</head>
<body>
<!-- google maps api-->
<script>
(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
key: "AIzaSyBa1wDqAMfKv30BSzSdXB-AEsk4BRD9xTw",
v: "weekly",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<div id="map"></div>
<script type="module" src="/main.js"></script>

View file

@ -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();
}

View file

@ -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",

View file

@ -10,5 +10,8 @@
},
"devDependencies": {
"vite": "^5.1.0"
},
"dependencies": {
"@googlemaps/js-api-loader": "^1.16.6"
}
}

View file

@ -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

View file

@ -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!({

View file

@ -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<state::State>)->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<state::State>)->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<RetRoute>,
path:Vec<RetRoute<&'static str>>,
}
#[derive(serde::Serialize)]
struct RetRoute{
struct RetRoute<S:AsRef<str>>{
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<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())};
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<state::State>)->tide::Result{
let resp = tide::Response::builder(200)
.body(resp_body)
.header("Content-Type","application/json")
.header("Access-Control-Allow-Origin", "*")
.build();
Ok(resp)
}

View file

@ -1,5 +1,6 @@
pub async fn bus_travel_time(route:crate::route::Route, from_idx:usize, to_idx:usize)->anyhow::Result<chrono::Duration>{
let coords:Vec<crate::types::Coords> = 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<crate::types::Coords> = 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)])
}

View file

@ -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<Service> for &'static str{
fn from(value: Service) -> Self {
match value {
Service::OCCT => "OCCT",
Service::BC => "BC"
}
}
}