mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 03:35:51 +03:00
Allow colorschemes to optionally color zoomed-in lanes based on OSM road rank. Most schemes don't do this, but one needs to, and maintaining a separate git branch has become annoying.
Should have no behavioral change to existing color schemes.
This commit is contained in:
parent
f73d9da080
commit
5aee85f19d
@ -1,5 +1,7 @@
|
||||
use crate::common::ColorScale;
|
||||
use crate::helpers::loading_tips;
|
||||
use map_model::osm::RoadRank;
|
||||
use map_model::LaneType;
|
||||
use widgetry::{Choice, Color, Fill, Style, Texture};
|
||||
|
||||
// I've gone back and forth how to organize color scheme code. I was previously against having one
|
||||
@ -25,6 +27,7 @@ pub enum ColorSchemeChoice {
|
||||
Textured,
|
||||
MapboxLight,
|
||||
MapboxDark,
|
||||
FadedZoom,
|
||||
}
|
||||
|
||||
impl ColorSchemeChoice {
|
||||
@ -40,11 +43,14 @@ impl ColorSchemeChoice {
|
||||
Choice::new("textured", ColorSchemeChoice::Textured),
|
||||
Choice::new("mapbox light", ColorSchemeChoice::MapboxLight),
|
||||
Choice::new("mapbox dark", ColorSchemeChoice::MapboxDark),
|
||||
Choice::new("faded zoom", ColorSchemeChoice::FadedZoom),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ColorScheme {
|
||||
scheme: ColorSchemeChoice,
|
||||
|
||||
// UI
|
||||
pub hovering: Color,
|
||||
pub panel_bg: Color,
|
||||
@ -62,19 +68,19 @@ pub struct ColorScheme {
|
||||
pub dialog_bg: Color,
|
||||
|
||||
// Roads
|
||||
pub driving_lane: Color,
|
||||
pub bus_lane: Color,
|
||||
pub parking_lane: Color,
|
||||
pub bike_lane: Color,
|
||||
pub sidewalk: Color,
|
||||
driving_lane: Color,
|
||||
bus_lane: Color,
|
||||
parking_lane: Color,
|
||||
bike_lane: Color,
|
||||
sidewalk: Color,
|
||||
pub sidewalk_lines: Color,
|
||||
pub general_road_marking: Color,
|
||||
pub road_center_line: Color,
|
||||
pub light_rail_track: Color,
|
||||
pub private_road: Color,
|
||||
pub unzoomed_highway: Color,
|
||||
pub unzoomed_arterial: Color,
|
||||
pub unzoomed_residential: Color,
|
||||
unzoomed_highway: Color,
|
||||
unzoomed_arterial: Color,
|
||||
unzoomed_residential: Color,
|
||||
|
||||
// Intersections
|
||||
pub normal_intersection: Color,
|
||||
@ -127,13 +133,15 @@ pub struct ColorScheme {
|
||||
|
||||
// Misc
|
||||
pub parking_trip: Color,
|
||||
pub bike_trip: Color,
|
||||
pub bus_trip: Color,
|
||||
pub before_changes: Color,
|
||||
pub after_changes: Color,
|
||||
}
|
||||
|
||||
impl ColorScheme {
|
||||
pub fn new(scheme: ColorSchemeChoice) -> ColorScheme {
|
||||
match scheme {
|
||||
let mut cs = match scheme {
|
||||
ColorSchemeChoice::Standard => ColorScheme::standard(),
|
||||
ColorSchemeChoice::NightMode => ColorScheme::night_mode(),
|
||||
ColorSchemeChoice::SAMGreenDay => ColorScheme::sam_green_day(),
|
||||
@ -144,13 +152,18 @@ impl ColorScheme {
|
||||
ColorSchemeChoice::Textured => ColorScheme::textured(),
|
||||
ColorSchemeChoice::MapboxLight => ColorScheme::mapbox_light(),
|
||||
ColorSchemeChoice::MapboxDark => ColorScheme::mapbox_dark(),
|
||||
}
|
||||
ColorSchemeChoice::FadedZoom => ColorScheme::faded_zoom(),
|
||||
};
|
||||
cs.scheme = scheme;
|
||||
cs
|
||||
}
|
||||
|
||||
fn standard() -> ColorScheme {
|
||||
let mut gui_style = Style::standard();
|
||||
gui_style.loading_tips = loading_tips();
|
||||
ColorScheme {
|
||||
scheme: ColorSchemeChoice::Standard,
|
||||
|
||||
// UI
|
||||
hovering: gui_style.hovering_color,
|
||||
panel_bg: gui_style.panel_bg,
|
||||
@ -239,6 +252,8 @@ impl ColorScheme {
|
||||
|
||||
// Misc
|
||||
parking_trip: hex("#4E30A6"),
|
||||
bike_trip: Color::rgb(15, 125, 75),
|
||||
bus_trip: Color::rgb(190, 74, 76),
|
||||
before_changes: Color::BLUE,
|
||||
after_changes: Color::RED,
|
||||
}
|
||||
@ -260,6 +275,40 @@ impl ColorScheme {
|
||||
pub fn rotating_color_agents(&self, idx: usize) -> Color {
|
||||
modulo_color(&self.agent_colors, idx)
|
||||
}
|
||||
|
||||
pub fn unzoomed_road_surface(&self, rank: RoadRank) -> Color {
|
||||
match rank {
|
||||
RoadRank::Highway => self.unzoomed_highway,
|
||||
RoadRank::Arterial => self.unzoomed_arterial,
|
||||
RoadRank::Local => self.unzoomed_residential,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn zoomed_road_surface(&self, lane: LaneType, rank: RoadRank) -> Color {
|
||||
match self.scheme {
|
||||
ColorSchemeChoice::FadedZoom => match rank {
|
||||
RoadRank::Highway => hex("#BEB2C0"),
|
||||
RoadRank::Arterial => hex("#B6BDC5"),
|
||||
RoadRank::Local => hex("#C6CDD5"),
|
||||
},
|
||||
_ => match lane {
|
||||
LaneType::Driving => self.driving_lane,
|
||||
LaneType::Bus => self.bus_lane,
|
||||
LaneType::Parking => self.parking_lane,
|
||||
LaneType::Sidewalk | LaneType::Shoulder => self.sidewalk,
|
||||
LaneType::Biking => self.bike_lane,
|
||||
LaneType::SharedLeftTurn => self.driving_lane,
|
||||
LaneType::Construction => self.parking_lane,
|
||||
LaneType::LightRail => unreachable!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
pub fn zoomed_intersection_surface(&self, rank: RoadRank) -> Color {
|
||||
match self.scheme {
|
||||
ColorSchemeChoice::FadedZoom => self.zoomed_road_surface(LaneType::Driving, rank),
|
||||
_ => self.normal_intersection,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn modulo_color(colors: &Vec<Color>, idx: usize) -> Color {
|
||||
@ -395,6 +444,7 @@ impl ColorScheme {
|
||||
cs.residential_building = hex("#2C2C2B").into();
|
||||
cs.commerical_building = hex("#2C2C2B").into();
|
||||
|
||||
// TODO Things like this could be refactored in zoomed_road_surface
|
||||
cs.driving_lane = road;
|
||||
cs.parking_lane = road;
|
||||
cs.bike_lane = road;
|
||||
@ -408,4 +458,9 @@ impl ColorScheme {
|
||||
|
||||
cs
|
||||
}
|
||||
|
||||
fn faded_zoom() -> ColorScheme {
|
||||
let cs = ColorScheme::standard();
|
||||
cs
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ pub fn color_for_agent_type(app: &App, a: AgentType) -> Color {
|
||||
AgentType::Pedestrian => app.cs.unzoomed_pedestrian,
|
||||
AgentType::Bike => app.cs.unzoomed_bike,
|
||||
AgentType::Bus | AgentType::Train => app.cs.unzoomed_bus,
|
||||
AgentType::TransitRider => app.cs.bus_lane,
|
||||
AgentType::TransitRider => app.cs.bus_trip,
|
||||
AgentType::Car => app.cs.unzoomed_car,
|
||||
}
|
||||
}
|
||||
@ -144,10 +144,10 @@ pub fn color_for_trip_phase(app: &App, tpt: TripPhaseType) -> Color {
|
||||
match tpt {
|
||||
TripPhaseType::Driving => app.cs.unzoomed_car,
|
||||
TripPhaseType::Walking => app.cs.unzoomed_pedestrian,
|
||||
TripPhaseType::Biking => app.cs.bike_lane,
|
||||
TripPhaseType::Biking => app.cs.bike_trip,
|
||||
TripPhaseType::Parking => app.cs.parking_trip,
|
||||
TripPhaseType::WaitingForBus(_, _) => app.cs.bus_layer,
|
||||
TripPhaseType::RidingBus(_, _, _) => app.cs.bus_lane,
|
||||
TripPhaseType::RidingBus(_, _, _) => app.cs.bus_trip,
|
||||
TripPhaseType::Aborted | TripPhaseType::Finished => unreachable!(),
|
||||
TripPhaseType::DelayedStart => Color::YELLOW,
|
||||
TripPhaseType::Remote => Color::PINK,
|
||||
|
@ -4,7 +4,7 @@ use crate::helpers::ID;
|
||||
use crate::options::{CameraAngle, Options};
|
||||
use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS};
|
||||
use geom::{Angle, Distance, Line, Polygon, Pt2D, Ring};
|
||||
use map_model::{Building, BuildingID, Map, OffstreetParking, NORMAL_LANE_THICKNESS};
|
||||
use map_model::{Building, BuildingID, LaneType, Map, OffstreetParking, NORMAL_LANE_THICKNESS};
|
||||
use std::cell::RefCell;
|
||||
use widgetry::{Color, Drawable, EventCtx, GeomBatch, GfxCtx, Line, Text};
|
||||
|
||||
@ -188,7 +188,13 @@ impl DrawBuilding {
|
||||
}
|
||||
}
|
||||
}
|
||||
paths_batch.push(cs.sidewalk, driveway.make_polygons(NORMAL_LANE_THICKNESS));
|
||||
paths_batch.push(
|
||||
cs.zoomed_road_surface(
|
||||
LaneType::Sidewalk,
|
||||
map.get_parent(bldg.sidewalk()).get_rank(),
|
||||
),
|
||||
driveway.make_polygons(NORMAL_LANE_THICKNESS),
|
||||
);
|
||||
|
||||
DrawBuilding {
|
||||
id: bldg.id,
|
||||
|
@ -6,7 +6,7 @@ use crate::render::{
|
||||
};
|
||||
use geom::{Angle, ArrowCap, Distance, Line, PolyLine, Polygon, Pt2D, Ring, Time, EPSILON_DIST};
|
||||
use map_model::{
|
||||
Direction, DrivingSide, Intersection, IntersectionID, IntersectionType, Map, Road,
|
||||
Direction, DrivingSide, Intersection, IntersectionID, IntersectionType, LaneType, Map, Road,
|
||||
RoadWithStopSign, Turn, TurnType, SIDEWALK_THICKNESS,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
@ -41,8 +41,12 @@ impl DrawIntersection {
|
||||
|
||||
// Order matters... main polygon first, then sidewalk corners.
|
||||
let mut default_geom = GeomBatch::new();
|
||||
default_geom.push(app.cs.normal_intersection, i.polygon.clone());
|
||||
default_geom.extend(app.cs.sidewalk, calculate_corners(i, map));
|
||||
let rank = i.get_rank(map);
|
||||
default_geom.push(app.cs.zoomed_intersection_surface(rank), i.polygon.clone());
|
||||
default_geom.extend(
|
||||
app.cs.zoomed_road_surface(LaneType::Sidewalk, rank),
|
||||
calculate_corners(i, map),
|
||||
);
|
||||
|
||||
for turn in map.get_turns_in_intersection(i.id) {
|
||||
// Avoid double-rendering
|
||||
|
@ -39,16 +39,7 @@ impl DrawLane {
|
||||
let mut draw = GeomBatch::new();
|
||||
if !lane.is_light_rail() {
|
||||
draw.push(
|
||||
match lane.lane_type {
|
||||
LaneType::Driving => app.cs.driving_lane,
|
||||
LaneType::Bus => app.cs.bus_lane,
|
||||
LaneType::Parking => app.cs.parking_lane,
|
||||
LaneType::Sidewalk | LaneType::Shoulder => app.cs.sidewalk,
|
||||
LaneType::Biking => app.cs.bike_lane,
|
||||
LaneType::SharedLeftTurn => app.cs.driving_lane,
|
||||
LaneType::Construction => app.cs.parking_lane,
|
||||
LaneType::LightRail => unreachable!(),
|
||||
},
|
||||
app.cs.zoomed_road_surface(lane.lane_type, road.get_rank()),
|
||||
self.polygon.clone(),
|
||||
);
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ use aabb_quadtree::QuadTree;
|
||||
use abstutil::Timer;
|
||||
use geom::{Bounds, Circle, Distance, Polygon, Pt2D, Time};
|
||||
use map_model::{
|
||||
osm, AreaID, BuildingID, BusStopID, IntersectionID, LaneID, Map, ParkingLotID, RoadID,
|
||||
Traversable, NORMAL_LANE_THICKNESS, SIDEWALK_THICKNESS,
|
||||
AreaID, BuildingID, BusStopID, IntersectionID, LaneID, Map, ParkingLotID, RoadID, Traversable,
|
||||
NORMAL_LANE_THICKNESS, SIDEWALK_THICKNESS,
|
||||
};
|
||||
use sim::{GetDrawAgents, UnzoomedAgent, VehicleType};
|
||||
use std::borrow::Borrow;
|
||||
@ -210,7 +210,7 @@ impl DrawMap {
|
||||
} else if r.is_private() {
|
||||
cs.private_road
|
||||
} else {
|
||||
rank_to_color(cs, r.get_rank())
|
||||
cs.unzoomed_road_surface(r.get_rank())
|
||||
},
|
||||
));
|
||||
}
|
||||
@ -224,7 +224,7 @@ impl DrawMap {
|
||||
} else if i.is_private(map) {
|
||||
cs.private_road
|
||||
} else {
|
||||
rank_to_color(cs, i.get_rank(map))
|
||||
cs.unzoomed_road_surface(i.get_rank(map))
|
||||
}
|
||||
} else {
|
||||
cs.unzoomed_interesting_intersection
|
||||
@ -522,11 +522,3 @@ impl UnzoomedAgents {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn rank_to_color(cs: &ColorScheme, rank: osm::RoadRank) -> Color {
|
||||
match rank {
|
||||
osm::RoadRank::Highway => cs.unzoomed_highway,
|
||||
osm::RoadRank::Arterial => cs.unzoomed_arterial,
|
||||
osm::RoadRank::Local => cs.unzoomed_residential,
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ use crate::colors::ColorScheme;
|
||||
use crate::helpers::ID;
|
||||
use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS};
|
||||
use geom::{Distance, PolyLine, Polygon, Pt2D};
|
||||
use map_model::{Map, ParkingLot, ParkingLotID, NORMAL_LANE_THICKNESS, PARKING_LOT_SPOT_LENGTH};
|
||||
use map_model::{
|
||||
osm, LaneType, Map, ParkingLot, ParkingLotID, NORMAL_LANE_THICKNESS, PARKING_LOT_SPOT_LENGTH,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
use widgetry::{Drawable, EventCtx, GeomBatch, GfxCtx};
|
||||
|
||||
@ -23,7 +25,7 @@ impl DrawParkingLot {
|
||||
for aisle in &lot.aisles {
|
||||
let aisle_thickness = NORMAL_LANE_THICKNESS / 2.0;
|
||||
unzoomed_batch.push(
|
||||
cs.unzoomed_residential,
|
||||
cs.unzoomed_road_surface(osm::RoadRank::Local),
|
||||
PolyLine::unchecked_new(aisle.clone()).make_polygons(aisle_thickness),
|
||||
);
|
||||
}
|
||||
@ -64,14 +66,21 @@ impl Renderable for DrawParkingLot {
|
||||
// TODO This isn't getting clipped to the parking lot boundary properly, so just stick
|
||||
// this on the lowest order for now.
|
||||
batch.push(
|
||||
app.cs.sidewalk,
|
||||
app.cs.zoomed_road_surface(
|
||||
LaneType::Sidewalk,
|
||||
app.primary
|
||||
.map
|
||||
.get_parent(lot.sidewalk_pos.lane())
|
||||
.get_rank(),
|
||||
),
|
||||
front_path_line.make_polygons(NORMAL_LANE_THICKNESS),
|
||||
);
|
||||
batch.push(app.cs.parking_lot, lot.polygon.clone());
|
||||
for aisle in &lot.aisles {
|
||||
let aisle_thickness = NORMAL_LANE_THICKNESS / 2.0;
|
||||
batch.push(
|
||||
app.cs.driving_lane,
|
||||
app.cs
|
||||
.zoomed_road_surface(LaneType::Driving, osm::RoadRank::Local),
|
||||
PolyLine::unchecked_new(aisle.clone()).make_polygons(aisle_thickness),
|
||||
);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::app::App;
|
||||
use crate::helpers::ID;
|
||||
use crate::render::{DrawOptions, Renderable};
|
||||
use geom::{Distance, Polygon, Pt2D};
|
||||
use map_model::{Map, Road, RoadID};
|
||||
use map_model::{LaneType, Map, Road, RoadID};
|
||||
use std::cell::RefCell;
|
||||
use widgetry::{Drawable, GeomBatch, GfxCtx, Line, Text};
|
||||
|
||||
@ -86,9 +86,11 @@ impl Renderable for DrawRoad {
|
||||
app.cs.road_center_line
|
||||
};
|
||||
let bg = if r.is_private() {
|
||||
app.cs.driving_lane.lerp(app.cs.private_road, 0.5)
|
||||
app.cs
|
||||
.zoomed_road_surface(LaneType::Driving, r.get_rank())
|
||||
.lerp(app.cs.private_road, 0.5)
|
||||
} else {
|
||||
app.cs.driving_lane
|
||||
app.cs.zoomed_road_surface(LaneType::Driving, r.get_rank())
|
||||
};
|
||||
|
||||
if false {
|
||||
|
@ -30,7 +30,7 @@ pub const ENDPT_BACK: &str = "abst:endpt_back";
|
||||
pub const INFERRED_PARKING: &str = "abst:parking_inferred";
|
||||
pub const INFERRED_SIDEWALKS: &str = "abst:sidewalks_inferred";
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||
pub enum RoadRank {
|
||||
Local,
|
||||
Arterial,
|
||||
|
Loading…
Reference in New Issue
Block a user