mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 07:25:47 +03:00
Draw arrows to show entrances/exits to a LTN.
(and rename Line::reverse for consistency with PolyLine)
This commit is contained in:
parent
e62a41d45b
commit
32fc46831b
@ -1,6 +1,6 @@
|
|||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
use geom::{Distance, Line};
|
use geom::{Distance, Line, PolyLine, Polygon};
|
||||||
use map_gui::tools::{CityPicker, ColorDiscrete};
|
use map_gui::tools::{CityPicker, ColorDiscrete};
|
||||||
use map_gui::ID;
|
use map_gui::ID;
|
||||||
use map_model::{IntersectionID, Map, Road, RoadID};
|
use map_model::{IntersectionID, Map, Road, RoadID};
|
||||||
@ -242,7 +242,6 @@ impl Neighborhood {
|
|||||||
vec![
|
vec![
|
||||||
("interior", Color::BLUE.alpha(0.8)),
|
("interior", Color::BLUE.alpha(0.8)),
|
||||||
("perimeter", Color::hex("#40B5AD").alpha(0.8)),
|
("perimeter", Color::hex("#40B5AD").alpha(0.8)),
|
||||||
("border", Color::CYAN.alpha(0.8)),
|
|
||||||
("rat-run", Color::RED.alpha(0.8)),
|
("rat-run", Color::RED.alpha(0.8)),
|
||||||
("modal filter", Color::GREEN),
|
("modal filter", Color::GREEN),
|
||||||
],
|
],
|
||||||
@ -257,10 +256,37 @@ impl Neighborhood {
|
|||||||
colorer.add_r(*r, "perimeter");
|
colorer.add_r(*r, "perimeter");
|
||||||
}
|
}
|
||||||
for i in &self.borders {
|
for i in &self.borders {
|
||||||
colorer.add_i(*i, "border");
|
// TODO These should have a higher z-order than rat runs
|
||||||
|
let arrow = self.border_arrow(&app.primary.map, *i);
|
||||||
|
colorer.unzoomed.push(Color::PURPLE, arrow.clone());
|
||||||
|
colorer.zoomed.push(Color::PURPLE, arrow.clone());
|
||||||
}
|
}
|
||||||
colorer.build(ctx)
|
colorer.build(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn border_arrow(&self, map: &Map, i: IntersectionID) -> Polygon {
|
||||||
|
assert!(self.borders.contains(&i));
|
||||||
|
// Multiple interior roads could connect to one border, but let's just use one (the common
|
||||||
|
// case anyway)
|
||||||
|
let road = map.get_r(
|
||||||
|
*map.get_i(i)
|
||||||
|
.roads
|
||||||
|
.iter()
|
||||||
|
.find(|r| self.interior.contains(r))
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
let line = if road.dst_i == i {
|
||||||
|
road.center_pts.last_line()
|
||||||
|
} else {
|
||||||
|
road.center_pts.first_line().reversed()
|
||||||
|
};
|
||||||
|
PolyLine::must_new(vec![
|
||||||
|
line.pt2(),
|
||||||
|
line.pt2()
|
||||||
|
.project_away(Distance::meters(30.0), line.angle()),
|
||||||
|
])
|
||||||
|
.make_double_arrow(Distance::meters(5.0), geom::ArrowCap::Triangle)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RatRun {
|
impl RatRun {
|
||||||
|
@ -142,7 +142,7 @@ impl Line {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reversed line segment
|
/// Returns a reversed line segment
|
||||||
pub fn reverse(&self) -> Line {
|
pub fn reversed(&self) -> Line {
|
||||||
Line::must_new(self.pt2(), self.pt1())
|
Line::must_new(self.pt2(), self.pt1())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +354,7 @@ fn calculate_corner_curbs(i: &Intersection, map: &Map) -> Vec<Polygon> {
|
|||||||
let first_line = l2.first_line().shift_either_direction(width);
|
let first_line = l2.first_line().shift_either_direction(width);
|
||||||
pts.push(first_line.pt1());
|
pts.push(first_line.pt1());
|
||||||
pts.push(first_line.unbounded_dist_along(thickness));
|
pts.push(first_line.unbounded_dist_along(thickness));
|
||||||
let last_line = l1.last_line().shift_either_direction(width).reverse();
|
let last_line = l1.last_line().shift_either_direction(width).reversed();
|
||||||
pts.insert(0, last_line.pt1());
|
pts.insert(0, last_line.pt1());
|
||||||
pts.insert(0, last_line.unbounded_dist_along(thickness));
|
pts.insert(0, last_line.unbounded_dist_along(thickness));
|
||||||
PolyLine::deduping_new(pts).ok()
|
PolyLine::deduping_new(pts).ok()
|
||||||
@ -375,7 +375,7 @@ fn calculate_corner_curbs(i: &Intersection, map: &Map) -> Vec<Polygon> {
|
|||||||
.first_line()
|
.first_line()
|
||||||
.shift_either_direction(direction * shift(l2.width));
|
.shift_either_direction(direction * shift(l2.width));
|
||||||
if let Ok(pl) = PolyLine::deduping_new(vec![
|
if let Ok(pl) = PolyLine::deduping_new(vec![
|
||||||
last_line.reverse().unbounded_dist_along(thickness),
|
last_line.reversed().unbounded_dist_along(thickness),
|
||||||
last_line.pt2(),
|
last_line.pt2(),
|
||||||
first_line.pt1(),
|
first_line.pt1(),
|
||||||
first_line.unbounded_dist_along(thickness),
|
first_line.unbounded_dist_along(thickness),
|
||||||
@ -409,7 +409,7 @@ fn calculate_border_arrows(i: &Intersection, r: &Road, map: &Map) -> Vec<Polygon
|
|||||||
if !i.outgoing_lanes.is_empty() {
|
if !i.outgoing_lanes.is_empty() {
|
||||||
let (line, width) = if r.dst_i == i.id {
|
let (line, width) = if r.dst_i == i.id {
|
||||||
(
|
(
|
||||||
center.last_line().shift_left(width_back / 2.0).reverse(),
|
center.last_line().shift_left(width_back / 2.0).reversed(),
|
||||||
width_back,
|
width_back,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -429,7 +429,7 @@ fn calculate_border_arrows(i: &Intersection, r: &Road, map: &Map) -> Vec<Polygon
|
|||||||
if !i.incoming_lanes.is_empty() {
|
if !i.incoming_lanes.is_empty() {
|
||||||
let (line, width) = if r.dst_i == i.id {
|
let (line, width) = if r.dst_i == i.id {
|
||||||
(
|
(
|
||||||
center.last_line().shift_right(width_fwd / 2.0).reverse(),
|
center.last_line().shift_right(width_fwd / 2.0).reversed(),
|
||||||
width_fwd,
|
width_fwd,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -232,7 +232,7 @@ fn curvey_turn(src: &Lane, dst: &Lane) -> Result<PolyLine> {
|
|||||||
// The control points are straight out/in from the source/destination lanes, so
|
// The control points are straight out/in from the source/destination lanes, so
|
||||||
// that the car exits and enters at the same angle as the road.
|
// that the car exits and enters at the same angle as the road.
|
||||||
let src_line = src.last_line();
|
let src_line = src.last_line();
|
||||||
let dst_line = dst.first_line().reverse();
|
let dst_line = dst.first_line().reversed();
|
||||||
|
|
||||||
// TODO Tune the 5.0 and pieces
|
// TODO Tune the 5.0 and pieces
|
||||||
let pt1 = src.last_pt();
|
let pt1 = src.last_pt();
|
||||||
|
@ -291,7 +291,7 @@ impl Lane {
|
|||||||
/// pt2 will be endpoint
|
/// pt2 will be endpoint
|
||||||
pub fn end_line(&self, i: IntersectionID) -> Line {
|
pub fn end_line(&self, i: IntersectionID) -> Line {
|
||||||
if i == self.src_i {
|
if i == self.src_i {
|
||||||
self.first_line().reverse()
|
self.first_line().reversed()
|
||||||
} else if i == self.dst_i {
|
} else if i == self.dst_i {
|
||||||
self.last_line()
|
self.last_line()
|
||||||
} else {
|
} else {
|
||||||
|
@ -743,7 +743,7 @@ impl Pedestrian {
|
|||||||
PedState::EnteringParkingLot(pl, ref time_int) => {
|
PedState::EnteringParkingLot(pl, ref time_int) => {
|
||||||
let line = &map.get_pl(pl).sidewalk_line;
|
let line = &map.get_pl(pl).sidewalk_line;
|
||||||
(
|
(
|
||||||
line.reverse()
|
line.reversed()
|
||||||
.percent_along(time_int.percent(now))
|
.percent_along(time_int.percent(now))
|
||||||
.unwrap_or_else(|| line.pt1()),
|
.unwrap_or_else(|| line.pt1()),
|
||||||
line.angle().opposite(),
|
line.angle().opposite(),
|
||||||
|
Loading…
Reference in New Issue
Block a user