just trying to detect the weirdness that is O253. pretty much works.

This commit is contained in:
Dustin Carlino 2019-02-06 15:07:37 -08:00
parent d56f04167b
commit 3ee73668f2
3 changed files with 85 additions and 4 deletions

View File

@ -8,9 +8,13 @@
- bad polyline shifting causes jagged lane endings in generalized_trim_back
- handle small roads again somehow?
- o40 has a long cut when merged, why not hit in the middle?
- what if we allow intersections between infinite lines for merged cases?
- what's going on with O253 generally?
- need a way to see the original untrimmed roads... want to draw them at the end, in a plugin
- experiment with resolution
- try it bigger
- VERY overeager... ate half of the map
- deal with loop roads
- deal with loop roads?
- manually draw a picture of the weird intersection to see what would look reasonable. i think we need original road bands from deleted stuff to make decent polygons.

View File

@ -435,6 +435,25 @@ impl PolyLine {
}
b
}
// In one side and out another.
pub fn crosses_polygon(&self, pts: &Vec<Pt2D>) -> bool {
let mut crossings = 0;
for l1 in self.lines() {
for pair in pts.windows(2) {
if l1.intersection(&Line::new(pair[0], pair[1])).is_some() {
crossings += 1;
}
}
}
if crossings > 2 {
panic!(
"{} crosses polygon more than two times! What happened?",
self
);
}
crossings == 2
}
}
impl fmt::Display for PolyLine {

View File

@ -4,10 +4,10 @@ mod merge;
use crate::raw_data::{StableIntersectionID, StableRoadID};
use crate::{raw_data, MapEdits, LANE_THICKNESS};
use abstutil::Timer;
use abstutil::{note, Timer};
use geom::{Bounds, Distance, GPSBounds, PolyLine, Pt2D};
use serde_derive::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet};
use std::collections::{BTreeMap, BTreeSet, HashSet};
#[derive(Serialize, Deserialize)]
pub struct InitialMap {
@ -127,6 +127,38 @@ impl InitialMap {
i.polygon = geometry::intersection_polygon(i, &mut m.roads);
}
// TODO Move to a module if this grows.
// Look for road center lines that hit an intersection polygon that isn't one of their
// endpoints.
timer.start_iter(
"look for roads crossing intersections in strange ways",
m.roads.len(),
);
for r in m.roads.values() {
timer.next();
// TODO Prune search.
for i in m.intersections.values() {
if r.src_i == i.id || r.dst_i == i.id {
continue;
}
if !r.trimmed_center_pts.crosses_polygon(&i.polygon) {
continue;
}
// TODO Avoid some false positives by seeing if this road is "close" to the
// intersection it crosses. This probably needs more tuning. It avoids expected
// tunnel/bridge crossings.
if !m.floodfill(i.id, 5).contains(&r.id) {
continue;
}
// TODO Still seeing false positives due to lack of short road merging.
note(format!("{} is suspicious -- it hits {}", r.id, i.id));
// TODO Resolution... Change the road's src/dst intersection and recalculate?
}
}
merge::short_roads(&mut m);
m
@ -142,4 +174,30 @@ impl InitialMap {
abstutil::write_binary(&path, self).expect(&format!("Saving {} failed", path));
info!("Saved {}", path);
}
fn floodfill(&self, start: StableIntersectionID, steps: usize) -> HashSet<StableRoadID> {
let mut seen: HashSet<StableRoadID> = HashSet::new();
let mut queue: Vec<(StableRoadID, usize)> = self.intersections[&start]
.roads
.iter()
.map(|r| (*r, 1))
.collect();
while !queue.is_empty() {
let (r, count) = queue.pop().unwrap();
if seen.contains(&r) {
continue;
}
seen.insert(r);
if count < steps {
for next in self.intersections[&self.roads[&r].src_i]
.roads
.iter()
.chain(self.intersections[&self.roads[&r].dst_i].roads.iter())
{
queue.push((*next, count + 1));
}
}
}
seen
}
}