refactoring intersection->roads query

This commit is contained in:
Dustin Carlino 2018-11-07 11:47:30 -08:00
parent 9eb1469c89
commit 6e786d5630
6 changed files with 29 additions and 38 deletions

View File

@ -38,8 +38,8 @@ impl ControlStopSign {
}
fn smart_assignment(map: &Map, intersection: IntersectionID) -> ControlStopSign {
if map.get_i(intersection).get_roads(map).len() <= 2 {
return ControlStopSign::for_degenerate_intersection(map, intersection);
if map.get_i(intersection).roads.len() <= 2 {
return ControlStopSign::for_degenerate_and_deadend(map, intersection);
}
// Higher numbers are higher rank roads
@ -127,7 +127,7 @@ impl ControlStopSign {
ss
}
fn for_degenerate_intersection(map: &Map, i: IntersectionID) -> ControlStopSign {
fn for_degenerate_and_deadend(map: &Map, i: IntersectionID) -> ControlStopSign {
let mut ss = ControlStopSign {
intersection: i,
turns: BTreeMap::new(),
@ -146,7 +146,7 @@ impl ControlStopSign {
// intersection geometry), sometimes more turns conflict than really should. For now, just
// detect and fallback to an all-way stop.
if let Err(err) = ss.validate(map, i) {
warn!("Giving up on for_degenerate_intersection({}): {}", i, err);
warn!("Giving up on for_degenerate_and_deadend({}): {}", i, err);
return ControlStopSign::all_way_stop(map, i);
}

View File

@ -35,7 +35,7 @@ impl DrawIntersection {
crosswalks: calculate_crosswalks(inter.id, map),
sidewalk_corners: calculate_corners(inter.id, map),
has_traffic_signal: inter.has_traffic_signal,
should_draw_stop_sign: !inter.has_traffic_signal && !inter.is_degenerate(map),
should_draw_stop_sign: !inter.has_traffic_signal && !inter.is_degenerate(),
}
}

View File

@ -5,7 +5,7 @@ use dimensioned::si;
use geom::Pt2D;
use std::collections::BTreeSet;
use std::fmt;
use {LaneID, Map, RoadID, TurnID};
use {LaneID, RoadID, TurnID};
// TODO reconsider pub usize. maybe outside world shouldnt know.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
@ -32,6 +32,8 @@ pub struct Intersection {
// TODO narrow down when and why. is it just sidewalks in weird cases?
pub incoming_lanes: Vec<LaneID>,
pub outgoing_lanes: Vec<LaneID>,
pub roads: BTreeSet<RoadID>,
}
impl PartialEq for Intersection {
@ -41,20 +43,12 @@ impl PartialEq for Intersection {
}
impl Intersection {
pub fn get_roads(&self, map: &Map) -> BTreeSet<RoadID> {
let mut roads: BTreeSet<RoadID> = BTreeSet::new();
for l in self.incoming_lanes.iter().chain(self.outgoing_lanes.iter()) {
roads.insert(map.get_l(*l).parent);
}
roads
pub fn is_dead_end(&self) -> bool {
self.roads.len() == 1
}
pub fn is_dead_end(&self, map: &Map) -> bool {
self.get_roads(map).len() == 1
}
pub fn is_degenerate(&self, map: &Map) -> bool {
self.get_roads(map).len() == 2
pub fn is_degenerate(&self) -> bool {
self.roads.len() == 2
}
pub fn dump_debug(&self) {

View File

@ -1,7 +1,6 @@
use abstutil::wraparound_get;
use dimensioned::si;
use geom::{Angle, PolyLine, Pt2D};
use std::collections::BTreeSet;
use std::marker;
use {Intersection, Road, RoadID, LANE_THICKNESS};
@ -12,16 +11,13 @@ const DEGENERATE_INTERSECTION_HALF_LENGTH: si::Meter<f64> = si::Meter {
// The polygon should exist entirely within the thick bands around all original roads -- it just
// carves up part of that space, doesn't reach past it.
pub fn intersection_polygon(
i: &Intersection,
road_ids: BTreeSet<RoadID>,
roads: &Vec<Road>,
) -> Vec<Pt2D> {
pub fn intersection_polygon(i: &Intersection, roads: &Vec<Road>) -> Vec<Pt2D> {
// Turn all of the incident roads into two PolyLines (the "forwards" and "backwards" borders of
// the road), both with an endpoint at i.point, and the angle of the last segment of the center
// line.
let mut lines: Vec<(RoadID, Angle, PolyLine, PolyLine)> = road_ids
.into_iter()
let mut lines: Vec<(RoadID, Angle, PolyLine, PolyLine)> = i
.roads
.iter()
.map(|id| {
let r = &roads[id.0];
let fwd_width = LANE_THICKNESS * (r.children_forwards.len() as f64);
@ -37,7 +33,7 @@ pub fn intersection_polygon(
let pl_normal = line.shift(width_normal).unwrap();
let pl_reverse = line.reversed().shift(width_reverse).unwrap().reversed();
(id, line.last_line().angle(), pl_normal, pl_reverse)
(*id, line.last_line().angle(), pl_normal, pl_reverse)
}).collect();
// Sort the polylines by the angle of their last segment.

View File

@ -57,12 +57,11 @@ fn dedupe(turns: Vec<Turn>) -> Vec<Turn> {
}
fn make_driving_turns(i: &Intersection, map: &Map) -> Vec<Turn> {
if i.is_dead_end(map) {
if i.is_dead_end() {
return make_driving_turns_for_dead_end(i, map);
}
// TODO make get_roads do this?
let roads: Vec<&Road> = i.get_roads(map).into_iter().map(|r| map.get_r(r)).collect();
let roads: Vec<&Road> = i.roads.iter().map(|r| map.get_r(*r)).collect();
let mut result = Vec::new();
@ -148,7 +147,7 @@ fn match_up_driving_lanes(
}
fn make_driving_turns_for_dead_end(i: &Intersection, map: &Map) -> Vec<Turn> {
let road = map.get_r(i.get_roads(map).into_iter().next().unwrap());
let road = map.get_r(*i.roads.iter().next().unwrap());
let incoming = filter_driving_lanes(road.incoming_lanes(i.id));
let outgoing = filter_driving_lanes(road.outgoing_lanes(i.id));
if incoming.is_empty() || outgoing.is_empty() {
@ -248,7 +247,7 @@ fn make_turns(
assert_eq!(map.get_l(*l).src_i, parent);
}
let dead_end = map.get_i(parent).is_dead_end(map);
let dead_end = map.get_i(parent).is_dead_end();
let mut result = Vec::new();
for src in incoming {
@ -276,10 +275,10 @@ fn make_walking_turns(i: &Intersection, map: &Map) -> Vec<Turn> {
// Sort roads by the angle into the intersection, so we can reason about sidewalks of adjacent
// roads.
let mut roads: Vec<(RoadID, Angle)> = i
.get_roads(map)
.into_iter()
.roads
.iter()
.map(|id| {
let r = map.get_r(id);
let r = map.get_r(*id);
if r.src_i == i.id {
(r.id, r.center_pts.reversed().last_line().angle())

View File

@ -95,6 +95,7 @@ impl Map {
has_traffic_signal: i.has_traffic_signal,
incoming_lanes: Vec::new(),
outgoing_lanes: Vec::new(),
roads: BTreeSet::new(),
});
pt_to_intersection.insert(HashablePt2D::from(pt), id);
}
@ -135,7 +136,9 @@ impl Map {
}
let (src_i, dst_i) = if lane.reverse_pts { (i2, i1) } else { (i1, i2) };
m.intersections[src_i.0].outgoing_lanes.push(id);
m.intersections[src_i.0].roads.insert(road_id);
m.intersections[dst_i.0].incoming_lanes.push(id);
m.intersections[dst_i.0].roads.insert(road_id);
// TODO probably different behavior for oneways
// TODO need to factor in yellow center lines (but what's the right thing to even do?
@ -181,8 +184,7 @@ impl Map {
panic!("{:?} is orphaned!", i);
}
let incident_roads = i.get_roads(&m);
intersection_polygons.push(make::intersection_polygon(i, incident_roads, &m.roads));
intersection_polygons.push(make::intersection_polygon(i, &m.roads));
}
for (idx, p) in intersection_polygons.into_iter().enumerate() {
m.intersections[idx].polygon = p;
@ -423,7 +425,7 @@ impl Map {
let r = self.get_r(from);
for id in vec![r.src_i, r.dst_i].into_iter() {
roads.extend(self.get_i(id).get_roads(self));
roads.extend(self.get_i(id).roads.clone());
}
roads.into_iter().collect()