Just rearrange code, in preparation for merging edit mode and the main explore map mode

This commit is contained in:
Dustin Carlino 2021-08-07 10:35:54 -07:00
parent 22dfb616a3
commit b59419ea84
5 changed files with 148 additions and 138 deletions

View File

@ -2,8 +2,8 @@ use geom::Distance;
use map_gui::ID;
use map_model::{EditCmd, LaneType};
use widgetry::{
lctrl, Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, Outcome,
Panel, State, TextExt, VerticalAlignment, Widget,
lctrl, Drawable, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, State,
TextExt, VerticalAlignment, Widget,
};
use crate::app::{App, Transition};
@ -12,8 +12,6 @@ use crate::edit::{LoadEdits, RoadEditor, SaveEdits};
use crate::sandbox::gameplay::GameplayMode;
use crate::ungap::magnifying::MagnifyingGlass;
const EDITED_COLOR: Color = Color::CYAN;
pub struct QuickEdit {
top_panel: Panel,
network_layer: Drawable,
@ -32,8 +30,8 @@ impl QuickEdit {
Box::new(QuickEdit {
top_panel: make_top_panel(ctx, app),
magnifying_glass: MagnifyingGlass::new(ctx, false),
network_layer: crate::ungap::render_network_layer(ctx, app),
edits_layer: render_edits(ctx, app),
network_layer: crate::ungap::layers::render_network_layer(ctx, app),
edits_layer: crate::ungap::layers::render_edits(ctx, app),
changelist_key: (edits.edits_name.clone(), edits.commands.len()),
})
@ -48,7 +46,7 @@ impl State<App> for QuickEdit {
if self.changelist_key != changelist_key {
self.changelist_key = changelist_key;
self.network_layer = crate::ungap::render_network_layer(ctx, app);
self.edits_layer = render_edits(ctx, app);
self.edits_layer = crate::ungap::layers::render_edits(ctx, app);
self.top_panel = make_top_panel(ctx, app);
}
}
@ -178,7 +176,11 @@ fn make_top_panel(ctx: &mut EventCtx, app: &App) -> Panel {
.secondary()
.into_widget(ctx),
);
file_management.push(crate::ungap::legend(ctx, EDITED_COLOR, "changed road"));
file_management.push(crate::ungap::legend(
ctx,
*crate::ungap::layers::EDITED_COLOR,
"changed road",
));
file_management.push(Widget::row(vec![
ctx.style()
.btn_outline
@ -218,15 +220,3 @@ fn make_top_panel(ctx: &mut EventCtx, app: &App) -> Panel {
.aligned(HorizontalAlignment::Center, VerticalAlignment::Top)
.build(ctx)
}
pub fn render_edits(ctx: &mut EventCtx, app: &App) -> Drawable {
let mut batch = GeomBatch::new();
let map = &app.primary.map;
for r in &map.get_edits().changed_roads {
batch.push(
EDITED_COLOR.alpha(0.5),
map.get_r(*r).get_thick_polygon(map),
);
}
batch.upload(ctx)
}

125
game/src/ungap/layers.rs Normal file
View File

@ -0,0 +1,125 @@
use geom::{Circle, Distance, Pt2D};
use map_model::{LaneType, PathConstraints, Road};
use widgetry::{Color, Drawable, EventCtx, GeomBatch, Widget};
use crate::app::App;
lazy_static::lazy_static! {
pub static ref DEDICATED_TRAIL: Color = Color::GREEN;
pub static ref PROTECTED_BIKE_LANE: Color = Color::hex("#A4DE02");
pub static ref PAINTED_BIKE_LANE: Color = Color::hex("#76BA1B");
pub static ref GREENWAY: Color = Color::hex("#4C9A2A");
pub static ref EDITED_COLOR: Color = Color::CYAN;
}
pub fn legend(ctx: &mut EventCtx, color: Color, label: &str) -> Widget {
let radius = 15.0;
Widget::row(vec![
GeomBatch::from(vec![(
color,
Circle::new(Pt2D::new(radius, radius), Distance::meters(radius)).to_polygon(),
)])
.into_widget(ctx)
.centered_vert(),
ctx.style()
.btn_plain
.text(label)
.build_def(ctx)
.centered_vert(),
])
}
pub fn render_network_layer(ctx: &mut EventCtx, app: &App) -> Drawable {
let mut batch = GeomBatch::new();
// The basemap colors are beautiful, but we want to emphasize the bike network, so all's foggy
// in love and war...
batch.push(
Color::BLACK.alpha(0.4),
app.primary.map.get_boundary_polygon().clone(),
);
for r in app.primary.map.all_roads() {
if r.is_cycleway() {
batch.push(*DEDICATED_TRAIL, r.get_thick_polygon(&app.primary.map));
continue;
}
if is_greenway(r) {
batch.push(*GREENWAY, r.get_thick_polygon(&app.primary.map));
}
// Don't cover up the arterial/local classification -- add thick side lines to show bike
// facilties in each direction.
let mut bike_lane_left = false;
let mut buffer_left = false;
let mut bike_lane_right = false;
let mut buffer_right = false;
let mut on_left = true;
for (_, _, lt) in r.lanes_ltr() {
if lt == LaneType::Driving || lt == LaneType::Bus {
// We're walking the lanes from left-to-right. So as soon as we hit a vehicle lane,
// any bike lane we find is on the right side of the road.
// (Barring really bizarre things like a bike lane in the middle of the road)
on_left = false;
} else if lt == LaneType::Biking {
if on_left {
bike_lane_left = true;
} else {
bike_lane_right = true;
}
} else if matches!(lt, LaneType::Buffer(_)) {
if on_left {
buffer_left = true;
} else {
buffer_right = true;
}
}
let half_width = r.get_half_width(&app.primary.map);
for (shift, bike_lane, buffer) in [
(-1.0, bike_lane_left, buffer_left),
(1.0, bike_lane_right, buffer_right),
] {
let color = if bike_lane && buffer {
*PROTECTED_BIKE_LANE
} else if bike_lane {
*PAINTED_BIKE_LANE
} else {
// If we happen to have a buffer, but no bike lane, let's just not ask
// questions...
continue;
};
if let Ok(pl) = r.center_pts.shift_either_direction(shift * half_width) {
batch.push(color, pl.make_polygons(0.9 * half_width));
}
}
}
}
batch.upload(ctx)
}
// TODO Check how other greenways are tagged.
// https://www.openstreetmap.org/way/262778812 has bicycle=designated, cycleway=shared_lane...
pub fn is_greenway(road: &Road) -> bool {
!road
.access_restrictions
.allow_through_traffic
.contains(PathConstraints::Car)
&& road
.access_restrictions
.allow_through_traffic
.contains(PathConstraints::Bike)
}
pub fn render_edits(ctx: &mut EventCtx, app: &App) -> Drawable {
let mut batch = GeomBatch::new();
let map = &app.primary.map;
for r in &map.get_edits().changed_roads {
batch.push(
EDITED_COLOR.alpha(0.5),
map.get_r(*r).get_thick_polygon(map),
);
}
batch.upload(ctx)
}

View File

@ -1,28 +1,22 @@
mod edit;
mod layers;
mod magnifying;
mod nearby;
mod quick_sketch;
use abstutil::prettyprint_usize;
use geom::{Circle, Distance, Pt2D};
use geom::Distance;
use map_gui::tools::{nice_map_name, CityPicker, PopupMsg};
use map_model::{LaneType, PathConstraints, Road};
use widgetry::{
lctrl, Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key, Line, Outcome,
Panel, State, Text, Toggle, VerticalAlignment, Widget,
lctrl, Drawable, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, State, Text,
Toggle, VerticalAlignment, Widget,
};
use self::layers::{legend, render_network_layer};
use self::magnifying::MagnifyingGlass;
use self::nearby::Nearby;
use crate::app::{App, Transition};
use crate::common::Warping;
use magnifying::MagnifyingGlass;
use nearby::Nearby;
lazy_static::lazy_static! {
static ref DEDICATED_TRAIL: Color = Color::GREEN;
static ref PROTECTED_BIKE_LANE: Color = Color::hex("#A4DE02");
static ref PAINTED_BIKE_LANE: Color = Color::hex("#76BA1B");
static ref GREENWAY: Color = Color::hex("#4C9A2A");
}
pub struct ExploreMap {
top_panel: Panel,
@ -258,10 +252,10 @@ fn make_legend(ctx: &mut EventCtx, app: &App, elevation: bool, nearby: bool) ->
legend(ctx, app.cs.unzoomed_highway, "highway"),
legend(ctx, app.cs.unzoomed_arterial, "major street"),
legend(ctx, app.cs.unzoomed_residential, "minor street"),
legend(ctx, *DEDICATED_TRAIL, "trail"),
legend(ctx, *PROTECTED_BIKE_LANE, "protected bike lane"),
legend(ctx, *PAINTED_BIKE_LANE, "painted bike lane"),
legend(ctx, *GREENWAY, "Stay Healthy Street / greenway"),
legend(ctx, *layers::DEDICATED_TRAIL, "trail"),
legend(ctx, *layers::PROTECTED_BIKE_LANE, "protected bike lane"),
legend(ctx, *layers::PAINTED_BIKE_LANE, "painted bike lane"),
legend(ctx, *layers::GREENWAY, "Stay Healthy Street / greenway"),
// TODO Distinguish door-zone bike lanes?
// TODO Call out bike turning boxes?
// TODO Call out bike signals?
@ -293,102 +287,3 @@ fn make_legend(ctx: &mut EventCtx, app: &App, elevation: bool, nearby: bool) ->
.aligned(HorizontalAlignment::Right, VerticalAlignment::Bottom)
.build(ctx)
}
pub fn legend(ctx: &mut EventCtx, color: Color, label: &str) -> Widget {
let radius = 15.0;
Widget::row(vec![
GeomBatch::from(vec![(
color,
Circle::new(Pt2D::new(radius, radius), Distance::meters(radius)).to_polygon(),
)])
.into_widget(ctx)
.centered_vert(),
ctx.style()
.btn_plain
.text(label)
.build_def(ctx)
.centered_vert(),
])
}
pub fn render_network_layer(ctx: &mut EventCtx, app: &App) -> Drawable {
let mut batch = GeomBatch::new();
// The basemap colors are beautiful, but we want to emphasize the bike network, so all's foggy
// in love and war...
batch.push(
Color::BLACK.alpha(0.4),
app.primary.map.get_boundary_polygon().clone(),
);
for r in app.primary.map.all_roads() {
if r.is_cycleway() {
batch.push(*DEDICATED_TRAIL, r.get_thick_polygon(&app.primary.map));
continue;
}
if is_greenway(r) {
batch.push(*GREENWAY, r.get_thick_polygon(&app.primary.map));
}
// Don't cover up the arterial/local classification -- add thick side lines to show bike
// facilties in each direction.
let mut bike_lane_left = false;
let mut buffer_left = false;
let mut bike_lane_right = false;
let mut buffer_right = false;
let mut on_left = true;
for (_, _, lt) in r.lanes_ltr() {
if lt == LaneType::Driving || lt == LaneType::Bus {
// We're walking the lanes from left-to-right. So as soon as we hit a vehicle lane,
// any bike lane we find is on the right side of the road.
// (Barring really bizarre things like a bike lane in the middle of the road)
on_left = false;
} else if lt == LaneType::Biking {
if on_left {
bike_lane_left = true;
} else {
bike_lane_right = true;
}
} else if matches!(lt, LaneType::Buffer(_)) {
if on_left {
buffer_left = true;
} else {
buffer_right = true;
}
}
let half_width = r.get_half_width(&app.primary.map);
for (shift, bike_lane, buffer) in [
(-1.0, bike_lane_left, buffer_left),
(1.0, bike_lane_right, buffer_right),
] {
let color = if bike_lane && buffer {
*PROTECTED_BIKE_LANE
} else if bike_lane {
*PAINTED_BIKE_LANE
} else {
// If we happen to have a buffer, but no bike lane, let's just not ask
// questions...
continue;
};
if let Ok(pl) = r.center_pts.shift_either_direction(shift * half_width) {
batch.push(color, pl.make_polygons(0.9 * half_width));
}
}
}
}
batch.upload(ctx)
}
// TODO Check how other greenways are tagged.
// https://www.openstreetmap.org/way/262778812 has bicycle=designated, cycleway=shared_lane...
pub fn is_greenway(road: &Road) -> bool {
!road
.access_restrictions
.allow_through_traffic
.contains(PathConstraints::Car)
&& road
.access_restrictions
.allow_through_traffic
.contains(PathConstraints::Bike)
}

View File

@ -63,7 +63,7 @@ fn bike_network_roads(map: &Map) -> Vec<DirectedRoadID> {
let mut results = Vec::new();
for r in map.all_roads() {
if r.is_cycleway()
|| crate::ungap::is_greenway(r)
|| crate::ungap::layers::is_greenway(r)
|| r.lanes_ltr.iter().any(|(_, _, lt)| *lt == LaneType::Biking)
{
// Just start from both directions

View File

@ -9,7 +9,7 @@ use widgetry::{
use crate::app::{App, Transition};
use crate::common::RouteSketcher;
use crate::edit::apply_map_edits;
use crate::ungap::edit::render_edits;
use crate::ungap::layers::render_edits;
use crate::ungap::magnifying::MagnifyingGlass;
pub struct QuickSketch {