modeling and rendering bus stops

This commit is contained in:
Dustin Carlino 2018-08-27 14:40:11 -07:00
parent b70648a8d4
commit a9bb71c59f
8 changed files with 90 additions and 11 deletions

View File

@ -626,3 +626,20 @@ Basic problem: how do we show map edits/diffs?
- hold a button to show the original versions of things in a transparentish overlay
How to show diffs for agents?
## Bus
Before even looking at the GTFS schema, how should we model buses? They're
basically a special car that just goes from bus stop to bus stop (a
SidewalkSpot) and then just stops for a little while. The route is fixed, but
for now, since pathfinding ignores live traffic, probably fine to ignore this.
- step 1: hardcode two BusStops and hardcode spawn a car that cycles between the two
- render a bus stop on the sidewalk
- this actually belongs to the map layer! associated with a sidewalk I guess.
- render the bus in a special color, and also, make it really long (adjust following dist, but not parking spot len)
- step 2: make some peds pick a SINGLE bus to use for their route, if it helps
- step 3: make peds load on the bus and get off at the correct stop. make buses usually wait a fixed time at each stop, but wait a littl extra if loading passengers takes a while.
- step N: load in GTFS for seattle to get real routes and stops
later: multiple transfers, dedicated bus lanes, light rail...

View File

@ -78,6 +78,12 @@
0.294,
1.0
],
"BusStopMarking": [
0.867,
0.627,
0.867,
0.8
],
"UnchangedIntersection": [
0.6,
0.6,

View File

@ -23,6 +23,7 @@ pub enum Colors {
Crosswalk,
StopSignMarking,
Biking,
BusStopMarking,
UnchangedIntersection,
ChangedIntersection,

View File

@ -54,14 +54,23 @@ impl DrawLane {
round: true,
});
}
for m in match lane.lane_type {
map_model::LaneType::Sidewalk => Some(calculate_sidewalk_lines(lane)),
map_model::LaneType::Parking => Some(calculate_parking_lines(lane)),
map_model::LaneType::Driving => calculate_driving_lines(lane, road),
map_model::LaneType::Biking => None,
} {
markings.push(m);
}
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(s, lane));
}
}
map_model::LaneType::Parking => {
markings.push(calculate_parking_lines(lane));
}
map_model::LaneType::Driving => {
for m in calculate_driving_lines(lane, road) {
markings.push(m);
}
}
map_model::LaneType::Biking => {}
};
if lane.is_driving() && !map.get_i(lane.dst_i).has_traffic_signal {
if let Some(m) = calculate_stop_sign_line(lane, control_map) {
markings.push(m);
@ -292,3 +301,21 @@ 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;
// TODO this should maybe be a property of the map model; not sure what data sources will
// actually have
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.
lines: vec![geometry::drawing_line(&Line::new(
lane.dist_along(stop.dist_along - radius).0,
lane.dist_along(stop.dist_along + radius).0,
))],
color: Colors::BusStopMarking,
thickness: 0.8 * geometry::LANE_THICKNESS,
round: true,
}
}

View File

@ -1,7 +1,7 @@
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
use aabb_quadtree::geom::{Point, Rect};
use geom::{Angle, PolyLine, Polygon, Pt2D};
use geom::{Angle, Line, PolyLine, Polygon, Pt2D};
use std::f64;
pub const LANE_THICKNESS: f64 = 2.5;
@ -71,3 +71,7 @@ pub fn regular_polygon(center: Pt2D, sides: usize, length: f64) -> Polygon {
pts.push(first_pt);
Polygon::new(&pts)
}
pub fn drawing_line(l: &Line) -> [f64; 4] {
[l.pt1().x(), l.pt1().y(), l.pt2().x(), l.pt2().y()]
}

View File

@ -31,6 +31,12 @@ pub enum LaneType {
Biking,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct BusStop {
pub sidewalk: LaneID,
pub dist_along: si::Meter<f64>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Lane {
pub id: LaneID,
@ -47,6 +53,7 @@ pub struct Lane {
pub dst_i: IntersectionID,
pub building_paths: Vec<BuildingID>,
pub bus_stops: Vec<BusStop>,
}
impl PartialEq for Lane {

View File

@ -26,7 +26,7 @@ mod turn;
pub use building::{Building, BuildingID, FrontPath};
pub use edits::{EditReason, Edits};
pub use intersection::{Intersection, IntersectionID};
pub use lane::{Lane, LaneID, LaneType, PARKING_SPOT_LENGTH};
pub use lane::{BusStop, Lane, LaneID, LaneType, PARKING_SPOT_LENGTH};
pub use map::Map;
pub use parcel::{Parcel, ParcelID};
pub use pathfind::pathfind;

View File

@ -2,11 +2,12 @@
use abstutil;
use building::{Building, BuildingID};
use dimensioned::si;
use edits::Edits;
use geom::{Bounds, HashablePt2D, PolyLine, Pt2D};
use geometry;
use intersection::{Intersection, IntersectionID};
use lane::{Lane, LaneID, LaneType};
use lane::{BusStop, Lane, LaneID, LaneType};
use make;
use parcel::{Parcel, ParcelID};
use raw_data;
@ -121,6 +122,21 @@ impl Map {
None => (unshifted_pts.shift_blindly(width), true),
};
let mut bus_stops = Vec::new();
// TODO load a GTFS, don't hardcode this
if id == LaneID(309) {
bus_stops.push(BusStop {
sidewalk: id,
dist_along: 25.0 * si::M,
});
}
if id == LaneID(840) {
bus_stops.push(BusStop {
sidewalk: id,
dist_along: 50.0 * si::M,
});
}
// lane_center_pts will get updated in the next pass
m.lanes.push(Lane {
id,
@ -131,6 +147,7 @@ impl Map {
lane_type: lane.lane_type,
parent: road_id,
building_paths: Vec::new(),
bus_stops,
});
if lane.reverse_pts {
m.roads[road_id.0]