moved the route reconstruction into the Route struct

This commit is contained in:
Johannes Erwerle 2022-09-15 12:44:54 +02:00
parent 32a81b3561
commit 367fc0ef3e
2 changed files with 40 additions and 56 deletions

View file

@ -8,11 +8,17 @@ pub struct AStar<'a> {
pub graph: &'a GridGraph, 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)] #[derive(Eq, PartialEq)]
struct HeapElement { struct HeapElement {
index: u32, 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 path_cost: EdgeCost, // the cost to reach this node from the start node
} }
@ -64,10 +70,7 @@ impl AStar<'_> {
let mut popcount = 0; let mut popcount = 0;
while let Some(HeapElement { while let Some(HeapElement {
index, index, path_cost, ..
cost, // the cost value, no longer needed, because it is only important for the
// distance estimate
path_cost,
}) = heap.pop() }) = heap.pop()
{ {
//println!("working on node {} with cost {} and path cost {}", index, cost, path_cost); //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); println!("popped {} elements from the heap", popcount);
// now the route calculation is done. If a route exist we can construct Route::construct(self.graph, &ancestor, &distance, start, end)
// 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
} }
} }

View file

@ -107,6 +107,34 @@ impl LookupGrid {
} }
impl Route { 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<Option<u32>>, distance: &Vec<EdgeCost>, start: &GraphNode, end: &GraphNode) -> Option<Self>{
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<FeatureCollection> { pub fn to_geojson(&self) -> Box<FeatureCollection> {
let mut features: Box<FeatureCollection> = Box::new(FeatureCollection { let mut features: Box<FeatureCollection> = Box::new(FeatureCollection {
bbox: None, bbox: None,
@ -205,10 +233,7 @@ impl GridGraph {
//println!("working on node {} with cost {}", index, cost); //println!("working on node {} with cost {}", index, cost);
let edge_start = self.edge_offsets[index as usize] as usize; for edge in self.get_edges(index as usize).iter() {
let edge_end = self.edge_offsets[(index + 1) as usize] as usize;
for edge in self.edges[edge_start..edge_end].iter() {
let new_cost = cost + edge.cost; let new_cost = cost + edge.cost;
if new_cost < distance[edge.neighbor as usize] { if new_cost < distance[edge.neighbor as usize] {
@ -228,27 +253,7 @@ impl GridGraph {
println!("popped {} elements from the heap", popcount); println!("popped {} elements from the heap", popcount);
// now the route calculation is done. If a route exist we can construct Route::construct(self, &ancestor, &distance, start, end)
// 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
} }
/// returns the GraphNode nearest to that positon. /// returns the GraphNode nearest to that positon.