mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +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 (pl1, width1) = wraparound_get(&road_centers, idx);
|
||||||
let (pl2, width2) = wraparound_get(&road_centers, idx + 1);
|
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 max_width = (*width1).max(*width2);
|
||||||
let poly = Polygon::new(&glued.to_thick_boundary_pts(max_width));
|
let poly = Polygon::new(&glued.to_thick_boundary_pts(max_width));
|
||||||
g.draw_polygon(Color::RED.alpha(0.4), &poly);
|
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 trips = ctx.loading_screen("load trip data", |_, mut timer| {
|
||||||
let popdat: PopDat = abstutil::read_binary("../data/shapes/popdat", &mut timer)
|
let popdat: PopDat = abstutil::read_binary("../data/shapes/popdat", &mut timer)
|
||||||
.expect("Couldn't load popdat");
|
.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
|
let requests = all_trips
|
||||||
.iter()
|
.iter()
|
||||||
.map(|trip| trip.path_req(&ui.primary.map))
|
.map(|trip| trip.path_req(&ui.primary.map))
|
||||||
|
@ -30,7 +30,7 @@ impl TripsVisualizer {
|
|||||||
],
|
],
|
||||||
ctx,
|
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
|
// TODO We'll break if there are no matching trips
|
||||||
current: 0,
|
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 mut results = Vec::new();
|
||||||
let bounds = ui.primary.map.get_gps_bounds();
|
let bounds = ui.primary.map.get_gps_bounds();
|
||||||
timer.start_iter("clip trips", popdat.trips.len());
|
timer.start_iter("clip trips", popdat.trips.len());
|
||||||
for trip in &popdat.trips {
|
for trip in &popdat.trips {
|
||||||
timer.next();
|
timer.next();
|
||||||
|
if results.len() == max_results {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if !bounds.contains(trip.from) || !bounds.contains(trip.to) {
|
if !bounds.contains(trip.from) || !bounds.contains(trip.to) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -38,11 +38,7 @@ impl PolyLine {
|
|||||||
|
|
||||||
// Can't have duplicates! If the polyline ever crosses back on itself, all sorts of things
|
// Can't have duplicates! If the polyline ever crosses back on itself, all sorts of things
|
||||||
// are broken.
|
// are broken.
|
||||||
let seen_pts: HashSet<HashablePt2D> = result
|
let seen_pts = to_set(result.points());
|
||||||
.points()
|
|
||||||
.iter()
|
|
||||||
.map(|pt| HashablePt2D::from(*pt))
|
|
||||||
.collect();
|
|
||||||
if seen_pts.len() != result.points().len() {
|
if seen_pts.len() != result.points().len() {
|
||||||
panic!("PolyLine has repeat points: {}", result);
|
panic!("PolyLine has repeat points: {}", result);
|
||||||
}
|
}
|
||||||
@ -95,10 +91,17 @@ impl PolyLine {
|
|||||||
PolyLine::new(pts)
|
PolyLine::new(pts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Rename append, make a prepend that just flips the arguments
|
// Returns None if the two have any duplicate points (besides the last->first).
|
||||||
pub fn extend(self, other: &PolyLine) -> PolyLine {
|
pub fn extend(self, other: &PolyLine) -> Option<PolyLine> {
|
||||||
assert_eq!(*self.pts.last().unwrap(), other.pts[0]);
|
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.
|
// There's an exciting edge case: the next point to add is on self's last line.
|
||||||
let same_line = self
|
let same_line = self
|
||||||
.last_line()
|
.last_line()
|
||||||
@ -109,7 +112,7 @@ impl PolyLine {
|
|||||||
pts.pop();
|
pts.pop();
|
||||||
}
|
}
|
||||||
pts.extend(other.pts.iter().skip(1));
|
pts.extend(other.pts.iter().skip(1));
|
||||||
PolyLine::new(pts)
|
Some(PolyLine::new(pts))
|
||||||
}
|
}
|
||||||
|
|
||||||
// One or both args might be empty.
|
// One or both args might be empty.
|
||||||
@ -123,6 +126,7 @@ impl PolyLine {
|
|||||||
|
|
||||||
PolyLine::new(first)
|
PolyLine::new(first)
|
||||||
.extend(&PolyLine::new(second))
|
.extend(&PolyLine::new(second))
|
||||||
|
.unwrap()
|
||||||
.points()
|
.points()
|
||||||
.clone()
|
.clone()
|
||||||
}
|
}
|
||||||
@ -653,3 +657,7 @@ fn check_angles(orig: &PolyLine, fixed: PolyLine) -> Warn<PolyLine> {
|
|||||||
}
|
}
|
||||||
Warn::warnings(fixed, warnings)
|
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
|
.original_center_pts
|
||||||
.get_slice_starting_at(r.trimmed_center_pts.last_pt())
|
.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 {
|
} else {
|
||||||
if let Some(prepend) = r
|
if let Some(prepend) = r
|
||||||
.original_center_pts
|
.original_center_pts
|
||||||
.get_slice_ending_at(r.trimmed_center_pts.first_pt())
|
.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)
|
self.steps[i].slice(map, start_dist_this_step, dist_remaining)
|
||||||
{
|
{
|
||||||
if pts_so_far.is_some() {
|
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);
|
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 {
|
} else {
|
||||||
pts_so_far = Some(new_pts);
|
pts_so_far = Some(new_pts);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ fn main() {
|
|||||||
let mut popdat = popdat::PopDat::import_all(&mut timer);
|
let mut popdat = popdat::PopDat::import_all(&mut timer);
|
||||||
|
|
||||||
// TODO Productionize this.
|
// 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(
|
let parcels = popdat::psrc::import_parcels(
|
||||||
"/home/dabreegster/Downloads/psrc/2014/landuse/parcels_urbansim.txt",
|
"/home/dabreegster/Downloads/psrc/2014/landuse/parcels_urbansim.txt",
|
||||||
&mut timer,
|
&mut timer,
|
||||||
|
Loading…
Reference in New Issue
Block a user