From 367fc0ef3e0eac10e9878dd542ad11522abdb08f Mon Sep 17 00:00:00 2001 From: Johannes Erwerle Date: Thu, 15 Sep 2022 12:44:54 +0200 Subject: [PATCH] moved the route reconstruction into the Route struct --- src/astar.rs | 41 +++++++++--------------------------- src/gridgraph.rs | 55 ++++++++++++++++++++++++++---------------------- 2 files changed, 40 insertions(+), 56 deletions(-) diff --git a/src/astar.rs b/src/astar.rs index 1d6afe4..abaf0ce 100644 --- a/src/astar.rs +++ b/src/astar.rs @@ -8,11 +8,17 @@ pub struct AStar<'a> { pub graph: &'a GridGraph, } +/// An element on the Heap for A*. +/// The Ord and PartialOrd Traits are inverted so that the MaxHeap works as a +/// MinHeap. +/// index is the index of the Node, cost is the cost which the heap sorts after. +/// path_cost is the actual cost of the path to that node. #[derive(Eq, PartialEq)] struct HeapElement { index: u32, - cost: EdgeCost, // the cost so far plus the estimated cost until we reach the - // destination + + // the cost so far plus the estimated cost until we reach the destination + cost: EdgeCost, path_cost: EdgeCost, // the cost to reach this node from the start node } @@ -64,10 +70,7 @@ impl AStar<'_> { let mut popcount = 0; while let Some(HeapElement { - index, - cost, // the cost value, no longer needed, because it is only important for the - // distance estimate - path_cost, + index, path_cost, .. }) = heap.pop() { //println!("working on node {} with cost {} and path cost {}", index, cost, path_cost); @@ -113,30 +116,6 @@ impl AStar<'_> { println!("popped {} elements from the heap", popcount); - // now the route calculation is done. If a route exist we can construct - // it from the ancestors. - if ancestor[end.index as usize].is_some() { - let mut route = Route { - cost: distance[end.index as usize], - nodes: Vec::new(), - }; - - let mut current = end.index; - while current != start.index { - route - .nodes - .push(self.graph.nodes[current as usize].position); - current = ancestor[current as usize].unwrap(); - } - route - .nodes - .push(self.graph.nodes[current as usize].position); - - route.nodes.reverse(); - - return Some(route); - } - - None + Route::construct(self.graph, &ancestor, &distance, start, end) } } diff --git a/src/gridgraph.rs b/src/gridgraph.rs index d469da7..2fc00fb 100644 --- a/src/gridgraph.rs +++ b/src/gridgraph.rs @@ -107,6 +107,34 @@ impl LookupGrid { } impl Route { + + /// Constructs a route from the start to the end node on the graph + /// based on the ancestor and distance lists of a routing algorithm. + pub fn construct(graph: &GridGraph, ancestors: &Vec>, distance: &Vec, start: &GraphNode, end: &GraphNode) -> Option{ + if ancestors[end.index as usize].is_some() { + let mut route = Route { + cost: distance[end.index as usize], + nodes: Vec::new(), + }; + + let mut current = end.index; + while current != start.index { + route + .nodes + .push(graph.nodes[current as usize].position); + current = ancestors[current as usize].unwrap(); + } + route + .nodes + .push(graph.nodes[current as usize].position); + + route.nodes.reverse(); + + return Some(route); + } + None + } + pub fn to_geojson(&self) -> Box { let mut features: Box = Box::new(FeatureCollection { bbox: None, @@ -205,10 +233,7 @@ impl GridGraph { //println!("working on node {} with cost {}", index, cost); - let edge_start = self.edge_offsets[index as usize] as usize; - let edge_end = self.edge_offsets[(index + 1) as usize] as usize; - - for edge in self.edges[edge_start..edge_end].iter() { + for edge in self.get_edges(index as usize).iter() { let new_cost = cost + edge.cost; if new_cost < distance[edge.neighbor as usize] { @@ -228,27 +253,7 @@ impl GridGraph { println!("popped {} elements from the heap", popcount); - // now the route calculation is done. If a route exist we can construct - // it from the ancestors. - if ancestor[end.index as usize].is_some() { - let mut route = Route { - cost: distance[end.index as usize], - nodes: Vec::new(), - }; - - let mut current = end.index; - while current != start.index { - route.nodes.push(self.nodes[current as usize].position); - current = ancestor[current as usize].unwrap(); - } - route.nodes.push(self.nodes[current as usize].position); - - route.nodes.reverse(); - - return Some(route); - } - - None + Route::construct(self, &ancestor, &distance, start, end) } /// returns the GraphNode nearest to that positon.