mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 17:34:58 +03:00
make bus stops a separate layer to render. easy!
This commit is contained in:
parent
74ad9d0819
commit
e4339436fc
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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)],
|
||||
}
|
||||
}
|
||||
|
62
editor/src/render/bus_stop.rs
Normal file
62
editor/src/render/bus_stop.rs
Normal 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()]
|
||||
}
|
||||
}
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user