Skip to content

Commit

Permalink
Fix some subtle edge cases with routes, involving the start/end
Browse files Browse the repository at this point in the history
positions and cases with one step.
  • Loading branch information
dabreegster committed Sep 13, 2024
1 parent 370b74f commit 8c4a071
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 89 deletions.
87 changes: 1 addition & 86 deletions backend/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ impl MapModel {

#[wasm_bindgen(js_name = loadFile)]
pub fn load_file(input_bytes: &[u8]) -> Result<MapModel, JsValue> {
// Panics shouldn't happen, but if they do, console.log them.
console_error_panic_hook::set_once();
START.call_once(|| {
console_log::init_with_level(log::Level::Info).unwrap();
});

bincode::deserialize_from(input_bytes).map_err(err_to_js)
}

Expand Down
2 changes: 1 addition & 1 deletion graph/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ impl Road {
}

/// A position along a road, along with the closer intersection
#[derive(Clone, Copy, PartialEq)]
#[derive(Clone, Debug, Copy, PartialEq)]
pub struct Position {
pub road: RoadID,
pub fraction_along: f64,
Expand Down
34 changes: 32 additions & 2 deletions graph/src/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,13 @@ impl Router {
}

pub fn route(&self, graph: &Graph, start: Position, end: Position) -> Result<Route> {
debug!("route from {start:?} to {end:?}");
if start == end {
bail!("start = end");
}

if start.road == end.road {
debug!("path: start = end road case");
return Ok(Route {
start,
end,
Expand All @@ -108,6 +110,27 @@ impl Router {
});
}

if start.intersection == end.intersection {
let common_intersection = start.intersection;
debug!("path: start = end intersection case");
let start_road = &graph.roads[start.road.0];
let end_road = &graph.roads[start.road.0];
return Ok(Route {
start,
end,
steps: vec![
PathStep::Road {
road: start.road,
forwards: start_road.dst_i == common_intersection,
},
PathStep::Road {
road: end.road,
forwards: end_road.src_i == common_intersection,
},
],
});
}

let start_node = self.node_map.get(start.intersection).unwrap();
let end_node = self.node_map.get(end.intersection).unwrap();

Expand All @@ -127,7 +150,9 @@ impl Router {
let i2 = self.node_map.translate_id(pair[1]);
let road = graph.find_edge(i1, i2);

if pos == itertools::Position::First && road.id != start.road {
if (pos == itertools::Position::First || pos == itertools::Position::Only)
&& road.id != start.road
{
steps.push(PathStep::Road {
road: start.road,
// TODO Test carefully.
Expand All @@ -138,7 +163,9 @@ impl Router {
road: road.id,
forwards: road.src_i == i1,
});
if pos == itertools::Position::Last && road.id != end.road {
if (pos == itertools::Position::Last || pos == itertools::Position::Only)
&& road.id != end.road
{
steps.push(PathStep::Road {
road: end.road,
// TODO Test carefully.
Expand All @@ -154,9 +181,12 @@ impl Router {
impl Route {
pub fn linestring(&self, graph: &Graph) -> LineString {
let mut pts = Vec::new();
debug!("turning {} steps into linestring", self.steps.len());
debug!("route start is {:?}, end is {:?}", self.start, self.end);
for (pos, step) in self.steps.iter().with_position() {
match step {
PathStep::Road { road, forwards } => {
debug!("step on {road:?}, forwards = {forwards}");
pts.extend(slice_road_step(
&graph.roads[road.0].linestring,
*forwards,
Expand Down

0 comments on commit 8c4a071

Please sign in to comment.