From 6989c72aa1ae721fbe36f59fec42704c56e5e299 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Sat, 19 Oct 2019 13:40:24 -0700 Subject: [PATCH] show location of all buses serving a route --- game/src/debug/bus_explorer.rs | 51 ++++++++++++++++++++++------------ sim/src/sim.rs | 16 +++++++++++ sim/src/transit.rs | 8 ++++++ 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/game/src/debug/bus_explorer.rs b/game/src/debug/bus_explorer.rs index 14f0b902c9..57b97d54ea 100644 --- a/game/src/debug/bus_explorer.rs +++ b/game/src/debug/bus_explorer.rs @@ -2,14 +2,17 @@ use crate::common::{CommonState, RoadColorer, RoadColorerBuilder}; use crate::game::{State, Transition, WizardState}; use crate::helpers::ID; use crate::ui::UI; -use ezgui::{Choice, Color, EventCtx, GfxCtx, Key, Line, ModalMenu, Text, WarpingItemSlider}; -use geom::Pt2D; -use map_model::{BusRoute, BusRouteID, BusStopID, Map, PathRequest, PathStep}; +use ezgui::{ + Choice, Color, EventCtx, GeomBatch, GfxCtx, Key, Line, ModalMenu, Text, WarpingItemSlider, +}; +use geom::{Circle, Distance, Pt2D}; +use map_model::{BusRoute, BusRouteID, BusStopID, PathRequest, PathStep}; pub struct BusRouteExplorer { slider: WarpingItemSlider, colorer: RoadColorer, - stop_labels: Vec<(Text, Pt2D)>, + labels: Vec<(Text, Pt2D)>, + bus_locations: Vec, } impl BusRouteExplorer { @@ -28,11 +31,7 @@ impl BusRouteExplorer { return None; } if routes.len() == 1 { - Some(Box::new(BusRouteExplorer::for_route( - routes[0], - &ui.primary.map, - ctx, - ))) + Some(Box::new(BusRouteExplorer::for_route(routes[0], ui, ctx))) } else { Some(make_bus_route_picker( routes.into_iter().map(|r| r.id).collect(), @@ -40,7 +39,8 @@ impl BusRouteExplorer { } } - fn for_route(route: &BusRoute, map: &Map, ctx: &mut EventCtx) -> BusRouteExplorer { + fn for_route(route: &BusRoute, ui: &UI, ctx: &mut EventCtx) -> BusRouteExplorer { + let map = &ui.primary.map; let stops: Vec<(Pt2D, BusStopID, Text)> = route .stops .iter() @@ -50,8 +50,14 @@ impl BusRouteExplorer { }) .collect(); - let mut colorer = - RoadColorerBuilder::new(Text::prompt(&route.name), vec![("route", Color::RED)]); + let mut bus_locations = Vec::new(); + for (_, pt) in ui.primary.sim.location_of_buses(route.id, map) { + bus_locations.push(pt); + } + + let mut txt = Text::prompt(&route.name); + txt.add(Line(format!("{} buses", bus_locations.len()))); + let mut colorer = RoadColorerBuilder::new(txt, vec![("route", Color::RED)]); for (stop1, stop2) in route .stops @@ -80,9 +86,9 @@ impl BusRouteExplorer { } } - let mut stop_labels = Vec::new(); + let mut labels = Vec::new(); for (idx, bs) in route.stops.iter().enumerate() { - stop_labels.push(( + labels.push(( Text::from(Line(format!("{}", idx + 1))), map.get_bs(*bs).sidewalk_pos.pt(map), )); @@ -96,7 +102,8 @@ impl BusRouteExplorer { ctx, ), colorer: colorer.build(ctx, map), - stop_labels, + labels, + bus_locations, } } } @@ -125,9 +132,17 @@ impl State for BusRouteExplorer { fn draw(&self, g: &mut GfxCtx, ui: &UI) { self.colorer.draw(g, ui); - for (label, pt) in &self.stop_labels { + for (label, pt) in &self.labels { g.draw_text_at(label, *pt); } + + let mut batch = GeomBatch::new(); + let radius = Distance::meters(20.0) / g.canvas.cam_zoom; + for pt in &self.bus_locations { + batch.push(Color::BLUE, Circle::new(*pt, radius).to_polygon()); + } + batch.draw(g); + self.slider.draw(g); CommonState::draw_osd(g, ui, &ui.primary.current_selection); } @@ -136,7 +151,7 @@ impl State for BusRouteExplorer { pub struct BusRoutePicker; impl BusRoutePicker { pub fn new(ui: &UI, menu: &mut ModalMenu) -> Option> { - if !menu.action("explore a bus route") { + if ui.primary.current_selection.is_some() || !menu.action("explore a bus route") { return None; } Some(make_bus_route_picker( @@ -166,7 +181,7 @@ fn make_bus_route_picker(routes: Vec) -> Box { })?; Some(Transition::Replace(Box::new(BusRouteExplorer::for_route( ui.primary.map.get_br(id), - &ui.primary.map, + ui, ctx, )))) })) diff --git a/sim/src/sim.rs b/sim/src/sim.rs index 4bf289c13d..a9dc6dab01 100644 --- a/sim/src/sim.rs +++ b/sim/src/sim.rs @@ -265,6 +265,10 @@ impl Sim { self.trips.abort_trip_failed_start(trip); } } + if results.is_empty() { + // TODO Bigger failure + timer.warn(format!("Failed to make ANY buses for {}!", route.name)); + } results } @@ -897,6 +901,18 @@ impl Sim { pub fn get_intersection_delays(&self, id: IntersectionID) -> &DurationHistogram { self.intersections.get_intersection_delays(id) } + + pub fn location_of_buses(&self, route: BusRouteID, map: &Map) -> Vec<(CarID, Pt2D)> { + let mut results = Vec::new(); + for car in self.transit.buses_for_route(route) { + // TODO This is a slow, indirect method! + results.push(( + car, + self.canonical_pt_for_agent(AgentID::Car(car), map).unwrap(), + )); + } + results + } } // Invasive debugging diff --git a/sim/src/transit.rs b/sim/src/transit.rs index d986ab57e4..2fe01f1d0f 100644 --- a/sim/src/transit.rs +++ b/sim/src/transit.rs @@ -241,4 +241,12 @@ impl TransitSimState { pub fn bus_route(&self, bus: CarID) -> BusRouteID { self.buses[&bus].route } + + pub fn buses_for_route(&self, route: BusRouteID) -> Vec { + if let Some(ref r) = self.routes.get(&route) { + r.buses.clone() + } else { + Vec::new() + } + } }