mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 23:15:24 +03:00
Cleaning up a few APIs, now that lanes belong to roads...
This commit is contained in:
parent
0f4a31e915
commit
4c46510342
@ -585,7 +585,7 @@ pub fn draw_unwalkable_roads(ctx: &mut EventCtx, app: &App, opts: &Options) -> D
|
||||
}
|
||||
}
|
||||
// TODO Skip highways
|
||||
batch.push(Color::BLUE.alpha(0.5), road.get_thick_polygon(&app.map));
|
||||
batch.push(Color::BLUE.alpha(0.5), road.get_thick_polygon());
|
||||
}
|
||||
ctx.upload(batch)
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ impl RouteSketcher {
|
||||
for pair in self.route.full_path.windows(2) {
|
||||
// TODO Inefficient!
|
||||
let r = map.find_road_between(pair[0], pair[1]).unwrap();
|
||||
batch.push(Color::RED.alpha(0.5), map.get_r(r).get_thick_polygon(map));
|
||||
batch.push(Color::RED.alpha(0.5), map.get_r(r).get_thick_polygon());
|
||||
}
|
||||
for i in &self.route.full_path {
|
||||
batch.push(
|
||||
@ -145,7 +145,7 @@ impl RouteSketcher {
|
||||
map.simple_path_btwn(self.route.waypoints[0], i)
|
||||
{
|
||||
for r in roads {
|
||||
batch.push(Color::BLUE.alpha(0.5), map.get_r(r).get_thick_polygon(map));
|
||||
batch.push(Color::BLUE.alpha(0.5), map.get_r(r).get_thick_polygon());
|
||||
}
|
||||
for i in intersections {
|
||||
batch.push(Color::BLUE.alpha(0.5), map.get_i(i).polygon.clone());
|
||||
|
@ -81,10 +81,7 @@ impl RoadSelector {
|
||||
for r in &self.roads {
|
||||
batch.push(
|
||||
Color::BLUE.alpha(0.5),
|
||||
app.primary
|
||||
.map
|
||||
.get_r(*r)
|
||||
.get_thick_polygon(&app.primary.map),
|
||||
app.primary.map.get_r(*r).get_thick_polygon(),
|
||||
);
|
||||
}
|
||||
self.intersections.clear();
|
||||
@ -223,10 +220,7 @@ impl RoadSelector {
|
||||
for r in &roads {
|
||||
batch.push(
|
||||
Color::RED.alpha(0.5),
|
||||
app.primary
|
||||
.map
|
||||
.get_r(*r)
|
||||
.get_thick_polygon(&app.primary.map),
|
||||
app.primary.map.get_r(*r).get_thick_polygon(),
|
||||
);
|
||||
}
|
||||
for i in intersections {
|
||||
|
@ -529,7 +529,7 @@ fn search_osm(filter: String, ctx: &mut EventCtx, app: &mut App) -> Transition {
|
||||
.any(|(k, v)| format!("{} = {}", k, v).contains(&filter))
|
||||
{
|
||||
num_matches += 1;
|
||||
batch.push(color, r.get_thick_polygon(map));
|
||||
batch.push(color, r.get_thick_polygon());
|
||||
}
|
||||
}
|
||||
for a in map.all_areas() {
|
||||
|
@ -197,7 +197,7 @@ impl Dataviz {
|
||||
let mut tooltips = Vec::new();
|
||||
for (r, cnt) in per_road.borrow() {
|
||||
tooltips.push((
|
||||
map.get_r(*r).get_thick_polygon(map),
|
||||
map.get_r(*r).get_thick_polygon(),
|
||||
Text::from(format!("{} collisions", prettyprint_usize(*cnt))),
|
||||
));
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ impl SelectSegments {
|
||||
// Point out the road we're using as the template
|
||||
if let Ok(outline) = map
|
||||
.get_r(self.base_road)
|
||||
.get_thick_polygon(map)
|
||||
.get_thick_polygon()
|
||||
.to_outline(Distance::meters(3.0))
|
||||
{
|
||||
batch.push(color.alpha(0.9), outline);
|
||||
@ -94,7 +94,7 @@ impl SelectSegments {
|
||||
let alpha = if self.current.contains(r) { 0.9 } else { 0.5 };
|
||||
batch.push(
|
||||
Fill::ColoredTexture(Color::CYAN.alpha(alpha), Texture::CROSS_HATCH),
|
||||
map.get_r(*r).get_thick_polygon(map),
|
||||
map.get_r(*r).get_thick_polygon(),
|
||||
);
|
||||
}
|
||||
self.draw = ctx.upload(batch);
|
||||
|
@ -627,7 +627,7 @@ fn make_main_panel(
|
||||
]);
|
||||
let mut drag_drop = DragDrop::new(ctx, "lane cards", StackAxis::Horizontal);
|
||||
|
||||
let road_width = road.get_width(map);
|
||||
let road_width = road.get_width();
|
||||
let lanes_ltr = road.lanes_ltr();
|
||||
let lanes_len = lanes_ltr.len();
|
||||
|
||||
@ -987,7 +987,7 @@ fn can_reverse(_: LaneType) -> bool {
|
||||
fn fade_irrelevant(app: &App, r: RoadID) -> GeomBatch {
|
||||
let map = &app.primary.map;
|
||||
let road = map.get_r(r);
|
||||
let mut holes = vec![road.get_thick_polygon(map)];
|
||||
let mut holes = vec![road.get_thick_polygon()];
|
||||
for i in [road.src_i, road.dst_i] {
|
||||
let i = map.get_i(i);
|
||||
holes.push(i.polygon.clone());
|
||||
@ -1013,7 +1013,7 @@ fn draw_drop_position(app: &App, r: RoadID, from: usize, to: usize) -> GeomBatch
|
||||
for (l, _, _) in road.lanes_ltr().into_iter().take(take_num) {
|
||||
width += map.get_l(l).width;
|
||||
}
|
||||
if let Ok(pl) = road.get_left_side(map).shift_right(width) {
|
||||
if let Ok(pl) = road.get_left_side().shift_right(width) {
|
||||
batch.push(app.cs.selected, pl.make_polygons(OUTLINE_THICKNESS));
|
||||
}
|
||||
batch
|
||||
|
@ -949,12 +949,7 @@ pub fn fade_irrelevant(app: &App, members: &BTreeSet<IntersectionID>) -> GeomBat
|
||||
let i = app.primary.map.get_i(*i);
|
||||
holes.push(i.polygon.clone());
|
||||
for r in &i.roads {
|
||||
holes.push(
|
||||
app.primary
|
||||
.map
|
||||
.get_r(*r)
|
||||
.get_thick_polygon(&app.primary.map),
|
||||
);
|
||||
holes.push(app.primary.map.get_r(*r).get_thick_polygon());
|
||||
}
|
||||
}
|
||||
// The convex hull illuminates a bit more of the surrounding area, looks better
|
||||
|
@ -219,7 +219,7 @@ impl TuneRelative {
|
||||
for r in path {
|
||||
let r = map.get_r(r);
|
||||
// TODO Glue polylines together and do dashed_lines
|
||||
batch.push(app.cs.route, r.get_thick_polygon(map));
|
||||
batch.push(app.cs.route, r.get_thick_polygon());
|
||||
dist_btwn += r.center_pts.length();
|
||||
car_dt += r.center_pts.length() / r.speed_limit;
|
||||
}
|
||||
|
@ -558,7 +558,7 @@ fn draw_problems(
|
||||
);
|
||||
details.tooltips.push((
|
||||
match on {
|
||||
Traversable::Lane(l) => map.get_parent(*l).get_thick_polygon(map),
|
||||
Traversable::Lane(l) => map.get_parent(*l).get_thick_polygon(),
|
||||
Traversable::Turn(t) => map.get_i(t.parent).polygon.clone(),
|
||||
},
|
||||
Text::from("A vehicle wanted to over-take this cyclist near here."),
|
||||
|
@ -88,7 +88,7 @@ impl DrawNetworkLayer {
|
||||
} else {
|
||||
Fill::Color(color)
|
||||
},
|
||||
r.center_pts.make_polygons(thickness * r.get_width(map)),
|
||||
r.center_pts.make_polygons(thickness * r.get_width()),
|
||||
);
|
||||
|
||||
// Arbitrarily pick a color when two different types of roads meet
|
||||
|
@ -381,7 +381,7 @@ impl Layers {
|
||||
};
|
||||
// TODO If it's a bike element, should probably thicken for the unzoomed scale...
|
||||
// the maximum amount?
|
||||
batch.push(color, r.get_thick_polygon(&app.primary.map));
|
||||
batch.push(color, r.get_thick_polygon());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -530,7 +530,7 @@ fn export_geometry(map: &Map, i: IntersectionID) -> geojson::GeoJson {
|
||||
bbox: None,
|
||||
geometry: Some(
|
||||
r.center_pts
|
||||
.to_thick_ring(r.get_width(map))
|
||||
.to_thick_ring(r.get_width())
|
||||
.translate(-center.x(), -center.y())
|
||||
.to_geojson(None),
|
||||
),
|
||||
@ -573,7 +573,7 @@ fn export_all_geometry(map: &Map) -> geojson::GeoJson {
|
||||
bbox: None,
|
||||
geometry: Some(
|
||||
r.center_pts
|
||||
.to_thick_ring(r.get_width(map))
|
||||
.to_thick_ring(r.get_width())
|
||||
.to_geojson(gps_bounds),
|
||||
),
|
||||
id: None,
|
||||
|
@ -130,7 +130,7 @@ fn generate_buildings_on_empty_residential_roads(
|
||||
quadtree = QuadTree::default(map.get_bounds().as_bbox());
|
||||
let mut static_polygons = Vec::new();
|
||||
for r in map.all_roads() {
|
||||
let poly = r.get_thick_polygon(map);
|
||||
let poly = r.get_thick_polygon();
|
||||
quadtree.insert_with_box(static_polygons.len(), poly.get_bounds().as_bbox());
|
||||
static_polygons.push(poly);
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ impl DrawIntersection {
|
||||
.iter()
|
||||
.map(|r| {
|
||||
let road = map.get_r(*r);
|
||||
let half_width = road.get_half_width(map);
|
||||
let half_width = road.get_half_width();
|
||||
let left = road.center_pts.must_shift_left(half_width);
|
||||
let right = road.center_pts.must_shift_right(half_width);
|
||||
if road.src_i == i.id {
|
||||
|
@ -221,7 +221,7 @@ impl DrawMap {
|
||||
let mut unzoomed_pieces: Vec<(isize, Color, Polygon)> = Vec::new();
|
||||
|
||||
for r in map.all_roads() {
|
||||
let width = r.get_width(map);
|
||||
let width = r.get_width();
|
||||
|
||||
unzoomed_pieces.push((
|
||||
10 * r.zorder,
|
||||
|
@ -42,7 +42,7 @@ impl DrawRoad {
|
||||
let ((l1, dir1, lt1), (_, dir2, lt2)) = (pair[0], pair[1]);
|
||||
width += app.map().get_l(l1).width;
|
||||
if dir1 != dir2 && lt1.is_for_moving_vehicles() && lt2.is_for_moving_vehicles() {
|
||||
let pl = r.get_left_side(app.map()).must_shift_right(width);
|
||||
let pl = r.get_left_side().must_shift_right(width);
|
||||
batch.extend(
|
||||
center_line_color,
|
||||
pl.dashed_lines(
|
||||
@ -132,11 +132,11 @@ impl Renderable for DrawRoad {
|
||||
|
||||
fn get_outline(&self, map: &Map) -> Polygon {
|
||||
// Highlight the entire thing, not just an outline
|
||||
map.get_r(self.id).get_thick_polygon(map)
|
||||
map.get_r(self.id).get_thick_polygon()
|
||||
}
|
||||
|
||||
fn contains_pt(&self, pt: Pt2D, map: &Map) -> bool {
|
||||
map.get_r(self.id).get_thick_polygon(map).contains_pt(pt)
|
||||
map.get_r(self.id).get_thick_polygon().contains_pt(pt)
|
||||
}
|
||||
|
||||
fn get_zorder(&self) -> isize {
|
||||
|
@ -41,7 +41,7 @@ impl<'a> ColorDiscrete<'a> {
|
||||
pub fn add_l<I: AsRef<str>>(&mut self, l: LaneID, category: I) {
|
||||
let color = self.colors[category.as_ref()];
|
||||
self.unzoomed
|
||||
.push(color, self.map.get_parent(l).get_thick_polygon(self.map));
|
||||
.push(color, self.map.get_parent(l).get_thick_polygon());
|
||||
let lane = self.map.get_l(l);
|
||||
self.zoomed.push(
|
||||
color.alpha(0.4),
|
||||
@ -52,11 +52,9 @@ impl<'a> ColorDiscrete<'a> {
|
||||
pub fn add_r<I: AsRef<str>>(&mut self, r: RoadID, category: I) {
|
||||
let color = self.colors[category.as_ref()];
|
||||
self.unzoomed
|
||||
.push(color, self.map.get_r(r).get_thick_polygon(self.map));
|
||||
self.zoomed.push(
|
||||
color.alpha(0.4),
|
||||
self.map.get_r(r).get_thick_polygon(self.map),
|
||||
);
|
||||
.push(color, self.map.get_r(r).get_thick_polygon());
|
||||
self.zoomed
|
||||
.push(color.alpha(0.4), self.map.get_r(r).get_thick_polygon());
|
||||
}
|
||||
|
||||
pub fn add_i<I: AsRef<str>>(&mut self, i: IntersectionID, category: I) {
|
||||
@ -274,7 +272,7 @@ impl<'a> ColorNetwork<'a> {
|
||||
|
||||
pub fn add_l(&mut self, l: LaneID, color: Color) {
|
||||
self.unzoomed
|
||||
.push(color, self.map.get_parent(l).get_thick_polygon(self.map));
|
||||
.push(color, self.map.get_parent(l).get_thick_polygon());
|
||||
let lane = self.map.get_l(l);
|
||||
self.zoomed.push(
|
||||
color.alpha(0.4),
|
||||
@ -284,11 +282,9 @@ impl<'a> ColorNetwork<'a> {
|
||||
|
||||
pub fn add_r(&mut self, r: RoadID, color: Color) {
|
||||
self.unzoomed
|
||||
.push(color, self.map.get_r(r).get_thick_polygon(self.map));
|
||||
self.zoomed.push(
|
||||
color.alpha(0.4),
|
||||
self.map.get_r(r).get_thick_polygon(self.map),
|
||||
);
|
||||
.push(color, self.map.get_r(r).get_thick_polygon());
|
||||
self.zoomed
|
||||
.push(color.alpha(0.4), self.map.get_r(r).get_thick_polygon());
|
||||
}
|
||||
|
||||
pub fn add_i(&mut self, i: IntersectionID, color: Color) {
|
||||
|
@ -92,7 +92,7 @@ impl CrossStreet {
|
||||
let mut batch = GeomBatch::new();
|
||||
for r in &first {
|
||||
let road = map.get_r(*r);
|
||||
batch.push(Color::RED, road.get_thick_polygon(map));
|
||||
batch.push(Color::RED, road.get_thick_polygon());
|
||||
for i in [road.src_i, road.dst_i] {
|
||||
for cross in &map.get_i(i).roads {
|
||||
cross_streets.insert(*cross);
|
||||
|
@ -559,7 +559,7 @@ fn modify_lanes(map: &mut Map, r: RoadID, lanes_ltr: Vec<LaneSpec>, effects: &mu
|
||||
let mut modified_lanes = BTreeSet::new();
|
||||
for r in road_geom_changed {
|
||||
effects.changed_roads.insert(r);
|
||||
let lane_specs = map.get_r(r).lane_specs(map);
|
||||
let lane_specs = map.get_r(r).lane_specs();
|
||||
let road = &mut map.roads[r.0];
|
||||
road.recreate_lanes(lane_specs);
|
||||
for lane in &road.lanes {
|
||||
@ -613,7 +613,7 @@ fn recalculate_intersection_polygon(
|
||||
let half_width = if r.id == changed_road {
|
||||
changed_road_width / 2.0
|
||||
} else {
|
||||
r.get_half_width(map)
|
||||
r.get_half_width()
|
||||
};
|
||||
|
||||
let mut trimmed_center_pts = r.center_pts.clone();
|
||||
@ -784,7 +784,7 @@ impl Map {
|
||||
pub fn get_r_edit(&self, r: RoadID) -> EditRoad {
|
||||
let r = self.get_r(r);
|
||||
EditRoad {
|
||||
lanes_ltr: r.lane_specs(self),
|
||||
lanes_ltr: r.lane_specs(),
|
||||
speed_limit: r.speed_limit,
|
||||
access_restrictions: r.access_restrictions.clone(),
|
||||
}
|
||||
@ -877,17 +877,15 @@ impl Map {
|
||||
// Might need to update bus stops.
|
||||
if enforce_valid {
|
||||
for id in &effects.changed_roads {
|
||||
let stops = self.get_r(*id).all_bus_stops(self);
|
||||
let stops = self.get_r(*id).all_bus_stops();
|
||||
for s in stops {
|
||||
let sidewalk_pos = self.get_bs(s).sidewalk_pos;
|
||||
// Must exist, because we aren't allowed to orphan a bus stop.
|
||||
let driving_lane = self
|
||||
.get_r(*id)
|
||||
.find_closest_lane(
|
||||
sidewalk_pos.lane(),
|
||||
|l| PathConstraints::Bus.can_use(l, self),
|
||||
self,
|
||||
)
|
||||
.find_closest_lane(sidewalk_pos.lane(), |l| {
|
||||
PathConstraints::Bus.can_use(l, self)
|
||||
})
|
||||
.unwrap();
|
||||
let driving_pos = sidewalk_pos.equiv_pos(driving_lane, self);
|
||||
self.bus_stops.get_mut(&s).unwrap().driving_pos = driving_pos;
|
||||
|
@ -153,7 +153,7 @@ pub fn snap_driveway(
|
||||
let sidewalk_lane = sidewalk_pos.lane();
|
||||
if let Some(driving_pos) = map
|
||||
.get_parent(sidewalk_lane)
|
||||
.find_closest_lane(sidewalk_lane, |l| PathConstraints::Car.can_use(l, map), map)
|
||||
.find_closest_lane(sidewalk_lane, |l| PathConstraints::Car.can_use(l, map))
|
||||
.and_then(|l| {
|
||||
sidewalk_pos
|
||||
.equiv_pos(l, map)
|
||||
|
@ -316,9 +316,7 @@ fn all_walk_all_yield(map: &Map, i: IntersectionID) -> ControlTrafficSignal {
|
||||
fn stage_per_road(map: &Map, i: IntersectionID) -> ControlTrafficSignal {
|
||||
let mut ts = new(i, map);
|
||||
|
||||
let sorted_roads = map
|
||||
.get_i(i)
|
||||
.get_roads_sorted_by_incoming_angle(map.all_roads());
|
||||
let sorted_roads = map.get_i(i).get_roads_sorted_by_incoming_angle(map);
|
||||
for idx in 0..sorted_roads.len() {
|
||||
let r = sorted_roads[idx];
|
||||
let adj1 = *abstutil::wraparound_get(&sorted_roads, (idx as isize) - 1);
|
||||
|
@ -284,11 +284,9 @@ impl Matcher {
|
||||
} else {
|
||||
let sidewalk = map
|
||||
.get_parent(driving_pos.lane())
|
||||
.find_closest_lane(
|
||||
driving_pos.lane(),
|
||||
|l| PathConstraints::Pedestrian.can_use(l, map),
|
||||
map,
|
||||
)
|
||||
.find_closest_lane(driving_pos.lane(), |l| {
|
||||
PathConstraints::Pedestrian.can_use(l, map)
|
||||
})
|
||||
.ok_or_else(|| anyhow!("driving {} to sidewalk failed", driving_pos.lane()))?;
|
||||
driving_pos.equiv_pos(sidewalk, map)
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ pub fn make_walking_turns(map: &Map, i: &Intersection) -> Vec<Turn> {
|
||||
let driving_side = map.config.driving_side;
|
||||
|
||||
let roads: Vec<&Road> = i
|
||||
.get_roads_sorted_by_incoming_angle(map.all_roads())
|
||||
.get_roads_sorted_by_incoming_angle(map)
|
||||
.into_iter()
|
||||
.map(|id| map.get_r(id))
|
||||
.collect();
|
||||
@ -202,7 +202,7 @@ fn make_walking_turns_v2(map: &Map, i: &Intersection) -> Vec<Turn> {
|
||||
// those in order, remembering what roads don't have them.
|
||||
let mut lanes: Vec<Option<&Lane>> = Vec::new();
|
||||
let mut num_sidewalks = 0;
|
||||
let mut sorted_roads = i.get_roads_sorted_by_incoming_angle(map.all_roads());
|
||||
let mut sorted_roads = i.get_roads_sorted_by_incoming_angle(map);
|
||||
// And for left-handed driving, we need to walk around in the opposite order.
|
||||
if driving_side == DrivingSide::Left {
|
||||
sorted_roads.reverse();
|
||||
|
@ -520,11 +520,10 @@ impl Map {
|
||||
// TODO Making driving_connection do this.
|
||||
pub fn find_driving_lane_near_building(&self, b: BuildingID) -> LaneID {
|
||||
let sidewalk = self.get_b(b).sidewalk();
|
||||
if let Some(l) = self.get_parent(sidewalk).find_closest_lane(
|
||||
sidewalk,
|
||||
|l| PathConstraints::Car.can_use(l, self),
|
||||
self,
|
||||
) {
|
||||
if let Some(l) = self
|
||||
.get_parent(sidewalk)
|
||||
.find_closest_lane(sidewalk, |l| PathConstraints::Car.can_use(l, self))
|
||||
{
|
||||
if !self.get_l(l).driving_blackhole {
|
||||
return l;
|
||||
}
|
||||
|
@ -150,11 +150,9 @@ impl Building {
|
||||
/// The polyline goes from the building to the driving position
|
||||
// TODO Make this handle parking_blackhole
|
||||
pub fn driving_connection(&self, map: &Map) -> Option<(Position, PolyLine)> {
|
||||
let lane = map.get_parent(self.sidewalk()).find_closest_lane(
|
||||
self.sidewalk(),
|
||||
|l| PathConstraints::Car.can_use(l, map),
|
||||
map,
|
||||
)?;
|
||||
let lane = map
|
||||
.get_parent(self.sidewalk())
|
||||
.find_closest_lane(self.sidewalk(), |l| PathConstraints::Car.can_use(l, map))?;
|
||||
// TODO Do we need to insist on this buffer, now that we can make cars gradually appear?
|
||||
let pos = self
|
||||
.sidewalk_pos
|
||||
@ -217,11 +215,11 @@ impl Building {
|
||||
}
|
||||
|
||||
fn sidewalk_to_bike(sidewalk_pos: Position, map: &Map) -> Option<(Position, Position)> {
|
||||
let lane = map.get_parent(sidewalk_pos.lane()).find_closest_lane(
|
||||
sidewalk_pos.lane(),
|
||||
|l| !l.biking_blackhole && PathConstraints::Bike.can_use(l, map),
|
||||
map,
|
||||
)?;
|
||||
let lane = map
|
||||
.get_parent(sidewalk_pos.lane())
|
||||
.find_closest_lane(sidewalk_pos.lane(), |l| {
|
||||
!l.biking_blackhole && PathConstraints::Bike.can_use(l, map)
|
||||
})?;
|
||||
// No buffer needed
|
||||
Some((sidewalk_pos.equiv_pos(lane, map), sidewalk_pos))
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
||||
use abstutil::{deserialize_usize, serialize_usize};
|
||||
use geom::{Distance, Polygon};
|
||||
|
||||
use crate::{osm, DirectedRoadID, LaneID, Map, PathConstraints, Road, RoadID, Turn};
|
||||
use crate::{osm, DirectedRoadID, LaneID, Map, PathConstraints, RoadID, Turn};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct IntersectionID(
|
||||
@ -130,11 +130,11 @@ impl Intersection {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn get_roads_sorted_by_incoming_angle(&self, all_roads: &[Road]) -> Vec<RoadID> {
|
||||
pub fn get_roads_sorted_by_incoming_angle(&self, map: &Map) -> Vec<RoadID> {
|
||||
let center = self.polygon.center();
|
||||
let mut roads: Vec<RoadID> = self.roads.iter().cloned().collect();
|
||||
roads.sort_by_key(|id| {
|
||||
let r = &all_roads[id.0];
|
||||
let r = map.get_r(*id);
|
||||
let endpt = if r.src_i == self.id {
|
||||
r.center_pts.first_pt()
|
||||
} else if r.dst_i == self.id {
|
||||
@ -153,7 +153,7 @@ impl Intersection {
|
||||
/// carriageway (split into two one-ways).
|
||||
pub fn get_sorted_incoming_roads(&self, map: &Map) -> Vec<RoadID> {
|
||||
let mut roads = Vec::new();
|
||||
for r in self.get_roads_sorted_by_incoming_angle(map.all_roads()) {
|
||||
for r in self.get_roads_sorted_by_incoming_angle(map) {
|
||||
if !map.get_r(r).incoming_lanes(self.id).is_empty() {
|
||||
roads.push(r);
|
||||
}
|
||||
|
@ -476,9 +476,7 @@ impl Lane {
|
||||
let i = if fwd { l.dst_i } else { l.src_i };
|
||||
// TODO Remove these debug statements entirely after stabilizing this
|
||||
//println!("{}, fwd={}, pointing to {}", current, fwd, i);
|
||||
let mut roads = map
|
||||
.get_i(i)
|
||||
.get_roads_sorted_by_incoming_angle(map.all_roads());
|
||||
let mut roads = map.get_i(i).get_roads_sorted_by_incoming_angle(map);
|
||||
roads.retain(|r| !map.get_r(*r).is_footway());
|
||||
let idx = roads.iter().position(|r| *r == l.parent).unwrap();
|
||||
// Get the next road counter-clockwise
|
||||
|
@ -170,20 +170,20 @@ impl Road {
|
||||
self.lanes_ltr.clone()
|
||||
}
|
||||
|
||||
pub fn lane_specs(&self, map: &Map) -> Vec<LaneSpec> {
|
||||
self.lanes_ltr()
|
||||
.into_iter()
|
||||
.map(|(l, dir, lt)| LaneSpec {
|
||||
lt,
|
||||
dir,
|
||||
width: map.get_l(l).width,
|
||||
pub(crate) fn lane_specs(&self) -> Vec<LaneSpec> {
|
||||
self.lanes
|
||||
.iter()
|
||||
.map(|l| LaneSpec {
|
||||
lt: l.lane_type,
|
||||
dir: l.dir,
|
||||
width: l.width,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Gets the left PolyLine of the road
|
||||
pub fn get_left_side(&self, map: &Map) -> PolyLine {
|
||||
self.center_pts.must_shift_left(self.get_half_width(map))
|
||||
pub fn get_left_side(&self) -> PolyLine {
|
||||
self.center_pts.must_shift_left(self.get_half_width())
|
||||
}
|
||||
|
||||
/// Counting from the left side of the road
|
||||
@ -207,8 +207,8 @@ impl Road {
|
||||
panic!("{} doesn't contain {}", self.id, lane);
|
||||
}
|
||||
|
||||
pub fn parking_to_driving(&self, parking: LaneID, map: &Map) -> Option<LaneID> {
|
||||
self.find_closest_lane(parking, |l| l.is_driving(), map)
|
||||
pub fn parking_to_driving(&self, parking: LaneID) -> Option<LaneID> {
|
||||
self.find_closest_lane(parking, |l| l.is_driving())
|
||||
}
|
||||
|
||||
pub(crate) fn speed_limit_from_osm(&self) -> Speed {
|
||||
@ -255,15 +255,14 @@ impl Road {
|
||||
&self,
|
||||
from: LaneID,
|
||||
filter: F,
|
||||
map: &Map,
|
||||
) -> Option<LaneID> {
|
||||
let our_idx = self.offset(from) as isize;
|
||||
self.lanes_ltr()
|
||||
.into_iter()
|
||||
self.lanes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, (l, _, _))| {
|
||||
if (idx as isize) != our_idx && filter(map.get_l(l)) {
|
||||
Some((idx, l))
|
||||
.filter_map(|(idx, l)| {
|
||||
if (idx as isize) != our_idx && filter(l) {
|
||||
Some((idx, l.id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -275,15 +274,14 @@ impl Road {
|
||||
/// This is the FIRST yellow line where the direction of the road changes. If multiple direction
|
||||
/// changes happen, the result is kind of arbitrary.
|
||||
pub fn get_dir_change_pl(&self, map: &Map) -> PolyLine {
|
||||
let mut found: Option<LaneID> = None;
|
||||
for pair in self.lanes_ltr().windows(2) {
|
||||
let ((l1, dir1, _), (_, dir2, _)) = (pair[0], pair[1]);
|
||||
if dir1 != dir2 {
|
||||
found = Some(l1);
|
||||
let mut found: Option<&Lane> = None;
|
||||
for pair in self.lanes.windows(2) {
|
||||
if pair[0].dir != pair[1].dir {
|
||||
found = Some(&pair[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let lane = map.get_l(found.unwrap_or(self.lanes_ltr()[0].0));
|
||||
let lane = found.unwrap_or(&self.lanes[0]);
|
||||
// There's a weird edge case with single lane light rail on left-handed maps...
|
||||
let shifted = if map.get_config().driving_side == DrivingSide::Right || found.is_none() {
|
||||
lane.lane_center_pts.must_shift_left(lane.width / 2.0)
|
||||
@ -297,16 +295,16 @@ impl Road {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_half_width(&self, map: &Map) -> Distance {
|
||||
self.get_width(map) / 2.0
|
||||
pub fn get_half_width(&self) -> Distance {
|
||||
self.get_width() / 2.0
|
||||
}
|
||||
|
||||
pub fn get_width(&self, map: &Map) -> Distance {
|
||||
pub fn get_width(&self) -> Distance {
|
||||
self.lanes.iter().map(|l| l.width).sum::<Distance>()
|
||||
}
|
||||
|
||||
pub fn get_thick_polygon(&self, map: &Map) -> Polygon {
|
||||
self.center_pts.make_polygons(self.get_width(map))
|
||||
pub fn get_thick_polygon(&self) -> Polygon {
|
||||
self.center_pts.make_polygons(self.get_width())
|
||||
}
|
||||
|
||||
/// Creates the thick polygon representing one half of the road. For roads with multipe
|
||||
@ -315,11 +313,11 @@ impl Road {
|
||||
pub fn get_half_polygon(&self, dir: Direction, map: &Map) -> Result<Polygon> {
|
||||
let mut width_fwd = Distance::ZERO;
|
||||
let mut width_back = Distance::ZERO;
|
||||
for (l, dir, _) in self.lanes_ltr() {
|
||||
if dir == Direction::Fwd {
|
||||
width_fwd += map.get_l(l).width;
|
||||
for l in &self.lanes {
|
||||
if l.dir == Direction::Fwd {
|
||||
width_fwd += l.width;
|
||||
} else {
|
||||
width_back += map.get_l(l).width;
|
||||
width_back += l.width;
|
||||
}
|
||||
}
|
||||
let center = self.get_dir_change_pl(map);
|
||||
@ -402,7 +400,7 @@ impl Road {
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn all_bus_stops(&self, map: &Map) -> Vec<BusStopID> {
|
||||
pub fn all_bus_stops(&self) -> Vec<BusStopID> {
|
||||
self.lanes
|
||||
.iter()
|
||||
.flat_map(|l| l.bus_stops.iter())
|
||||
|
@ -376,7 +376,7 @@ impl Movement {
|
||||
}
|
||||
|
||||
let mut pl = r
|
||||
.get_left_side(map)
|
||||
.get_left_side()
|
||||
.must_shift_right((leftmost + rightmost) / 2.0);
|
||||
if self.id.from.dir == Direction::Back {
|
||||
pl = pl.reversed();
|
||||
|
@ -623,11 +623,9 @@ impl PathRequest {
|
||||
return None;
|
||||
}
|
||||
let offside_dir = start_lane.dir.opposite();
|
||||
let alt_lane = road.find_closest_lane(
|
||||
start_lane.id,
|
||||
|l| l.dir == offside_dir && constraints.can_use(l, map),
|
||||
map,
|
||||
)?;
|
||||
let alt_lane = road.find_closest_lane(start_lane.id, |l| {
|
||||
l.dir == offside_dir && constraints.can_use(l, map)
|
||||
})?;
|
||||
// TODO Do we need buffer_dist like driving_connection does?
|
||||
let pos = start.equiv_pos(alt_lane, map);
|
||||
let number_lanes_between =
|
||||
|
@ -74,25 +74,25 @@ impl ParkingMapper {
|
||||
{
|
||||
todo.insert(r.orig_id.osm_way_id);
|
||||
if show == Show::ToDo {
|
||||
batch.push(color, map.get_r(r.id).get_thick_polygon(map));
|
||||
batch.push(color, map.get_r(r.id).get_thick_polygon());
|
||||
}
|
||||
} else {
|
||||
done.insert(r.orig_id.osm_way_id);
|
||||
if show == Show::Done {
|
||||
batch.push(color, map.get_r(r.id).get_thick_polygon(map));
|
||||
batch.push(color, map.get_r(r.id).get_thick_polygon());
|
||||
}
|
||||
}
|
||||
}
|
||||
if show == Show::DividedHighways {
|
||||
for r in find_divided_highways(app) {
|
||||
batch.push(color, map.get_r(r).get_thick_polygon(map));
|
||||
batch.push(color, map.get_r(r).get_thick_polygon());
|
||||
}
|
||||
}
|
||||
if show == Show::UnmappedDividedHighways {
|
||||
for r in find_divided_highways(app) {
|
||||
let r = map.get_r(r);
|
||||
if !r.osm_tags.is("dual_carriageway", "yes") {
|
||||
batch.push(color, r.get_thick_polygon(map));
|
||||
batch.push(color, r.get_thick_polygon());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -217,7 +217,7 @@ impl State<App> for ParkingMapper {
|
||||
for r in map.all_roads() {
|
||||
if r.orig_id.osm_way_id == way {
|
||||
ids.insert(r.id);
|
||||
batch.push(Color::CYAN.alpha(0.5), r.get_thick_polygon(map));
|
||||
batch.push(Color::CYAN.alpha(0.5), r.get_thick_polygon());
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,13 +405,13 @@ impl ChangeWay {
|
||||
batch.push(
|
||||
Color::GREEN,
|
||||
r.center_pts
|
||||
.must_shift_right(r.get_half_width(map))
|
||||
.must_shift_right(r.get_half_width())
|
||||
.make_polygons(thickness),
|
||||
);
|
||||
batch.push(
|
||||
Color::BLUE,
|
||||
r.center_pts
|
||||
.must_shift_left(r.get_half_width(map))
|
||||
.must_shift_left(r.get_half_width())
|
||||
.make_polygons(thickness),
|
||||
);
|
||||
}
|
||||
@ -650,7 +650,7 @@ fn find_overlapping_stuff(app: &App, timer: &mut Timer) -> Vec<Polygon> {
|
||||
for (r, _, _) in closest.all_close_pts(b.label_center, Distance::meters(500.0)) {
|
||||
if !b
|
||||
.polygon
|
||||
.intersection(&map.get_r(r).get_thick_polygon(map))
|
||||
.intersection(&map.get_r(r).get_thick_polygon())
|
||||
.is_empty()
|
||||
{
|
||||
polygons.push(b.polygon.clone());
|
||||
@ -664,7 +664,7 @@ fn find_overlapping_stuff(app: &App, timer: &mut Timer) -> Vec<Polygon> {
|
||||
for (r, _, _) in closest.all_close_pts(pl.polygon.center(), Distance::meters(500.0)) {
|
||||
if !pl
|
||||
.polygon
|
||||
.intersection(&map.get_r(r).get_thick_polygon(map))
|
||||
.intersection(&map.get_r(r).get_thick_polygon())
|
||||
.is_empty()
|
||||
{
|
||||
polygons.push(pl.polygon.clone());
|
||||
|
@ -69,7 +69,7 @@ impl Player {
|
||||
let road = app.map.get_r(r);
|
||||
if valid_roads.contains(&r)
|
||||
&& !road.is_light_rail()
|
||||
&& road.get_thick_polygon(&app.map).contains_pt(pos)
|
||||
&& road.get_thick_polygon().contains_pt(pos)
|
||||
{
|
||||
// Where along the road are we?
|
||||
let pt_on_center_line = road.center_pts.project_pt(pos);
|
||||
@ -151,7 +151,7 @@ impl Player {
|
||||
On::Intersection(i) => app.map.get_i(i).polygon.clone().into_ring(),
|
||||
On::Road(r, _, _) => {
|
||||
let road = app.map.get_r(r);
|
||||
road.center_pts.to_thick_ring(road.get_width(&app.map))
|
||||
road.center_pts.to_thick_ring(road.get_width())
|
||||
}
|
||||
};
|
||||
// TODO Brittle order, but should be the first from the PolyLine's
|
||||
|
@ -671,8 +671,7 @@ impl ParkingLane {
|
||||
return None;
|
||||
}
|
||||
|
||||
let driving_lane = if let Some(l) = map.get_parent(lane.id).parking_to_driving(lane.id, map)
|
||||
{
|
||||
let driving_lane = if let Some(l) = map.get_parent(lane.id).parking_to_driving(lane.id) {
|
||||
l
|
||||
} else {
|
||||
// Serious enough to blow up loudly.
|
||||
@ -681,9 +680,9 @@ impl ParkingLane {
|
||||
if map.get_l(driving_lane).driving_blackhole {
|
||||
return None;
|
||||
}
|
||||
let sidewalk = if let Some(l) =
|
||||
map.get_parent(lane.id)
|
||||
.find_closest_lane(lane.id, |l| l.is_walkable(), map)
|
||||
let sidewalk = if let Some(l) = map
|
||||
.get_parent(lane.id)
|
||||
.find_closest_lane(lane.id, |l| l.is_walkable())
|
||||
{
|
||||
l
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user