mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 07:25:47 +03:00
work around path traces that're breaking PolyLine
This commit is contained in:
parent
1cdbe0ea81
commit
01a4abb64a
@ -467,7 +467,7 @@ fn recalc_intersection_geom(id: IntersectionID, map: &Map, g: &mut GfxCtx) {
|
||||
let (pl1, width1) = wraparound_get(&road_centers, idx);
|
||||
let (pl2, width2) = wraparound_get(&road_centers, idx + 1);
|
||||
|
||||
let glued = pl1.clone().extend(&pl2.reversed());
|
||||
let glued = pl1.clone().extend(&pl2.reversed()).unwrap();
|
||||
let max_width = (*width1).max(*width2);
|
||||
let poly = Polygon::new(&glued.to_thick_boundary_pts(max_width));
|
||||
g.draw_polygon(Color::RED.alpha(0.4), &poly);
|
||||
|
@ -21,7 +21,7 @@ impl TripsVisualizer {
|
||||
let trips = ctx.loading_screen("load trip data", |_, mut timer| {
|
||||
let popdat: PopDat = abstutil::read_binary("../data/shapes/popdat", &mut timer)
|
||||
.expect("Couldn't load popdat");
|
||||
let mut all_trips = clip_trips(&popdat, ui, &mut timer);
|
||||
let mut all_trips = clip_trips(&popdat, ui, 1_000, &mut timer);
|
||||
let requests = all_trips
|
||||
.iter()
|
||||
.map(|trip| trip.path_req(&ui.primary.map))
|
||||
|
@ -30,7 +30,7 @@ impl TripsVisualizer {
|
||||
],
|
||||
ctx,
|
||||
),
|
||||
trips: clip_trips(&popdat, ui, &mut timer),
|
||||
trips: clip_trips(&popdat, ui, 10_000, &mut timer),
|
||||
// TODO We'll break if there are no matching trips
|
||||
current: 0,
|
||||
}
|
||||
|
@ -190,12 +190,21 @@ impl Trip {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clip_trips(popdat: &popdat::PopDat, ui: &UI, timer: &mut Timer) -> Vec<Trip> {
|
||||
// TODO max_results just temporary for development.
|
||||
pub fn clip_trips(
|
||||
popdat: &popdat::PopDat,
|
||||
ui: &UI,
|
||||
max_results: usize,
|
||||
timer: &mut Timer,
|
||||
) -> Vec<Trip> {
|
||||
let mut results = Vec::new();
|
||||
let bounds = ui.primary.map.get_gps_bounds();
|
||||
timer.start_iter("clip trips", popdat.trips.len());
|
||||
for trip in &popdat.trips {
|
||||
timer.next();
|
||||
if results.len() == max_results {
|
||||
continue;
|
||||
}
|
||||
if !bounds.contains(trip.from) || !bounds.contains(trip.to) {
|
||||
continue;
|
||||
}
|
||||
|
@ -38,11 +38,7 @@ impl PolyLine {
|
||||
|
||||
// Can't have duplicates! If the polyline ever crosses back on itself, all sorts of things
|
||||
// are broken.
|
||||
let seen_pts: HashSet<HashablePt2D> = result
|
||||
.points()
|
||||
.iter()
|
||||
.map(|pt| HashablePt2D::from(*pt))
|
||||
.collect();
|
||||
let seen_pts = to_set(result.points());
|
||||
if seen_pts.len() != result.points().len() {
|
||||
panic!("PolyLine has repeat points: {}", result);
|
||||
}
|
||||
@ -95,10 +91,17 @@ impl PolyLine {
|
||||
PolyLine::new(pts)
|
||||
}
|
||||
|
||||
// TODO Rename append, make a prepend that just flips the arguments
|
||||
pub fn extend(self, other: &PolyLine) -> PolyLine {
|
||||
// Returns None if the two have any duplicate points (besides the last->first).
|
||||
pub fn extend(self, other: &PolyLine) -> Option<PolyLine> {
|
||||
assert_eq!(*self.pts.last().unwrap(), other.pts[0]);
|
||||
|
||||
let pl1 = to_set(self.points());
|
||||
let pl2 = to_set(&other.points()[1..]);
|
||||
if pl1.intersection(&pl2).next().is_some() {
|
||||
println!("Can't append, duplicate points... {} and {}", self, other);
|
||||
return None;
|
||||
}
|
||||
|
||||
// There's an exciting edge case: the next point to add is on self's last line.
|
||||
let same_line = self
|
||||
.last_line()
|
||||
@ -109,7 +112,7 @@ impl PolyLine {
|
||||
pts.pop();
|
||||
}
|
||||
pts.extend(other.pts.iter().skip(1));
|
||||
PolyLine::new(pts)
|
||||
Some(PolyLine::new(pts))
|
||||
}
|
||||
|
||||
// One or both args might be empty.
|
||||
@ -123,6 +126,7 @@ impl PolyLine {
|
||||
|
||||
PolyLine::new(first)
|
||||
.extend(&PolyLine::new(second))
|
||||
.unwrap()
|
||||
.points()
|
||||
.clone()
|
||||
}
|
||||
@ -653,3 +657,7 @@ fn check_angles(orig: &PolyLine, fixed: PolyLine) -> Warn<PolyLine> {
|
||||
}
|
||||
Warn::warnings(fixed, warnings)
|
||||
}
|
||||
|
||||
fn to_set(pts: &[Pt2D]) -> HashSet<HashablePt2D> {
|
||||
pts.iter().map(|pt| HashablePt2D::from(*pt)).collect()
|
||||
}
|
||||
|
@ -128,14 +128,14 @@ fn merge(
|
||||
.original_center_pts
|
||||
.get_slice_starting_at(r.trimmed_center_pts.last_pt())
|
||||
{
|
||||
r.trimmed_center_pts = r.trimmed_center_pts.clone().extend(&append);
|
||||
r.trimmed_center_pts = r.trimmed_center_pts.clone().extend(&append).unwrap();
|
||||
}
|
||||
} else {
|
||||
if let Some(prepend) = r
|
||||
.original_center_pts
|
||||
.get_slice_ending_at(r.trimmed_center_pts.first_pt())
|
||||
{
|
||||
r.trimmed_center_pts = prepend.extend(&r.trimmed_center_pts);
|
||||
r.trimmed_center_pts = prepend.extend(&r.trimmed_center_pts).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,8 +215,16 @@ impl Path {
|
||||
self.steps[i].slice(map, start_dist_this_step, dist_remaining)
|
||||
{
|
||||
if pts_so_far.is_some() {
|
||||
let pts = pts_so_far.unwrap().extend(&new_pts);
|
||||
if let Some(pts) = pts_so_far.unwrap().extend(&new_pts) {
|
||||
pts_so_far = Some(pts);
|
||||
} else {
|
||||
println!(
|
||||
"Adding {:?} to {:?} causes duplicate points!",
|
||||
self.steps[i],
|
||||
self.steps.iter().take(i).collect::<Vec<&PathStep>>()
|
||||
);
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
pts_so_far = Some(new_pts);
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ fn main() {
|
||||
let mut popdat = popdat::PopDat::import_all(&mut timer);
|
||||
|
||||
// TODO Productionize this.
|
||||
// https://file.ac/cLdO7Hp_OB0/ has trips_2014.csv. https://file.ac/Xdjmi8lb2dA/ has the 2014
|
||||
// inputs.
|
||||
let parcels = popdat::psrc::import_parcels(
|
||||
"/home/dabreegster/Downloads/psrc/2014/landuse/parcels_urbansim.txt",
|
||||
&mut timer,
|
||||
|
Loading…
Reference in New Issue
Block a user