Initial implementation of 'next arrivals'. Needs more work.
This commit is contained in:
parent
c83ac39bac
commit
431f21a8b8
|
|
@ -8,6 +8,7 @@ host = "x86_64-unknown-linux-gnu"
|
|||
sdl3 = {version = "0.17", features = ["ttf"]}
|
||||
serde = "1.0"
|
||||
gtfs-structures = "0.47"
|
||||
chrono = "*"
|
||||
zip = "8.3"
|
||||
csv = "1.4"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
mod loader;
|
||||
mod utils;
|
||||
pub mod structs;
|
||||
use chrono::{DateTime, Local, NaiveDate, NaiveDateTime};
|
||||
use std::{
|
||||
collections::{HashMap},
|
||||
collections::{HashMap, HashSet},
|
||||
fs::File,
|
||||
};
|
||||
use gtfs_structures::{Agency, Calendar, CalendarDate, RawStopTime, RawTrip, Route, Stop, TimepointType};
|
||||
use gtfs_structures::{Agency, Calendar, CalendarDate, Exception, RawStopTime, RawTrip, Route, Stop, TimepointType, Trip};
|
||||
|
||||
use crate::gtfs::{loader::load_gtfs, structs::{Arrival, Preferences}};
|
||||
|
||||
|
|
@ -31,11 +32,64 @@ pub struct Gtfs {
|
|||
|
||||
impl Gtfs {
|
||||
|
||||
pub fn _get_next_stops(&self) -> Vec<Arrival<'_>> {
|
||||
let arrivals = Vec::<Arrival>::new();
|
||||
pub fn get_next_arrivals_for(&self, target_datetime: &DateTime<Local>) -> Box<Vec<Arrival>> {
|
||||
let naive_target = target_datetime.naive_local();
|
||||
let target_date = naive_target.date();
|
||||
|
||||
// Find which calendars apply
|
||||
let mut active_service_ids: HashSet<String> = HashSet::new();
|
||||
for (id, calendar) in self.calendar.iter() {
|
||||
if calendar.valid_weekday(target_date)
|
||||
&& calendar.start_date <= target_date
|
||||
&& calendar.end_date > target_date {
|
||||
active_service_ids.insert(id.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// Are there any exceptions for the calendars above?
|
||||
for (_calendar_id, exceptions) in self.calendar_dates.iter() {
|
||||
for exception in exceptions.iter() {
|
||||
if exception.date.eq(&target_date) {
|
||||
match exception.exception_type {
|
||||
Exception::Added => {
|
||||
active_service_ids.insert(exception.service_id.clone());
|
||||
}
|
||||
Exception::Deleted => {
|
||||
active_service_ids.remove(&exception.service_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the trips happening on these calendars
|
||||
let mut trips: HashMap<&String, &RawTrip> = HashMap::new();
|
||||
for (id, trip) in self.trips.iter() {
|
||||
if active_service_ids.contains(&trip.service_id) {
|
||||
trips.insert(&trip.id, trip);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, find the arrivals for the active trips on the chosen stops
|
||||
let mut arrivals: Vec<Arrival> = Vec::new();
|
||||
let current_timestamp = target_datetime.timestamp();
|
||||
for (id, stop_time) in self.stop_times.iter() {
|
||||
if trips.contains_key(&stop_time.trip_id) {
|
||||
let stop_timestamp = stop_time.departure_time.or(stop_time.arrival_time).unwrap();
|
||||
if current_timestamp < stop_timestamp.into() {
|
||||
let arrival: Arrival = Arrival {
|
||||
route: self.routes.get(&self.trips.get(&stop_time.trip_id).unwrap().route_id).unwrap(),
|
||||
stop: self.stops.get(&stop_time.stop_id).unwrap(),
|
||||
departure_time: stop_timestamp
|
||||
};
|
||||
arrivals.push(arrival);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Box::from(arrivals);
|
||||
}
|
||||
|
||||
return arrivals;
|
||||
}
|
||||
|
||||
/// Load a GTFS structure from a zip file
|
||||
pub fn load(src_file: &str, prefs: &Preferences) -> Gtfs {
|
||||
|
|
@ -53,9 +107,8 @@ impl Gtfs {
|
|||
};
|
||||
|
||||
|
||||
load_gtfs(&mut gtfs, &mut zip_reader, &prefs.route_numbers, &prefs.stop_codes);
|
||||
|
||||
return gtfs;
|
||||
}
|
||||
load_gtfs(&mut gtfs, &mut zip_reader, &prefs.route_numbers, &prefs.stop_codes);
|
||||
|
||||
return gtfs;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,9 +8,10 @@ pub struct Preferences {
|
|||
pub stop_codes: HashSet<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
pub struct Arrival<'a> {
|
||||
pub route: &'a Route,
|
||||
pub stop: &'a Stop,
|
||||
pub timepoint: &'a TimepointType,
|
||||
pub departure_time: u32,
|
||||
}
|
||||
22
src/main.rs
22
src/main.rs
|
|
@ -1,14 +1,18 @@
|
|||
mod gtfs;
|
||||
mod renderer;
|
||||
use std::{collections::HashSet, os, process, thread, time::Duration};
|
||||
use sdl3::{EventPump, event::{self, Event, EventWatchCallback}, sys::init::SDL_Quit};
|
||||
use std::{collections::HashSet, process, thread, time::SystemTime};
|
||||
use chrono::{DateTime, Local};
|
||||
use sdl3::event::Event;
|
||||
|
||||
use crate::{gtfs::Gtfs, renderer::Screen};
|
||||
|
||||
const SRC_FILE: &str = "/home/nahuel/Downloads/GTFS_Realtime.zip";
|
||||
|
||||
|
||||
fn refresh_thread() {
|
||||
|
||||
fn refresh_schedule(gtfs: &Gtfs) {
|
||||
let current_timestamp = SystemTime::now();
|
||||
let datetime: DateTime<Local> = current_timestamp.clone().into();
|
||||
let next_arrivals = gtfs.get_next_arrivals_for(&datetime);
|
||||
print!("Next arrivals: {:#?}", next_arrivals);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -27,15 +31,17 @@ fn main() {
|
|||
|
||||
// Init GTFS static info
|
||||
println!("Loading GTFS data...");
|
||||
//let _gtfs = Gtfs::load(SRC_FILE, >fs_prefs);
|
||||
let gtfs = Gtfs::load(SRC_FILE, >fs_prefs);
|
||||
|
||||
// Init screen
|
||||
println!("Initializing screen...");
|
||||
let mut screen = Screen::init(&screen_prefs);
|
||||
let screen = Screen::init(&screen_prefs);
|
||||
println!("Startup done.");
|
||||
|
||||
// Start an asynchronous refresh thread
|
||||
let _update_thread = thread::Builder::new().name("updater".to_string()).spawn(refresh_thread);
|
||||
//let _update_thread = thread::Builder::new().name("updater".to_string()).spawn(move || { refresh_schedule(>fs) });
|
||||
|
||||
refresh_schedule(>fs);
|
||||
|
||||
// Main event loop
|
||||
let mut event_pump = screen.get_context().event_pump().unwrap();
|
||||
|
|
|
|||
Loading…
Reference in New Issue