plot elevation over time for bikes and peds, guarded behind dev mode

This commit is contained in:
Dustin Carlino 2020-03-15 12:47:14 -07:00
parent 4accd788f2
commit 64082501eb

View File

@ -13,7 +13,7 @@ use ezgui::{
VerticalAlignment,
};
use geom::{Angle, Circle, Distance, Duration, Polygon, Pt2D, Statistic, Time};
use map_model::{BuildingID, IntersectionID, IntersectionType};
use map_model::{BuildingID, IntersectionID, IntersectionType, Map, Path, PathStep};
use sim::{
AgentID, Analytics, CarID, PersonID, PersonState, TripEnd, TripID, TripMode, TripPhaseType,
TripResult, TripStart, VehicleType,
@ -446,6 +446,7 @@ fn info_for(
));
}
// TODO Simplify and expose everywhere after there's better data
kv.push((
"Elevation change".to_string(),
format!(
@ -454,6 +455,18 @@ fn info_for(
map.get_i(l.dst_i).elevation
),
));
kv.push((
"Incline / grade".to_string(),
format!("{:.1}%", l.percent_grade(map) * 100.0),
));
kv.push((
"Elevation details".to_string(),
format!(
"{} over {}",
map.get_i(l.dst_i).elevation - map.get_i(l.src_i).elevation,
l.length()
),
));
for (k, v) in &r.osm_tags {
kv.push((k.to_string(), v.to_string()));
@ -1127,6 +1140,7 @@ fn trip_details(
let total_width = 0.3 * ctx.canvas.window_width;
let mut timeline = Vec::new();
let num_phases = phases.len();
let mut elevation = Vec::new();
for (idx, p) in phases.into_iter().enumerate() {
let color = match p.phase_type {
TripPhaseType::Driving => Color::hex("#D63220"),
@ -1215,6 +1229,18 @@ fn trip_details(
// TODO Could really cache this between live updates
if let Some((dist, ref path)) = p.path {
if app.opts.dev
&& (p.phase_type == TripPhaseType::Walking || p.phase_type == TripPhaseType::Biking)
{
elevation.push(make_elevation(
ctx,
color,
p.phase_type == TripPhaseType::Walking,
path,
map,
));
}
if let Some(trace) = path.trace(map, dist, None) {
unzoomed.push(color, trace.make_polygons(Distance::meters(10.0)));
zoomed.extend(
@ -1244,6 +1270,7 @@ fn trip_details(
.evenly_spaced()
.margin_above(25)];
col.extend(make_table(ctx, table));
col.extend(elevation);
if let Some(p) = app.primary.sim.trip_to_person(trip) {
col.push(
ManagedWidget::btn(Button::text_bg(
@ -1318,3 +1345,45 @@ fn strip_prefix_usize(x: &String, prefix: &str) -> Option<usize> {
None
}
}
fn make_elevation(
ctx: &EventCtx,
color: Color,
walking: bool,
path: &Path,
map: &Map,
) -> ManagedWidget {
let mut pts: Vec<(Distance, Distance)> = Vec::new();
let mut dist = Distance::ZERO;
for step in path.get_steps() {
if let PathStep::Turn(t) = step {
pts.push((dist, map.get_i(t.parent).elevation));
}
dist += step.as_traversable().length(map);
}
// TODO Plot needs to support Distance as both X and Y axis. :P
// TODO Show roughly where we are in the trip; use distance covered by current path for this
Plot::new_usize(
ctx,
vec![Series {
label: if walking {
"Elevation for walking"
} else {
"Elevation for biking"
}
.to_string(),
color,
pts: pts
.into_iter()
.map(|(x, y)| {
(
Time::START_OF_DAY + Duration::seconds(x.inner_meters()),
y.inner_meters() as usize,
)
})
.collect(),
}],
PlotOptions::new(),
)
.bg(colors::PANEL_BG)
}