mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 02:33:54 +03:00
refactoring intersection->roads query
This commit is contained in:
parent
9eb1469c89
commit
6e786d5630
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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())
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user