diff --git a/web/src/controllers/map.rs b/web/src/controllers/map.rs new file mode 100644 index 0000000..322ae86 --- /dev/null +++ b/web/src/controllers/map.rs @@ -0,0 +1,52 @@ +use crate::{ + AppState, services::trip_tracking, session_middleware::{SessionResponder, SessionResponse}, templates::{MapTemplate, TripPerspective} +}; +use actix_web::{ + HttpResponse, Responder, get, post, web::{self, Data} +}; +use askama::Template; +use chrono::{TimeDelta, Timelike}; +use chrono_tz::America::New_York; +use libseptastic::{stop::Stop, stop_schedule::{LiveTrip, SeatAvailability, Trip, TripTracking}}; +use serde::{Deserialize, Serialize}; +use serde_qs::actix::QsQuery; +use std::{ + collections::{BTreeSet, HashSet}, default, sync::Arc +}; + + +#[get("/map")] +async fn get_map_element_html(state: Data>, resp: SessionResponse) -> impl Responder { + + let mut trips = state + .gtfs_service + .get_all_trips() + .iter() + .filter_map(|trip| { + Some(trip.1.clone()) + }) + .flatten() + .collect(); + + + state.trip_tracking_service.annotate_trips(&mut trips).await; + + let mut locations = vec![]; + + for other in trips { + if let libseptastic::stop_schedule::TripTracking::Tracked(td) = other.tracking_data { + if let Some(lat) = td.latitude && let Some(lng) = td.longitude { + locations.push((lat, lng, td.route_id)); + } + } + } + + let mt: MapTemplate = MapTemplate { + locations + }; + + resp.respond( + "","", + mt + ) +} diff --git a/web/src/services/gtfs_pull.rs b/web/src/services/gtfs_pull.rs index 31779a9..b120ac8 100644 --- a/web/src/services/gtfs_pull.rs +++ b/web/src/services/gtfs_pull.rs @@ -243,28 +243,27 @@ impl GtfsPullService { platform_id.clone(), annotated_stop.id.clone() ); + let platform = match state .transit_data .stops - .remove(platform_id) - .unwrap() + .remove(platform_id)? .platforms .clone() { - libseptastic::stop::StopType::SinglePlatform(plat) => Ok(plat), - _ => Err(anyhow!("")), - } - .unwrap(); + libseptastic::stop::StopType::SinglePlatform(plat) => Some(plat), + _ => None, + }?; state .transit_data .stops_by_platform_id - .remove(&platform.id) - .unwrap(); + .remove(&platform.id)?; - platform + Some(platform) }) - .collect(), + .flatten() + .collect() ), }); @@ -300,51 +299,64 @@ impl GtfsPullService { if stop.1.latitude == None || stop.1.longitude == None { continue; } - let platform = Arc::new(Platform { - id: global_id.clone(), - name: stop.1.name.clone().unwrap(), - lat: stop.1.latitude.unwrap(), - lng: stop.1.longitude.unwrap(), - platform_location: libseptastic::stop::PlatformLocationType::Normal, - }); - if let Some(parent) = &stop.1.parent_station { - let parent_global_id = make_global_id!(prefix, parent); - if !state.annotations.parent_stop_blacklist.contains(&parent_global_id) { - map.entry(parent_global_id) - .or_insert(vec![]).push(global_id.clone()); + if let Some(lat) = stop.1.latitude && + let Some(lng) = stop.1.longitude && + let Some(name) = stop.1.name.clone() { + + let platform = Arc::new(Platform { + id: global_id.clone(), + name: name.clone(), + lat, + lng, + platform_location: libseptastic::stop::PlatformLocationType::Normal, + }); + + if let Some(parent) = &stop.1.parent_station { + let parent_global_id = make_global_id!(prefix, parent); + if !state.annotations.parent_stop_blacklist.contains(&parent_global_id) { + map.entry(parent_global_id) + .or_insert(vec![]).push(global_id.clone()); + } } + + let stop = Arc::new(libseptastic::stop::Stop { + id: global_id.clone(), + name: name.clone(), + platforms: libseptastic::stop::StopType::SinglePlatform(platform.clone()), + }); + + + state + .transit_data + .stops + .insert(global_id.clone(), stop.clone()); + state + .transit_data + .platforms + .insert(global_id.clone(), platform.clone()); + state + .transit_data + .stops_by_platform_id + .insert(global_id.clone(), stop.clone()); + } else { + info!("Stop {} does not have all of latitude, longitude, and/or name", stop.1.id); } - - let stop = Arc::new(libseptastic::stop::Stop { - id: global_id.clone(), - name: stop.1.name.clone().unwrap(), - platforms: libseptastic::stop::StopType::SinglePlatform(platform.clone()), - }); - - - state - .transit_data - .stops - .insert(global_id.clone(), stop.clone()); - state - .transit_data - .platforms - .insert(global_id.clone(), platform.clone()); - state - .transit_data - .stops_by_platform_id - .insert(global_id.clone(), stop.clone()); } for pair in &map { - let parent_stop = state.transit_data.stops.get(pair.0).unwrap().clone(); - //let child_stop: Vec = pair.1.iter().map(|stop_id| { - // state.transit_data.stops.get(stop_id).unwrap().clone() - //}).collect(); + let parent_stop = match state.transit_data.stops.get(pair.0) { + Some(x) => x, + None => continue + }.clone(); + state.annotations.multiplatform_stops.push( - MultiplatformStopConfig { id: parent_stop.id.clone(), name: parent_stop.name.clone(), platform_station_ids: pair.1.clone() } - ); + MultiplatformStopConfig { + id: parent_stop.id.clone(), + name: parent_stop.name.clone(), + platform_station_ids: pair.1.clone() + } + ); } Ok(()) @@ -417,15 +429,25 @@ impl GtfsPullService { let global_rt_id = make_global_id!(prefix, trip.1.route_id); let dir = libseptastic::direction::Direction { - direction: match trip.1.direction_id.unwrap() { - gtfs_structures::DirectionType::Outbound => { + direction: match trip.1.direction_id { + Some(gtfs_structures::DirectionType::Outbound) => { libseptastic::direction::CardinalDirection::Outbound } - gtfs_structures::DirectionType::Inbound => { + Some(gtfs_structures::DirectionType::Inbound) => { libseptastic::direction::CardinalDirection::Inbound + }, + None => { + error!("Direction not found for trip {}", trip.1.id); + continue } }, - direction_destination: trip.1.trip_headsign.clone().unwrap(), + direction_destination: match trip.1.trip_headsign.clone() { + Some(x) => x, + None => { + error!("No direction destination found for trip {}", trip.1.id); + continue + } + } }; match state.transit_data.directions.entry(global_rt_id) { @@ -475,14 +497,13 @@ impl GtfsPullService { let stop = state .transit_data .stops_by_platform_id - .get(&global_stop_id) - .unwrap() + .get(&global_stop_id)? .clone(); + let platform = state .transit_data .platforms - .get(&global_stop_id) - .unwrap() + .get(&global_stop_id)? .clone(); state @@ -511,13 +532,14 @@ impl GtfsPullService { .or_insert(HashSet::new()) .insert(platform.id.clone()); - libseptastic::stop_schedule::StopSchedule { - arrival_time: i64::from(s.arrival_time.unwrap()), + Some(libseptastic::stop_schedule::StopSchedule { + arrival_time: i64::from(s.arrival_time?), stop_sequence: i64::from(s.stop_sequence), stop, platform, - } + }) }) + .flatten() .collect(); if let Some(calendar_day) = state @@ -527,22 +549,37 @@ impl GtfsPullService { { let trip = libseptastic::stop_schedule::Trip { trip_id: trip.1.id.clone(), - route: state + route: match state .transit_data .routes .get(&make_global_id!(prefix, trip.1.route_id)) - .unwrap() - .clone(), - direction: libseptastic::direction::Direction { - direction: match trip.1.direction_id.unwrap() { - gtfs_structures::DirectionType::Outbound => { - libseptastic::direction::CardinalDirection::Outbound - } - gtfs_structures::DirectionType::Inbound => { - libseptastic::direction::CardinalDirection::Inbound + .clone() { + Some(x) => x, + None => { + warn!("No route found for trip {} (was looking for route {})", trip.1.id, trip.1.route_id); + continue + } + }, + direction: libseptastic::direction::Direction { + direction: match trip.1.direction_id { + Some(gtfs_structures::DirectionType::Outbound) => { + libseptastic::direction::CardinalDirection::Outbound + }, + Some(gtfs_structures::DirectionType::Inbound) => { + libseptastic::direction::CardinalDirection::Inbound + }, + None => { + warn!("No direction found for trip {}", trip.1.id); + continue + } + }, + direction_destination: match trip.1.trip_headsign.clone() { + Some(x) => x, + None => { + warn!("No headsign found for trip {}", trip.1.id); + continue } }, - direction_destination: trip.1.trip_headsign.clone().unwrap(), }, tracking_data: libseptastic::stop_schedule::TripTracking::Untracked, schedule: sched, diff --git a/web/templates/map.html b/web/templates/map.html new file mode 100644 index 0000000..d8b5380 --- /dev/null +++ b/web/templates/map.html @@ -0,0 +1,36 @@ + + + + + + +
+ +