make bus stops a separate layer to render. easy!

This commit is contained in:
Dustin Carlino 2018-09-15 19:35:49 -07:00
parent 74ad9d0819
commit e4339436fc
10 changed files with 91 additions and 37 deletions

View File

@ -999,7 +999,6 @@ Alright, replan yet again.
= handle the two color things... just buildings?
- deal with overlapping keys that still kinda happen (sim ctrl, escape game)
- bug: do need to recalculate current_selection whenever anything potentially changes camera, like follow
- and see how much boilerplate a new type would need, by adding bus stops and water/parks
- including warping to it
= and see how much boilerplate a new type would need, by adding bus stops and water/parks
- consider merging control map into map
- see how hard it is to render textures onto cars or something

View File

@ -2,7 +2,7 @@ use colors::ColorScheme;
use control::ControlMap;
use ezgui::Canvas;
use kml::ExtraShapeID;
use map_model::{BuildingID, IntersectionID, LaneID, Map, ParcelID, TurnID};
use map_model::{BuildingID, BusStopID, IntersectionID, LaneID, Map, ParcelID, TurnID};
use sim::{CarID, PedestrianID, Sim};
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
@ -15,6 +15,7 @@ pub enum ID {
Pedestrian(PedestrianID),
ExtraShape(ExtraShapeID),
Parcel(ParcelID),
BusStop(BusStopID),
}
// For plugins and rendering. Not sure what module this should live in, here seems fine.

View File

@ -104,6 +104,9 @@ fn debug(id: &ID, map: &Map, control_map: &ControlMap, sim: &mut Sim) {
ID::Parcel(id) => {
map.get_p(*id).dump_debug();
}
ID::BusStop(id) => {
map.get_bs(*id).dump_debug();
}
}
}
@ -117,6 +120,7 @@ fn tooltip_lines(id: ID, map: &Map, draw_map: &DrawMap, sim: &Sim) -> Vec<String
ID::Intersection(id) => vec![format!("{}", id)],
ID::Turn(id) => map.get_t(id).tooltip_lines(map),
ID::ExtraShape(id) => draw_map.get_es(id).tooltip_lines(map),
ID::BusStop(id) => draw_map.get_bs(id).tooltip_lines(map),
ID::Parcel(id) => vec![format!("{}", id)],
}
}

View File

@ -0,0 +1,62 @@
use aabb_quadtree::geom::Rect;
use colors::Colors;
use dimensioned::si;
use ezgui::GfxCtx;
use geom::{PolyLine, Polygon, Pt2D};
use map_model::{geometry, BusStop, BusStopID, Map};
use objects::{Ctx, ID};
use render::{get_bbox, RenderOptions, Renderable};
pub struct DrawBusStop {
pub id: BusStopID,
polygon: Polygon,
}
impl DrawBusStop {
pub fn new(stop: &BusStop, map: &Map) -> DrawBusStop {
let radius = 2.0 * si::M;
// TODO if this happens to cross a bend in the lane, it'll look weird. similar to the
// lookahead arrows and center points / dashed white, we really want to render an Interval
// or something.
// Kinda sad that bus stops might be very close to the start of the lane, but it's
// happening.
let lane = map.get_l(stop.id.sidewalk);
let polygon = PolyLine::new(vec![
lane.safe_dist_along(stop.dist_along - radius)
.map(|(pt, _)| pt)
.unwrap_or(lane.first_pt()),
lane.safe_dist_along(stop.dist_along + radius)
.map(|(pt, _)| pt)
.unwrap_or(lane.last_pt()),
]).make_polygons_blindly(0.8 * geometry::LANE_THICKNESS);
DrawBusStop {
id: stop.id,
polygon,
}
}
}
impl Renderable for DrawBusStop {
fn get_id(&self) -> ID {
ID::BusStop(self.id)
}
fn draw(&self, g: &mut GfxCtx, opts: RenderOptions, ctx: Ctx) {
g.draw_polygon(
opts.color.unwrap_or(ctx.cs.get(Colors::BusStopMarking)),
&self.polygon,
);
}
fn get_bbox(&self) -> Rect {
get_bbox(&self.polygon.get_bounds())
}
fn contains_pt(&self, pt: Pt2D) -> bool {
self.polygon.contains_pt(pt)
}
fn tooltip_lines(&self, _map: &Map) -> Vec<String> {
vec![self.id.to_string()]
}
}

View File

@ -60,9 +60,6 @@ impl DrawLane {
match lane.lane_type {
map_model::LaneType::Sidewalk => {
markings.push(calculate_sidewalk_lines(lane));
for s in &lane.bus_stops {
markings.push(calculate_bus_stop_lines(map.get_bus_stop(*s), lane));
}
}
map_model::LaneType::Parking => {
markings.push(calculate_parking_lines(lane));
@ -328,25 +325,3 @@ fn calculate_id_positions(lane: &map_model::Lane) -> Option<Vec<Pt2D>> {
let (pt2, _) = lane.safe_dist_along(2.0 * geometry::LANE_THICKNESS * si::M)?;
Some(vec![pt1, pt2])
}
fn calculate_bus_stop_lines(stop: &map_model::BusStop, lane: &map_model::Lane) -> Marking {
let radius = 2.0 * si::M;
Marking {
// TODO if this happens to cross a bend in the lane, it'll look weird. similar to the
// lookahead arrows and center points / dashed white, we really want to render an Interval
// or something.
// Kinda sad that bus stops might be very close to the start of the lane, but it's
// happening.
lines: vec![geometry::drawing_line(&Line::new(
lane.safe_dist_along(stop.dist_along - radius)
.map(|(pt, _)| pt)
.unwrap_or(lane.first_pt()),
lane.safe_dist_along(stop.dist_along + radius)
.map(|(pt, _)| pt)
.unwrap_or(lane.last_pt()),
))],
color: Colors::BusStopMarking,
thickness: 0.8 * geometry::LANE_THICKNESS,
round: true,
}
}

View File

@ -5,10 +5,11 @@ use aabb_quadtree::QuadTree;
use control::ControlMap;
use geom::{LonLat, Pt2D};
use kml::{ExtraShape, ExtraShapeID};
use map_model::{BuildingID, IntersectionID, Lane, LaneID, Map, ParcelID, Turn, TurnID};
use map_model::{BuildingID, BusStopID, IntersectionID, Lane, LaneID, Map, ParcelID, Turn, TurnID};
use objects::ID;
use plugins::hider::Hider;
use render::building::DrawBuilding;
use render::bus_stop::DrawBusStop;
use render::car::DrawCar;
use render::extra_shape::DrawExtraShape;
use render::intersection::DrawIntersection;
@ -28,6 +29,7 @@ pub struct DrawMap {
pub buildings: Vec<DrawBuilding>,
pub parcels: Vec<DrawParcel>,
pub extra_shapes: Vec<DrawExtraShape>,
pub bus_stops: HashMap<BusStopID, DrawBusStop>,
quadtree: QuadTree<ID>,
}
@ -69,11 +71,14 @@ impl DrawMap {
.iter()
.map(|p| DrawParcel::new(p))
.collect();
let extra_shapes: Vec<DrawExtraShape> = raw_extra_shapes
.into_iter()
.map(|s| DrawExtraShape::new(s))
.collect();
let mut bus_stops: HashMap<BusStopID, DrawBusStop> = HashMap::new();
for s in map.all_bus_stops().values() {
bus_stops.insert(s.id, DrawBusStop::new(s, map));
}
// min_y here due to the wacky y inversion
let bounds = map.get_gps_bounds();
@ -103,6 +108,9 @@ impl DrawMap {
for obj in &extra_shapes {
quadtree.insert_with_box(obj.get_id(), obj.get_bbox());
}
for obj in bus_stops.values() {
quadtree.insert_with_box(obj.get_id(), obj.get_bbox());
}
(
DrawMap {
@ -112,6 +120,7 @@ impl DrawMap {
buildings,
parcels,
extra_shapes,
bus_stops,
quadtree,
},
@ -182,6 +191,10 @@ impl DrawMap {
&self.extra_shapes[id.0]
}
pub fn get_bs(&self, id: BusStopID) -> &DrawBusStop {
&self.bus_stops[&id]
}
// Returns in back-to-front order
// The second pair is ephemeral objects (cars, pedestrians) that we can't borrow --
// conveniently they're the front-most layer, so the caller doesn't have to do anything strange
@ -205,6 +218,7 @@ impl DrawMap {
let mut intersections: Vec<Box<&Renderable>> = Vec::new();
let mut buildings: Vec<Box<&Renderable>> = Vec::new();
let mut extra_shapes: Vec<Box<&Renderable>> = Vec::new();
let mut bus_stops: Vec<Box<&Renderable>> = Vec::new();
let mut turn_icons: Vec<Box<&Renderable>> = Vec::new();
let mut cars: Vec<Box<Renderable>> = Vec::new();
@ -242,6 +256,7 @@ impl DrawMap {
// two passes through buildings.
ID::Building(id) => buildings.push(Box::new(self.get_b(*id))),
ID::ExtraShape(id) => extra_shapes.push(Box::new(self.get_es(*id))),
ID::BusStop(id) => bus_stops.push(Box::new(self.get_bs(*id))),
ID::Turn(_) | ID::Car(_) | ID::Pedestrian(_) => {
panic!("{:?} shouldn't be in the quadtree", id)
@ -256,6 +271,7 @@ impl DrawMap {
borrows.extend(intersections);
borrows.extend(buildings);
borrows.extend(extra_shapes);
borrows.extend(bus_stops);
borrows.extend(turn_icons);
let mut returns: Vec<Box<Renderable>> = Vec::new();

View File

@ -1,6 +1,7 @@
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
mod building;
mod bus_stop;
mod car;
mod extra_shape;
mod intersection;

View File

@ -378,7 +378,7 @@ impl Map {
&self.bus_stops
}
pub fn get_bus_stop(&self, stop: BusStopID) -> &BusStop {
pub fn get_bs(&self, stop: BusStopID) -> &BusStop {
&self.bus_stops[&stop]
}

View File

@ -75,11 +75,7 @@ impl TransitSimState {
id,
name: route.name.clone(),
buses: Vec::new(),
stops: route
.stops
.iter()
.map(|s| map.get_bus_stop(*s).clone())
.collect(),
stops: route.stops.iter().map(|s| map.get_bs(*s).clone()).collect(),
},
);
id

View File

@ -62,7 +62,7 @@ impl SidewalkSpot {
pub fn bus_stop(stop: BusStopID, map: &Map) -> SidewalkSpot {
SidewalkSpot {
sidewalk: stop.sidewalk,
dist_along: map.get_bus_stop(stop).dist_along,
dist_along: map.get_bs(stop).dist_along,
connection: SidewalkPOI::BusStop(stop),
}
}