Skip to content

Commit

Permalink
Rank shortcuts by directness, to show the most likely ones first. #5
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Feb 9, 2024
1 parent 3acf42a commit dc2f1da
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
6 changes: 1 addition & 5 deletions backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,11 +311,7 @@ impl LTN {
Shortcuts::new(&self.map, self.neighbourhood.as_ref().unwrap())
.subset(RoadID(road))
.into_iter()
.map(|path| {
Feature::from(Geometry::from(
&self.map.mercator.to_wgs84(&path.geometry(&self.map)),
))
})
.map(|path| path.to_gj(&self.map))
.collect::<Vec<_>>(),
))
.map_err(err_to_js)?)
Expand Down
36 changes: 32 additions & 4 deletions backend/src/shortcuts.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::collections::HashMap;

use fast_paths::InputGraph;
use geo::LineString;
use geo::{EuclideanLength, LineString};
use geojson::{Feature, Geometry};

use crate::{IntersectionID, MapModel, Neighbourhood, NodeMap, RoadID};

Expand All @@ -12,6 +13,7 @@ pub struct Shortcuts {

pub struct Path {
steps: Vec<(RoadID, IntersectionID, IntersectionID)>,
directness: f64,
}

impl Shortcuts {
Expand Down Expand Up @@ -44,22 +46,44 @@ impl Shortcuts {
let mut count_per_road = HashMap::new();
for start in &neighbourhood.border_intersections {
for end in &neighbourhood.border_intersections {
if start == end {
continue;
}
if let (Some(i1), Some(i2)) = (node_map.get(*start), node_map.get(*end)) {
if let Some(path) = path_calc.calc_path(&ch, i1, i2) {
let mut steps = Vec::new();
let mut shortcut_length = 0.0;
for pair in path.get_nodes().windows(2) {
let i1 = node_map.translate_id(pair[0]);
let i2 = node_map.translate_id(pair[1]);
let road = map.find_edge(i1, i2);
steps.push((road.id, i1, i2));
*count_per_road.entry(road.id).or_insert(0) += 1;
shortcut_length += road.length();
}
paths.push(Path { steps });

// How long is the shortest route through the original router, using this
// neighbourhood or not?
let direct_length = match map.router_original.route(
map,
map.get_i(*start).point.into(),
map.get_i(*end).point.into(),
) {
Some(linestring) => linestring.euclidean_length(),
None => {
warn!("Found a shortcut from {start} to {end}, but not a route using the whole map");
shortcut_length
}
};
let directness = shortcut_length / direct_length;
paths.push(Path { steps, directness });
}
}
}
}

paths.sort_by_key(|path| (path.directness * 100.0) as usize);

Self {
paths,
count_per_road,
Expand All @@ -75,7 +99,7 @@ impl Shortcuts {
}

impl Path {
pub fn geometry(&self, map: &MapModel) -> LineString {
pub fn to_gj(&self, map: &MapModel) -> Feature {
let mut pts = Vec::new();
for (r, i1, _i2) in &self.steps {
let road = map.get_r(*r);
Expand All @@ -87,6 +111,10 @@ impl Path {
pts.extend(rev);
}
}
LineString::new(pts)
let mut f = Feature::from(Geometry::from(
&map.mercator.to_wgs84(&LineString::new(pts)),
));
f.set_property("directness", self.directness);
f
}
}
8 changes: 8 additions & 0 deletions web/src/ViewShortcutsMode.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@
Next
</button>
</div>
<p>
This shortcut is <b>
{notNull(
state.gj.features[state.shortcutIndex].properties,
).directness.toFixed(1)}x
</b>
the length of the shortest route using all roads, not just this neighbourhood
</p>
{/if}
</div>

Expand Down

0 comments on commit dc2f1da

Please sign in to comment.