Skip to content

Commit e437d21

Browse files
authored
Merge pull request #24 from SolverForge/issue/11-extract-shared-route-assembly
refactor: extract shared route-result assembly
2 parents c998170 + b53b374 commit e437d21

File tree

1 file changed

+41
-54
lines changed

1 file changed

+41
-54
lines changed

src/routing/network.rs

Lines changed: 41 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,39 @@ impl RoadNetwork {
223223
self.distance_lower_bound_between(from, to) / self.max_speed_mps
224224
}
225225

226+
fn node_path_geometry(&self, path: &[NodeIdx]) -> Vec<Coord> {
227+
path.iter()
228+
.filter_map(|&idx| self.graph.node_weight(idx).map(|n| n.coord()))
229+
.collect()
230+
}
231+
232+
fn node_path_metrics(&self, path: &[NodeIdx]) -> (f64, f64) {
233+
let mut distance = 0.0;
234+
let mut time = 0.0;
235+
236+
for window in path.windows(2) {
237+
if let Some(edge) = self.graph.find_edge(window[0], window[1]) {
238+
if let Some(weight) = self.graph.edge_weight(edge) {
239+
distance += weight.distance_m;
240+
time += weight.travel_time_s;
241+
}
242+
}
243+
}
244+
245+
(distance, time)
246+
}
247+
248+
fn route_result_from_node_path(&self, path: &[NodeIdx], duration_seconds: i64) -> RouteResult {
249+
let geometry = self.node_path_geometry(path);
250+
let (distance, _) = self.node_path_metrics(path);
251+
252+
RouteResult {
253+
duration_seconds,
254+
distance_meters: distance,
255+
geometry,
256+
}
257+
}
258+
226259
/// Iterate over all nodes as (lat, lng) pairs.
227260
pub fn nodes_iter(&self) -> impl Iterator<Item = (f64, f64)> + '_ {
228261
self.graph
@@ -416,28 +449,17 @@ impl RoadNetwork {
416449
match best_result {
417450
Some((total_cost, path)) => {
418451
let mut geometry = vec![from.snapped];
419-
for &idx in &path {
420-
if let Some(node) = self.graph.node_weight(idx) {
421-
let coord = node.coord();
422-
if geometry.last().copied() != Some(coord) {
423-
geometry.push(coord);
424-
}
452+
for coord in self.node_path_geometry(&path) {
453+
if geometry.last().copied() != Some(coord) {
454+
geometry.push(coord);
425455
}
426456
}
427457
if geometry.last().copied() != Some(to.snapped) {
428458
geometry.push(to.snapped);
429459
}
430460

431-
let mut distance = start_exit.distance_m;
432-
for window in path.windows(2) {
433-
if let Some(edge) = self.graph.find_edge(window[0], window[1]) {
434-
if let Some(weight) = self.graph.edge_weight(edge) {
435-
distance += weight.distance_m;
436-
}
437-
}
438-
}
439-
440-
distance += end_entry.distance_m;
461+
let (path_distance, _) = self.node_path_metrics(&path);
462+
let distance = start_exit.distance_m + path_distance + end_entry.distance_m;
441463

442464
Ok(RouteResult {
443465
duration_seconds: total_cost.round() as i64,
@@ -478,27 +500,7 @@ impl RoadNetwork {
478500
);
479501

480502
match result {
481-
Some((cost, path)) => {
482-
let geometry: Vec<Coord> = path
483-
.iter()
484-
.filter_map(|&idx| self.graph.node_weight(idx).map(|n| n.coord()))
485-
.collect();
486-
487-
let mut distance = 0.0;
488-
for window in path.windows(2) {
489-
if let Some(edge) = self.graph.find_edge(window[0], window[1]) {
490-
if let Some(weight) = self.graph.edge_weight(edge) {
491-
distance += weight.distance_m;
492-
}
493-
}
494-
}
495-
496-
Ok(RouteResult {
497-
duration_seconds: cost.round() as i64,
498-
distance_meters: distance,
499-
geometry,
500-
})
501-
}
503+
Some((cost, path)) => Ok(self.route_result_from_node_path(&path, cost.round() as i64)),
502504
None => Err(RoutingError::NoPath {
503505
from: from.original,
504506
to: to.original,
@@ -546,26 +548,11 @@ impl RoadNetwork {
546548

547549
match result {
548550
Some((_, path)) => {
549-
let geometry: Vec<Coord> = path
550-
.iter()
551-
.filter_map(|&idx| self.graph.node_weight(idx).map(|n| n.coord()))
552-
.collect();
553-
554-
let mut distance = 0.0;
555-
let mut time = 0.0;
556-
for window in path.windows(2) {
557-
if let Some(edge) = self.graph.find_edge(window[0], window[1]) {
558-
if let Some(weight) = self.graph.edge_weight(edge) {
559-
distance += weight.distance_m;
560-
time += weight.travel_time_s;
561-
}
562-
}
563-
}
564-
551+
let (distance, time) = self.node_path_metrics(&path);
565552
Ok(RouteResult {
566553
duration_seconds: time.round() as i64,
567554
distance_meters: distance,
568-
geometry,
555+
geometry: self.node_path_geometry(&path),
569556
})
570557
}
571558
None => Err(RoutingError::NoPath { from, to }),

0 commit comments

Comments
 (0)