diff --git a/.gitignore b/.gitignore index 7edecbd..4c49bd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1 @@ .env -tracking_data* -target/ - diff --git a/web/src/controllers/route.rs b/web/src/controllers/route.rs index 8fd1062..3e0f188 100644 --- a/web/src/controllers/route.rs +++ b/web/src/controllers/route.rs @@ -6,9 +6,9 @@ use actix_web::{ HttpResponse, Responder, get, web::{self, Data}, }; -use libseptastic::{route::RouteType, stop::StopType, stop_schedule::Trip}; +use libseptastic::{route::RouteType, stop_schedule::Trip}; use serde::{Deserialize, Serialize}; -use std::{collections::{HashMap, HashSet}, io::Write, sync::Arc}; +use std::{collections::HashSet, sync::Arc}; #[derive(Debug, Deserialize, Clone)] struct RouteQueryParams { diff --git a/web/src/main.rs b/web/src/main.rs index ee076e3..a42266b 100644 --- a/web/src/main.rs +++ b/web/src/main.rs @@ -5,13 +5,10 @@ use log::*; use services::gtfs_pull; use std::{fs::File, io::Read, sync::Arc}; -use crate::routing::{bfs_rts, construct_graph}; - mod controllers; mod services; mod session_middleware; mod templates; -mod routing; pub struct AppState { gtfs_service: services::gtfs_pull::GtfsPullService, @@ -61,7 +58,6 @@ async fn main() -> ::anyhow::Result<()> { .service(controllers::stop::get_stop_table_html) .service(controllers::index::get_index_html) .service(controllers::map::get_map_element_html) - .service(routing::get_routing_sample) .service(actix_files::Files::new("/assets", "./assets")) }) .bind(("0.0.0.0", 8080))? diff --git a/web/src/routing.rs b/web/src/routing.rs index cff4df2..7c6e320 100644 --- a/web/src/routing.rs +++ b/web/src/routing.rs @@ -1,10 +1,8 @@ -use std::{cmp::Ordering, collections::{BTreeSet, HashMap, HashSet}, sync::Arc}; +use std::{cmp::Ordering, collections::{BTreeSet, HashMap, HashSet}}; -use actix_web::{Responder, web::Data}; -use libseptastic::stop::StopType; use log::info; -use crate::{AppState, services, session_middleware::{SessionResponder, SessionResponse}, templates::RoutingTemplate}; +use crate::services; pub struct RoutingNodePointer { pub stop_id: String, @@ -81,24 +79,23 @@ pub fn haversine_distance(lat1: f64, lon1: f64, lat2: f64, lon2: f64) -> f64 { } -pub fn get_platforms_near(cds: Coordinates, - all_platforms: &HashMap> +pub fn get_stops_near(cds: Coordinates, + all_stops: &HashMap ) -> HashSet { let near_thresh_km = 0.45; - let mut platforms: HashSet = HashSet::new(); + let mut stops: HashSet = HashSet::new(); - for platform_p in all_platforms { - let platform = platform_p.1; + for stop_p in all_stops { + let stop = stop_p.1; - let dist = haversine_distance(cds.lat, cds.lng, platform.lat, platform.lng); + let dist = haversine_distance(cds.lat, cds.lng, stop.lat, stop.lng); if dist.abs() < near_thresh_km { - info!("dist {} for {} ({})", dist, platform.id.clone(), platform.name.clone()); - platforms.insert(platform.id.clone()); + stops.insert(stop.id.clone()); } } - platforms + stops } pub fn get_stop_as_node() { @@ -106,17 +103,17 @@ pub fn get_stop_as_node() { pub fn construct_graph( dest: Coordinates, - all_platforms: &HashMap>, + all_stops: &HashMap, gtfs_service: &services::gtfs_pull::GtfsPullService ) -> RoutingGraph { let mut graph = RoutingGraph::new(); - let limited_rts = vec!["SEPTABUS_44", "SEPTABUS_65", "SEPTABUS_27", "SEPTABUS_38", "SEPTABUS_124", "SEPTABUS_125", "SEPTABUS_1"]; + let limited_rts = vec!["44", "65", "27", "38", "124", "125", "1"]; - for platform_p in all_platforms { - let platform = platform_p.1; + for stop_p in all_stops { + let stop = stop_p.1; - let ras = gtfs_service.get_routes_at_stop(&platform.id); + let ras = gtfs_service.get_routes_at_stop(&stop.id); let cont = { let mut ret = false; @@ -133,24 +130,24 @@ pub fn construct_graph( continue; } - graph.insert(platform.id.clone(), RoutingNode { - stop_id: platform.id.clone(), - stop_name: platform.name.clone(), + graph.insert(stop.id.clone(), RoutingNode { + stop_id: stop.id.clone(), + stop_name: stop.name.clone(), next_stops_per_routes: { - let routes = gtfs_service.get_routes_at_stop(&platform.id); + let routes = gtfs_service.get_routes_at_stop(&stop.id); let mut other_stops = HashMap::>::new(); for route in &routes { - let mut platforms = gtfs_service.get_platforms_by_route(&route); - platforms.remove(&platform.id); + let mut stops = gtfs_service.get_stops_by_route(&route); + stops.remove(&stop.id); let rnps = { let mut ret = BTreeSet::new(); - for platform in &platforms { - let plt = all_platforms.get(platform).unwrap(); + for stop in &stops { + let stp = all_stops.get(stop).unwrap(); ret.insert(RoutingNodePointer{ - dest_dist: haversine_distance(dest.lat, dest.lng, plt.lat, plt.lng), - stop_id: platform.clone(), + dest_dist: haversine_distance(dest.lat, dest.lng, stp.lat, stp.lng), + stop_id: stop.clone(), route_id: route.clone(), stop_sequence: 0, direction: 0 @@ -170,50 +167,23 @@ pub fn construct_graph( graph } - -#[derive(Clone)] -pub struct WalkRouteStep { - pub dist: f64, - pub dest: String -} - -#[derive(Clone)] -pub struct TransitRouteStep { - pub platform: String, - pub route: String -} - -#[derive(Clone)] -pub enum RouteStep { - Walk(WalkRouteStep), - Transit(TransitRouteStep), - Origin, - Destination -} - -pub fn bfs_rts_int(route_id: &String, origin: &String, graph: &RoutingGraph, dests: &HashSet, mut visited: HashSet, max_legs: u8) -> Option> { +pub fn bfs_rts_int(route_id: &String, origin: &String, graph: &RoutingGraph, dests: &HashSet, mut visited: HashSet, max_legs: u8) -> Option { if max_legs == 0 { return None; } - let mut limited_rts = HashSet::new(); - - for item in vec!["SEPTABUS_44", "SEPTABUS_65", "SEPTABUS_27", "SEPTABUS_38", "SEPTABUS_124", "SEPTABUS_125", "SEPTABUS_1"] { + for item in vec!["44", "65", "27", "38", "124", "125", "1"] { limited_rts.insert(item); } - if !limited_rts.contains(&route_id.as_str()) { - info!("{} is not in the allowlist", route_id.as_str()); - return None; - } - - info!("made it"); + if !limited_rts.contains(&route_id.as_str()) { + return None; + } if let Some(origin_stop) = graph.get(origin) { - if dests.contains(origin) { - return Some(vec![ RouteStep::Transit(TransitRouteStep { platform: origin_stop.stop_name.clone(), route: route_id.clone() }) , RouteStep::Destination]) - } - + if dests.contains(origin) { + return Some(format!("[stop {} via rt {}] --> DEST", origin_stop.stop_name, route_id)) + } if visited.contains(origin) { return None; } @@ -226,9 +196,8 @@ pub fn bfs_rts_int(route_id: &String, origin: &String, graph: &RoutingGraph, des } for rnp in items.1 { - if let Some(mut rt) = bfs_rts_int(items.0, &rnp.stop_id, graph, dests, visited.clone(), max_legs - 1).clone() { - rt.insert(0, RouteStep::Transit(TransitRouteStep{ platform: origin_stop.stop_name.clone(), route: route_id.clone()})); - return Some(rt) + if let Some(rt) = bfs_rts_int(items.0, &rnp.stop_id, graph, dests, visited.clone(), max_legs - 1) { + return Some(format!("[stop {} via rt {}] >>[XFER]>> {}", origin_stop.stop_name, route_id, rt)) } } } @@ -237,18 +206,16 @@ pub fn bfs_rts_int(route_id: &String, origin: &String, graph: &RoutingGraph, des None } -pub fn bfs_rts(origin: &String, graph: &RoutingGraph, dests: &HashSet) -> Vec> { - let mut resp = vec![]; +pub fn bfs_rts(origin: &String, graph: &RoutingGraph, dests: &HashSet) -> String { + let mut resp = String::new(); if let Some(origin_stop) = graph.get(origin) { for items in &origin_stop.next_stops_per_routes { let route_id = items.0; for rnp in items.1 { - if let Some(mut rt) = bfs_rts_int(route_id, &rnp.stop_id, graph, dests, HashSet::new(), 3).clone() { - rt.insert(0, RouteStep::Walk(WalkRouteStep { dist: 0.0, dest: origin_stop.stop_name.clone() })); - rt.insert(0, RouteStep::Origin); - resp.push(rt); + if let Some(rt) = bfs_rts_int(route_id, &rnp.stop_id, graph, dests, HashSet::new(), 3) { + resp += format!("ORIGIN --> [stop {} via rt {}] --> {}\n", origin_stop.stop_name, route_id, rt).as_str(); } } } @@ -256,32 +223,3 @@ pub fn bfs_rts(origin: &String, graph: &RoutingGraph, dests: &HashSet) - resp } - -#[actix_web::get("/routing")] -pub async fn get_routing_sample( - state: Data>, - resp: SessionResponse, -) -> impl Responder { - let mut all_platforms = HashMap::new(); - state.gtfs_service.get_all_stops().iter().map(|stop| { - match &stop.1.platforms { - StopType::SinglePlatform(sp) => vec![sp.clone()], - StopType::MultiPlatform(mp) => mp.clone() - } - }).flatten().for_each(|p| { - all_platforms.insert((&p.id).clone(), p.clone()); - }); - - let srcs = get_platforms_near(Coordinates { lat: 39.95707, lng: -75.16625 }, &all_platforms); - let src = srcs.iter().next().unwrap(); - let dests = get_platforms_near(Coordinates { lat: 40.009144, lng: -75.213796 }, &all_platforms); - let rg = construct_graph(Coordinates { lat: 40.009144, lng: -75.213796 }, &all_platforms, &state.gtfs_service); - - resp.respond( - "test", - "test", - RoutingTemplate { - trips: bfs_rts(&String::from("SEPTABUS_3057"), &rg, &dests) - } - ) -} diff --git a/web/src/services/gtfs_pull.rs b/web/src/services/gtfs_pull.rs index 970a265..bfebaea 100644 --- a/web/src/services/gtfs_pull.rs +++ b/web/src/services/gtfs_pull.rs @@ -71,7 +71,6 @@ pub struct TransitData { // extended lookup methods pub route_id_by_stops: HashMap>, pub stops_by_route_id: HashMap>, - pub platforms_by_route_id: HashMap>, pub stops_by_platform_id: HashMap>, } @@ -97,7 +96,6 @@ impl TransitData { platforms: HashMap::new(), route_id_by_stops: HashMap::new(), stops_by_route_id: HashMap::new(), - platforms_by_route_id: HashMap::new(), stops_by_platform_id: HashMap::new(), calendar_days: HashMap::new(), directions: HashMap::new(), @@ -208,16 +206,6 @@ impl GtfsPullService { .unwrap_or(&HashSet::new()) .clone() } - - pub fn get_platforms_by_route(&self, id: &String) -> HashSet { - let l_state = self.state.lock().unwrap(); - l_state - .transit_data - .platforms_by_route_id - .get(id) - .unwrap_or(&HashSet::new()) - .clone() - } pub fn get_stop_by_id(&self, id: &String) -> Option { let l_state = self.state.lock().unwrap(); @@ -543,13 +531,6 @@ impl GtfsPullService { .entry(global_rt_id.clone()) .or_insert(HashSet::new()) .insert(platform.id.clone()); - - state - .transit_data - .platforms_by_route_id - .entry(global_rt_id.clone()) - .or_insert(HashSet::new()) - .insert(platform.id.clone()); Some(libseptastic::stop_schedule::StopSchedule { arrival_time: i64::from(s.arrival_time?), diff --git a/web/src/templates.rs b/web/src/templates.rs index 3736b39..5d550c0 100644 --- a/web/src/templates.rs +++ b/web/src/templates.rs @@ -13,7 +13,6 @@ use std::{ }; use crate::controllers::stop::StopFilter; -use crate::routing::RouteStep; #[derive(askama::Template)] #[template(path = "layout.html")] @@ -94,12 +93,6 @@ pub struct StopTableTemplate { pub stop_id: String, } -#[derive(askama::Template)] -#[template(path = "routing.html")] -pub struct RoutingTemplate { - pub trips: Vec>, -} - #[derive(askama::Template)] #[template(path = "stop_search_results.html")] pub struct StopSearchResults { diff --git a/web/templates/routing.html b/web/templates/routing.html deleted file mode 100644 index e199e3e..0000000 --- a/web/templates/routing.html +++ /dev/null @@ -1,16 +0,0 @@ -{% for trip in trips %} -
- {% for step in trip %} - {% match step %} - {% when RouteStep::Walk(walk) %} -

Walk {{ walk.dist }}m to {{ walk.dest }}

- {% when RouteStep::Transit(transit) %} -

Ride {{transit.route}} to {{ transit.platform }}

- {% when RouteStep::Origin %} -

begin at origin

- {% when RouteStep::Destination %} -

arrive at destination

- {% endmatch %} - {% endfor %} -
-{% endfor %}