mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-23 22:42:32 +03:00
Just rearrange code, in preparation for merging edit mode and the main explore map mode
This commit is contained in:
parent
22dfb616a3
commit
b59419ea84
@ -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
125
game/src/ungap/layers.rs
Normal 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)
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user