Add elevation details to routing results

This commit is contained in:
Dustin Carlino 2021-08-23 18:02:29 -07:00
parent a05a4f534c
commit 7e3802a519
3 changed files with 60 additions and 12 deletions

View File

@ -893,14 +893,6 @@ fn make_elevation(ctx: &EventCtx, color: Color, walking: bool, path: &Path, map:
dist += step.as_traversable().get_polyline(map).length(); dist += step.as_traversable().get_polyline(map).length();
} }
// TODO Cache this value?
let max_elevation = map
.all_intersections()
.iter()
.max_by_key(|i| i.elevation)
.unwrap()
.elevation;
// TODO Show roughly where we are in the trip; use distance covered by current path for this // TODO Show roughly where we are in the trip; use distance covered by current path for this
LinePlot::new_widget( LinePlot::new_widget(
ctx, ctx,
@ -921,7 +913,7 @@ fn make_elevation(ctx: &EventCtx, color: Color, walking: bool, path: &Path, map:
// If we use the max elevation encountered along the route, then no matter how we // If we use the max elevation encountered along the route, then no matter how we
// round, there are always edge cases where the scale will jump. So just use the // round, there are always edge cases where the scale will jump. So just use the
// maximum elevation from the entire map. // maximum elevation from the entire map.
max_y: Some(max_elevation.round_up_for_axis()), max_y: Some(map.max_elevation().round_up_for_axis()),
disabled: HashSet::new(), disabled: HashSet::new(),
}, },
) )

View File

@ -1,13 +1,15 @@
use std::collections::HashSet;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use rand::SeedableRng; use rand::SeedableRng;
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
use geom::{Circle, Distance, Duration, FindClosest, Polygon}; use geom::{Circle, Distance, Duration, FindClosest, Polygon};
use map_model::NORMAL_LANE_THICKNESS; use map_model::{PathStep, NORMAL_LANE_THICKNESS};
use sim::{TripEndpoint, TripMode}; use sim::{TripEndpoint, TripMode};
use widgetry::{ use widgetry::{
Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, LinePlot,
State, Text, TextExt, VerticalAlignment, Widget, Outcome, Panel, PlotOptions, Series, State, Text, TextExt, VerticalAlignment, Widget,
}; };
use crate::app::{App, Transition}; use crate::app::{App, Transition};
@ -167,6 +169,9 @@ impl RoutePlanner {
let mut total_distance = Distance::ZERO; let mut total_distance = Distance::ZERO;
let mut total_time = Duration::ZERO; let mut total_time = Duration::ZERO;
let mut elevation_pts: Vec<(Distance, Distance)> = Vec::new();
let mut current_dist = Distance::ZERO;
for pair in self.waypoints.windows(2) { for pair in self.waypoints.windows(2) {
if let Some((path, draw_path)) = if let Some((path, draw_path)) =
TripEndpoint::path_req(pair[0].at, pair[1].at, TripMode::Bike, map) TripEndpoint::path_req(pair[0].at, pair[1].at, TripMode::Bike, map)
@ -179,11 +184,29 @@ impl RoutePlanner {
batch.push(Color::CYAN, draw_path); batch.push(Color::CYAN, draw_path);
total_distance += path.total_length(); total_distance += path.total_length();
total_time += path.estimate_duration(map, Some(map_model::MAX_BIKE_SPEED)); total_time += path.estimate_duration(map, Some(map_model::MAX_BIKE_SPEED));
for step in path.get_steps() {
if let PathStep::Turn(t) = step {
elevation_pts.push((current_dist, map.get_i(t.parent).elevation));
}
current_dist += step.as_traversable().get_polyline(map).length();
}
} }
} }
self.draw_route = ctx.upload(batch); self.draw_route = ctx.upload(batch);
let mut total_up = Distance::ZERO;
let mut total_down = Distance::ZERO;
for pair in elevation_pts.windows(2) {
let dy = pair[1].1 - pair[0].1;
if dy < Distance::ZERO {
total_down -= dy;
} else {
total_up += dy;
}
}
self.results_panel = Panel::new_builder(Widget::col(vec![ self.results_panel = Panel::new_builder(Widget::col(vec![
Line("Your route").small_heading().into_widget(ctx), Line("Your route").small_heading().into_widget(ctx),
Text::from_all(vec![ Text::from_all(vec![
@ -196,6 +219,29 @@ impl RoutePlanner {
Line(total_time.to_string(&app.opts.units)), Line(total_time.to_string(&app.opts.units)),
]) ])
.into_widget(ctx), .into_widget(ctx),
Text::from_all(vec![
Line("Elevation change: ").secondary(),
Line(format!(
"{}↑, {}↓",
total_up.to_string(&app.opts.units),
total_down.to_string(&app.opts.units)
)),
])
.into_widget(ctx),
LinePlot::new_widget(
ctx,
vec![Series {
label: "Elevation".to_string(),
color: Color::RED,
pts: elevation_pts,
}],
PlotOptions {
filterable: false,
max_x: Some(current_dist.round_up_for_axis()),
max_y: Some(map.max_elevation().round_up_for_axis()),
disabled: HashSet::new(),
},
),
])) ]))
.aligned(HorizontalAlignment::Right, VerticalAlignment::Top) .aligned(HorizontalAlignment::Right, VerticalAlignment::Top)
.build(ctx); .build(ctx);

View File

@ -789,4 +789,14 @@ impl Map {
} }
None None
} }
/// Returns the highest elevation in the map
pub fn max_elevation(&self) -> Distance {
// TODO Cache?
self.all_intersections()
.iter()
.max_by_key(|i| i.elevation)
.unwrap()
.elevation
}
} }