avoid crash in make_shared_sidewalk_corner

This commit is contained in:
Dustin Carlino 2019-04-12 13:15:04 -07:00
parent 11a1c3543e
commit 2ecd8a0edb
8 changed files with 35 additions and 10 deletions

View File

@ -76,3 +76,14 @@ pub fn retain_btreemap<K: Ord + Clone, V, F: Fn(&K, &V) -> bool>(
map.remove(&k);
}
}
pub fn contains_duplicates<T: Ord>(vec: &Vec<T>) -> bool {
let mut set = BTreeSet::new();
for item in vec {
if set.contains(item) {
return true;
}
set.insert(item);
}
false
}

View File

@ -8,7 +8,7 @@ mod random;
mod time;
pub use crate::clone::Cloneable;
pub use crate::collections::{retain_btreemap, wraparound_get, MultiMap};
pub use crate::collections::{contains_duplicates, retain_btreemap, wraparound_get, MultiMap};
pub use crate::error::Error;
pub use crate::io::{
deserialize_btreemap, deserialize_multimap, find_next_file, find_prev_file, list_all_objects,

View File

@ -3,7 +3,6 @@
## Boundary clipping
- roads
- why does i96 break on new walking code? it's totally interior...
- what if they start/end in bounds, but briefly dip out? arboretum place east
- intersections

View File

@ -30,6 +30,7 @@ functionality
- stop signs (some directions stop and others dont), traffic signals with
multiple phases
- "reasonable" defaults inferred, editor for the rest
- weird highway on-ramps fixed
- WIP: small intersections, roundabouts merged
- Buildings
- classified by use, notion of residential density

View File

@ -175,6 +175,10 @@ impl Pt2D {
// Didn't find end
None
}
pub fn to_hashable(self) -> HashablePt2D {
HashablePt2D::new(self.x(), self.y())
}
}
impl fmt::Display for Pt2D {

View File

@ -2,7 +2,7 @@ use crate::{
Intersection, IntersectionID, IntersectionType, Lane, LaneID, LaneType, Road, Turn, TurnID,
TurnType, LANE_THICKNESS,
};
use abstutil::{wraparound_get, Timer, Warn};
use abstutil::{Timer, Warn};
use geom::{Distance, Line, PolyLine, Pt2D};
use nbez::{Bez3o, BezCurve, Point2d};
use std::collections::{BTreeSet, HashSet};
@ -217,7 +217,7 @@ fn make_walking_turns(
// TODO -1 and not +1 is brittle... must be the angle sorting
if let Some(l2) = get_sidewalk(
lanes,
wraparound_get(&roads, (idx1 as isize) - 1).outgoing_lanes(i.id),
abstutil::wraparound_get(&roads, (idx1 as isize) - 1).outgoing_lanes(i.id),
) {
if !l1.last_pt().epsilon_eq(l2.first_pt()) {
let geom = make_shared_sidewalk_corner(i, l1, l2, timer);
@ -240,7 +240,7 @@ fn make_walking_turns(
// ramps to get to the next sidewalk.
if let Some(l2) = get_sidewalk(
lanes,
wraparound_get(&roads, (idx1 as isize) - 2).outgoing_lanes(i.id),
abstutil::wraparound_get(&roads, (idx1 as isize) - 2).outgoing_lanes(i.id),
) {
result.extend(make_crosswalks(i.id, l1, l2));
}
@ -282,6 +282,8 @@ fn make_shared_sidewalk_corner(
l2: &Lane,
timer: &mut Timer,
) -> PolyLine {
let baseline = PolyLine::new(vec![l1.last_pt(), l2.first_pt()]);
// Find all of the points on the intersection polygon between the two sidewalks.
let corner1 = l1.last_line().shift_right(LANE_THICKNESS / 2.0).pt2();
let corner2 = l2.first_line().shift_right(LANE_THICKNESS / 2.0).pt1();
@ -295,6 +297,11 @@ fn make_shared_sidewalk_corner(
{
let deduped = Pt2D::approx_dedupe(pts, geom::EPSILON_DIST);
if deduped.len() >= 2 {
if abstutil::contains_duplicates(&deduped.iter().map(|pt| pt.to_hashable()).collect()) {
timer.warn(format!("SharedSidewalkCorner between {} and {} has weird duplicate geometry, so just doing straight line", l1.id, l2.id));
return baseline;
}
pts_between.extend(
PolyLine::new(deduped)
.shift_right(LANE_THICKNESS / 2.0)
@ -312,8 +319,11 @@ fn make_shared_sidewalk_corner(
final_pts.pop();
final_pts.push(l2.first_pt());
}
if abstutil::contains_duplicates(&final_pts.iter().map(|pt| pt.to_hashable()).collect()) {
timer.warn(format!("SharedSidewalkCorner between {} and {} has weird duplicate geometry, so just doing straight line", l1.id, l2.id));
return baseline;
}
let result = PolyLine::new(final_pts);
let baseline = PolyLine::new(vec![l1.last_pt(), l2.first_pt()]);
if result.length() > 10.0 * baseline.length() {
timer.warn(format!("SharedSidewalkCorner between {} and {} explodes to {} long, so just doing straight line", l1.id, l2.id, result.length()));
return baseline;

View File

@ -50,11 +50,11 @@ impl VehiclePathfinder {
g.add_turn(t, map);
}
println!(
/*println!(
"{} nodes, {} edges",
g.graph.node_count(),
g.graph.edge_count()
);
);*/
g
}

View File

@ -71,11 +71,11 @@ impl SidewalkPathfinder {
}
}
println!(
/*println!(
"{} nodes, {} edges",
g.graph.node_count(),
g.graph.edge_count()
);
);*/
g
}