actually add map files + reduce usage of unwrap
Some checks failed
Create and publish a Docker image / build-and-push-image (push) Failing after 4m52s

This commit is contained in:
Nicholas Orlowsky 2026-04-19 22:54:49 -04:00
parent 0698373151
commit 8a17159524
No known key found for this signature in database
GPG key ID: A9F3BA4C0AA7A70B
3 changed files with 195 additions and 70 deletions

View file

@ -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<Arc<AppState>>, 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
)
}

View file

@ -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,11 +299,16 @@ impl GtfsPullService {
if stop.1.latitude == None || stop.1.longitude == None {
continue;
}
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: stop.1.name.clone().unwrap(),
lat: stop.1.latitude.unwrap(),
lng: stop.1.longitude.unwrap(),
name: name.clone(),
lat,
lng,
platform_location: libseptastic::stop::PlatformLocationType::Normal,
});
@ -318,7 +322,7 @@ impl GtfsPullService {
let stop = Arc::new(libseptastic::stop::Stop {
id: global_id.clone(),
name: stop.1.name.clone().unwrap(),
name: name.clone(),
platforms: libseptastic::stop::StopType::SinglePlatform(platform.clone()),
});
@ -335,15 +339,23 @@ impl GtfsPullService {
.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);
}
}
for pair in &map {
let parent_stop = state.transit_data.stops.get(pair.0).unwrap().clone();
//let child_stop: Vec<libseptastic::stop::Stop> = 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()
}
);
}
@ -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,

36
web/templates/map.html Normal file
View file

@ -0,0 +1,36 @@
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""></script>
<style>
#map { height: 750px; width: 100%; }
</style>
<div id="map"></div>
<script>
var map = L.map('map').setView([39.952583, -75.165222], 9);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
{% for loc in locations %}
{
var icon = L.divIcon({
html: '<span style="background-color: #eee; padding: 2px;">{{ loc.2 }}</span>', // Your text here
className: 'text-label', // Custom CSS class
//iconSize: [100, 40], // Optional: Define size
//iconAnchor: [50, 20] // Optional: Center the text over the point
});
var marker = L.marker([{{loc.0}}, {{loc.1}}], {icon: icon}).addTo(map);
marker.bindPopup("{{ loc.2 }}")
}
{% endfor %}
</script>