Skip to content

Commit

Permalink
Just make InputRoad look more like Road, so later refactors have a sm…
Browse files Browse the repository at this point in the history
…aller diff. Mechanical renaming. #136
  • Loading branch information
dabreegster committed Dec 5, 2022
1 parent 79843fd commit ad5aeed
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 74 deletions.
109 changes: 53 additions & 56 deletions osm2streets/src/geometry/algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ pub fn intersection_polygon(
for road in roads.values_mut() {
if let Some(endpt) = trim_roads_for_merging.get(&(road.id, road.src_i == intersection_id)) {
if road.src_i == intersection_id {
match road.center_pts.safe_get_slice_starting_at(*endpt) {
match road.center_line.safe_get_slice_starting_at(*endpt) {
Some(pl) => {
road.center_pts = pl;
road.center_line = pl;
}
None => {
error!("{}'s trimmed points start past the endpt {endpt}", road.id);
Expand All @@ -44,9 +44,9 @@ pub fn intersection_polygon(
}
} else {
assert_eq!(road.dst_i, intersection_id);
match road.center_pts.safe_get_slice_ending_at(*endpt) {
match road.center_line.safe_get_slice_ending_at(*endpt) {
Some(pl) => {
road.center_pts = pl;
road.center_line = pl;
}
None => {
error!("{}'s trimmed points end before the endpt {endpt}", road.id);
Expand All @@ -61,16 +61,16 @@ pub fn intersection_polygon(
for id in sorted_roads {
let road = &roads[&id];
let center_pl = if road.src_i == intersection_id {
road.center_pts.reversed()
road.center_line.reversed()
} else if road.dst_i == intersection_id {
road.center_pts.clone()
road.center_line.clone()
} else {
panic!("Incident road {id} doesn't have an endpoint at {intersection_id}");
};
road_lines.push(RoadLine {
id,
fwd_pl: center_pl.shift_right(road.half_width)?,
back_pl: center_pl.shift_left(road.half_width)?,
fwd_pl: center_pl.shift_right(road.half_width())?,
back_pl: center_pl.shift_left(road.half_width())?,
});
}

Expand Down Expand Up @@ -135,9 +135,9 @@ fn generalized_trim_back(
for (r1, pl1) in &road_lines {
// road_center ends at the intersection.
let road_center = if roads[r1].dst_i == i {
roads[r1].center_pts.clone()
roads[r1].center_line.clone()
} else {
roads[r1].center_pts.reversed()
roads[r1].center_line.reversed()
};

// Always trim back a minimum amount, if possible.
Expand Down Expand Up @@ -239,7 +239,7 @@ fn generalized_trim_back(
let adj_back_pl = &wraparound_get(input_road_lines, idx + 1).fwd_pl;
let adj_fwd_pl = &wraparound_get(input_road_lines, idx - 1).back_pl;

roads.get_mut(&id).unwrap().center_pts = new_road_centers[&id].clone();
roads.get_mut(&id).unwrap().center_line = new_road_centers[&id].clone();
let r = &roads[&id];

// Include collisions between polylines of adjacent roads, so the polygon doesn't cover area
Expand All @@ -264,11 +264,11 @@ fn generalized_trim_back(

// Shift those final centers out again to find the main endpoints for the polygon.
if r.dst_i == i {
endpoints.push(r.center_pts.shift_right(r.half_width)?.last_pt());
endpoints.push(r.center_pts.shift_left(r.half_width)?.last_pt());
endpoints.push(r.center_line.shift_right(r.half_width())?.last_pt());
endpoints.push(r.center_line.shift_left(r.half_width())?.last_pt());
} else {
endpoints.push(r.center_pts.shift_left(r.half_width)?.first_pt());
endpoints.push(r.center_pts.shift_right(r.half_width)?.first_pt());
endpoints.push(r.center_line.shift_left(r.half_width())?.first_pt());
endpoints.push(r.center_line.shift_right(r.half_width())?.first_pt());
}

if back_pl.length() >= EPSILON_DIST * 3.0 && adj_back_pl.length() >= EPSILON_DIST * 3.0 {
Expand Down Expand Up @@ -319,9 +319,7 @@ fn generalized_trim_back(

// TODO We always do this. Maybe Results has the InputRoad and we just work in-place
for (id, r) in roads {
results
.trimmed_center_pts
.insert(id, (r.center_pts, r.half_width));
results.trimmed_center_pts.insert(id, r.center_line);
}
Ok(results)
}
Expand All @@ -336,11 +334,11 @@ fn pretrimmed_geometry(
let r = &roads[&r.id];
// Shift those final centers out again to find the main endpoints for the polygon.
if r.dst_i == results.intersection_id {
endpoints.push(r.center_pts.shift_right(r.half_width)?.last_pt());
endpoints.push(r.center_pts.shift_left(r.half_width)?.last_pt());
endpoints.push(r.center_line.shift_right(r.half_width())?.last_pt());
endpoints.push(r.center_line.shift_left(r.half_width())?.last_pt());
} else {
endpoints.push(r.center_pts.shift_left(r.half_width)?.first_pt());
endpoints.push(r.center_pts.shift_right(r.half_width)?.first_pt());
endpoints.push(r.center_line.shift_left(r.half_width())?.first_pt());
endpoints.push(r.center_line.shift_right(r.half_width())?.first_pt());
}
}

Expand All @@ -351,9 +349,7 @@ fn pretrimmed_geometry(
)))?
.into_polygon();
for (id, r) in roads {
results
.trimmed_center_pts
.insert(id, (r.center_pts, r.half_width));
results.trimmed_center_pts.insert(id, r.center_line);
}
Ok(results)
}
Expand All @@ -377,19 +373,19 @@ fn deadend(

let r = roads.get_mut(&id).unwrap();
let len_with_buffer = len + 3.0 * EPSILON_DIST;
let trimmed = if r.center_pts.length() >= len_with_buffer {
let trimmed = if r.center_line.length() >= len_with_buffer {
if r.src_i == results.intersection_id {
r.center_pts = r.center_pts.exact_slice(len, r.center_pts.length());
r.center_line = r.center_line.exact_slice(len, r.center_line.length());
} else {
r.center_pts = r
.center_pts
.exact_slice(Distance::ZERO, r.center_pts.length() - len);
r.center_line = r
.center_line
.exact_slice(Distance::ZERO, r.center_line.length() - len);
}
r.center_pts.clone()
r.center_line.clone()
} else if r.src_i == results.intersection_id {
r.center_pts.extend_to_length(len_with_buffer)
r.center_line.extend_to_length(len_with_buffer)
} else {
r.center_pts
r.center_line
.reversed()
.extend_to_length(len_with_buffer)
.reversed()
Expand All @@ -400,19 +396,17 @@ fn deadend(
// TODO Refactor with generalized_trim_back.
let mut endpts = vec![pl_b.last_pt(), pl_a.last_pt()];
if r.dst_i == results.intersection_id {
endpts.push(trimmed.shift_right(r.half_width)?.last_pt());
endpts.push(trimmed.shift_left(r.half_width)?.last_pt());
endpts.push(trimmed.shift_right(r.half_width())?.last_pt());
endpts.push(trimmed.shift_left(r.half_width())?.last_pt());
} else {
endpts.push(trimmed.shift_left(r.half_width)?.first_pt());
endpts.push(trimmed.shift_right(r.half_width)?.first_pt());
endpts.push(trimmed.shift_left(r.half_width())?.first_pt());
endpts.push(trimmed.shift_right(r.half_width())?.first_pt());
}

endpts.dedup();
results.intersection_polygon = Ring::must_new(close_off_polygon(endpts)).into_polygon();
for (id, r) in roads {
results
.trimmed_center_pts
.insert(id, (r.center_pts, r.half_width));
results.trimmed_center_pts.insert(id, r.center_line);
}
Ok(results)
}
Expand Down Expand Up @@ -468,9 +462,9 @@ fn on_off_ramp(
for r in road_lines {
let road = &roads[&r.id];
let center = if road.dst_i == results.intersection_id {
road.center_pts.clone()
road.center_line.clone()
} else {
road.center_pts.reversed()
road.center_line.reversed()
};
pieces.push(Piece {
id: road.id,
Expand All @@ -482,7 +476,12 @@ fn on_off_ramp(
}

// Break ties by preferring the outbound roads for thin
pieces.sort_by_key(|r| (roads[&r.id].half_width, r.dst_i == results.intersection_id));
pieces.sort_by_key(|r| {
(
roads[&r.id].half_width(),
r.dst_i == results.intersection_id,
)
});
let thick1 = pieces.pop().unwrap();
let thick2 = pieces.pop().unwrap();
let thin = pieces.pop().unwrap();
Expand Down Expand Up @@ -550,21 +549,21 @@ fn on_off_ramp(
if thin.dst_i != results.intersection_id {
trimmed_thin = trimmed_thin.reversed();
}
roads.get_mut(&thin.id).unwrap().center_pts = trimmed_thin;
roads.get_mut(&thin.id).unwrap().center_line = trimmed_thin;

// Trim the thick extra ends at the intersection
let extra = if roads[&thick_id].dst_i == results.intersection_id {
roads[&thick_id]
.center_pts
.center_line
.get_slice_starting_at(trimmed_thick.last_pt())?
} else {
trimmed_thick = trimmed_thick.reversed();
roads[&thick_id]
.center_pts
.center_line
.get_slice_ending_at(trimmed_thick.first_pt())?
.reversed()
};
roads.get_mut(&thick_id).unwrap().center_pts = trimmed_thick;
roads.get_mut(&thick_id).unwrap().center_line = trimmed_thick;
// Give the merge point some length
if extra.length() <= 2.0 * DEGENERATE_INTERSECTION_HALF_LENGTH + 3.0 * EPSILON_DIST {
return None;
Expand All @@ -580,9 +579,9 @@ fn on_off_ramp(
})
.unwrap();
if other.dst_i == results.intersection_id {
other.center_pts = other.center_pts.clone().extend(extra.reversed()).ok()?;
other.center_line = other.center_line.clone().extend(extra.reversed()).ok()?;
} else {
other.center_pts = extra.extend(other.center_pts.clone()).ok()?;
other.center_line = extra.extend(other.center_line.clone()).ok()?;
}
}

Expand All @@ -592,11 +591,11 @@ fn on_off_ramp(
let r = &roads[&id];
// Shift those final centers out again to find the main endpoints for the polygon.
if r.dst_i == results.intersection_id {
endpoints.push(r.center_pts.shift_right(r.half_width).ok()?.last_pt());
endpoints.push(r.center_pts.shift_left(r.half_width).ok()?.last_pt());
endpoints.push(r.center_line.shift_right(r.half_width()).ok()?.last_pt());
endpoints.push(r.center_line.shift_left(r.half_width()).ok()?.last_pt());
} else {
endpoints.push(r.center_pts.shift_left(r.half_width).ok()?.first_pt());
endpoints.push(r.center_pts.shift_right(r.half_width).ok()?.first_pt());
endpoints.push(r.center_line.shift_left(r.half_width()).ok()?.first_pt());
endpoints.push(r.center_line.shift_right(r.half_width()).ok()?.first_pt());
}
}
/*for (idx, pt) in endpoints.iter().enumerate() {
Expand All @@ -610,9 +609,7 @@ fn on_off_ramp(
endpoints.dedup();
results.intersection_polygon = Ring::must_new(close_off_polygon(endpoints)).into_polygon();
for (id, r) in roads {
results
.trimmed_center_pts
.insert(id, (r.center_pts, r.half_width));
results.trimmed_center_pts.insert(id, r.center_line);
}
Some(results)
}
15 changes: 10 additions & 5 deletions osm2streets/src/geometry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,23 @@ pub struct InputRoad {
pub src_i: IntersectionID,
pub dst_i: IntersectionID,
/// The true center of the road, including sidewalks. The input is untrimmed when called on the
/// first endpoint, then trimmed on that one side when called on th second endpoint.
pub center_pts: PolyLine,
pub half_width: Distance,
/// first endpoint, then trimmed on that first side when called on the second endpoint.
pub center_line: PolyLine,
pub total_width: Distance,
pub highway_type: String,
}

impl InputRoad {
pub fn half_width(&self) -> Distance {
self.total_width / 2.0
}
}

#[derive(Clone)]
pub struct Results {
pub intersection_id: IntersectionID,
pub intersection_polygon: Polygon,
/// Road -> (trimmed center line, half width)
pub trimmed_center_pts: BTreeMap<RoadID, (PolyLine, Distance)>,
pub trimmed_center_pts: BTreeMap<RoadID, PolyLine>,
/// Extra polygons with labels to debug the algorithm
pub debug: Vec<(String, Polygon)>,
}
10 changes: 5 additions & 5 deletions osm2streets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ impl StreetNetwork {
for road in self.roads_per_intersection(endpts[0]) {
// trimmed_center_line hasn't been initialized yet, so override this
let mut input = road.to_input_road();
input.center_pts = road.untrimmed_road_geometry(self.config.driving_side);
input.center_line = road.untrimmed_road_geometry(self.config.driving_side);
input_roads.push(input);
}
let mut results = intersection_polygon(
Expand All @@ -165,7 +165,7 @@ impl StreetNetwork {
// TODO Not sure if we should use this or not
&BTreeMap::new(),
)?;
results.trimmed_center_pts.remove(&road_id).unwrap().0
results.trimmed_center_pts.remove(&road_id).unwrap()
};

// Now the second
Expand All @@ -174,9 +174,9 @@ impl StreetNetwork {
for road in self.roads_per_intersection(endpts[1]) {
let mut input = road.to_input_road();
if road.id == road_id {
input.center_pts = trimmed_center_pts.clone();
input.center_line = trimmed_center_pts.clone();
} else {
input.center_pts = road.untrimmed_road_geometry(self.config.driving_side);
input.center_line = road.untrimmed_road_geometry(self.config.driving_side);
}
input_roads.push(input);
}
Expand All @@ -186,7 +186,7 @@ impl StreetNetwork {
// TODO Not sure if we should use this or not
&BTreeMap::new(),
)?;
Ok(results.trimmed_center_pts.remove(&road_id).unwrap().0)
Ok(results.trimmed_center_pts.remove(&road_id).unwrap())
}
}

Expand Down
15 changes: 9 additions & 6 deletions osm2streets/src/road.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ impl Road {
pub fn total_width(&self) -> Distance {
self.lane_specs_ltr.iter().map(|l| l.width).sum()
}
pub fn half_width(&self) -> Distance {
self.total_width() / 2.0
}

/// Calculates the number of (forward, both_ways, backward) lanes. The order of the lanes
/// doesn't matter.
Expand Down Expand Up @@ -271,7 +274,7 @@ impl Road {
use RoadPosition::*;

match position {
FullWidthCenter => self.total_width() / 2.0,
FullWidthCenter => self.half_width(),
Center => {
// Need to find the midpoint between the first and last occurrence of any roadway.
let mut left_buffer = Distance::ZERO;
Expand Down Expand Up @@ -373,7 +376,7 @@ impl Road {
}

warn!("named lane doesn't exist");
self.total_width() / 2.0
self.half_width()
}
}
}
Expand Down Expand Up @@ -427,8 +430,8 @@ impl Road {
id: self.id,
src_i: self.src_i,
dst_i: self.dst_i,
center_pts: self.center_line.clone(),
half_width: self.total_width() / 2.0,
center_line: self.center_line.clone(),
total_width: self.total_width(),
highway_type: self.highway_type.clone(),
}
}
Expand Down Expand Up @@ -469,12 +472,12 @@ impl RoadEdge {
for road in sorted_roads {
let mut left = RoadEdge {
road: road.id,
pl: road.center_line.must_shift_left(road.total_width() / 2.0),
pl: road.center_line.must_shift_left(road.half_width()),
lane: road.lane_specs_ltr[0].clone(),
};
let mut right = RoadEdge {
road: road.id,
pl: road.center_line.must_shift_right(road.total_width() / 2.0),
pl: road.center_line.must_shift_right(road.half_width()),
lane: road.lane_specs_ltr.last().unwrap().clone(),
};
if road.dst_i == i {
Expand Down
Loading

0 comments on commit ad5aeed

Please sign in to comment.