Preserve heap state in map matching
This commit is contained in:
committed by
Patrick Niklaus
parent
89fabc1b9c
commit
b630b4e32a
@@ -242,7 +242,8 @@ void calculateDistances(typename SearchEngineData<ch::Algorithm>::ManyToManyQuer
|
||||
{
|
||||
EdgeDistance annotation =
|
||||
ch::calculateEBGNodeAnnotations(facade, packed_leg.begin(), packed_leg.end());
|
||||
adjustPathDistanceToPhantomNodes(packed_leg, source_phantom, target_phantom, annotation);
|
||||
annotation = adjustPathDistanceToPhantomNodes(
|
||||
packed_leg, source_phantom, target_phantom, annotation);
|
||||
|
||||
distances_table[row_index * number_of_targets + column_index] = annotation;
|
||||
}
|
||||
|
||||
@@ -227,6 +227,9 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
{
|
||||
continue;
|
||||
}
|
||||
forward_heap.Clear();
|
||||
const auto &source_phantom = prev_unbroken_timestamps_list[s].phantom_node;
|
||||
insertSourceInHeap(forward_heap, source_phantom);
|
||||
|
||||
for (const auto s_prime : util::irange<std::size_t>(0UL, current_viterbi.size()))
|
||||
{
|
||||
@@ -237,14 +240,17 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
continue;
|
||||
}
|
||||
|
||||
double network_distance =
|
||||
getNetworkDistance(engine_working_data,
|
||||
facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
prev_unbroken_timestamps_list[s].phantom_node,
|
||||
current_timestamps_list[s_prime].phantom_node,
|
||||
weight_upper_bound);
|
||||
reverse_heap.Clear();
|
||||
const auto &target_phantom = current_timestamps_list[s_prime].phantom_node;
|
||||
insertTargetInHeap(reverse_heap, target_phantom);
|
||||
|
||||
double network_distance = getNetworkDistance(engine_working_data,
|
||||
facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
source_phantom,
|
||||
target_phantom,
|
||||
weight_upper_bound);
|
||||
|
||||
// get distance diff between loc1/2 and locs/s_prime
|
||||
const auto d_t = std::abs(network_distance - haversine_distance);
|
||||
|
||||
@@ -33,11 +33,12 @@ bool needsLoopBackwards(const PhantomNodes &phantoms)
|
||||
return needsLoopBackwards(phantoms.source_phantom, phantoms.target_phantom);
|
||||
}
|
||||
|
||||
void adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom,
|
||||
EdgeDistance &distance)
|
||||
EdgeDistance adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom,
|
||||
const EdgeDistance uncorrected_distance)
|
||||
{
|
||||
EdgeDistance distance = uncorrected_distance;
|
||||
if (!path.empty())
|
||||
{
|
||||
|
||||
@@ -97,6 +98,12 @@ void adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
|
||||
distance = target_phantom.GetReverseDistance() - source_phantom.GetReverseDistance();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_ASSERT_MSG(distance >= 0 || distance > -1.0f,
|
||||
"Distance correction generated negative number");
|
||||
// guard against underflow errors caused by rounding
|
||||
distance = std::max(EdgeDistance{0}, distance);
|
||||
return distance;
|
||||
}
|
||||
|
||||
} // namespace routing_algorithms
|
||||
|
||||
@@ -100,7 +100,7 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
|
||||
const PhantomNodes & /*phantom_nodes*/,
|
||||
const EdgeWeight weight_upper_bound)
|
||||
{
|
||||
if (forward_heap.Empty() || reverse_heap.Empty())
|
||||
if (forward_heap.Empty() && reverse_heap.Empty())
|
||||
{
|
||||
weight = INVALID_EDGE_WEIGHT;
|
||||
return;
|
||||
@@ -110,10 +110,14 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
|
||||
weight = weight_upper_bound;
|
||||
|
||||
// get offset to account for offsets on phantom nodes on compressed edges
|
||||
const auto min_edge_offset = std::min(0, forward_heap.MinKey());
|
||||
BOOST_ASSERT(min_edge_offset <= 0);
|
||||
EdgeWeight min_edge_offset = 0;
|
||||
if (forward_heap.Size() > 0)
|
||||
{
|
||||
min_edge_offset = std::min(min_edge_offset, forward_heap.MinKey());
|
||||
BOOST_ASSERT(min_edge_offset <= 0);
|
||||
}
|
||||
// we only every insert negative offsets for nodes in the forward heap
|
||||
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
|
||||
BOOST_ASSERT(reverse_heap.Empty() || reverse_heap.MinKey() >= 0);
|
||||
|
||||
// run two-Target Dijkstra routing step.
|
||||
while (0 < (forward_heap.Size() + reverse_heap.Size()))
|
||||
@@ -176,11 +180,6 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const PhantomNode &target_phantom,
|
||||
EdgeWeight weight_upper_bound)
|
||||
{
|
||||
forward_heap.Clear();
|
||||
reverse_heap.Clear();
|
||||
|
||||
insertNodesInHeaps(forward_heap, reverse_heap, {source_phantom, target_phantom});
|
||||
|
||||
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
||||
std::vector<NodeID> packed_path;
|
||||
search(engine_working_data,
|
||||
@@ -199,8 +198,6 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
||||
return std::numeric_limits<double>::max();
|
||||
}
|
||||
|
||||
BOOST_ASSERT(nodes_number > 0);
|
||||
|
||||
EdgeDistance distance = 0;
|
||||
|
||||
std::vector<NodeID> unpacked_nodes;
|
||||
@@ -208,24 +205,24 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
||||
if (!packed_path.empty())
|
||||
{
|
||||
unpacked_nodes.push_back(packed_path.front());
|
||||
unpackPath(facade,
|
||||
packed_path.begin(),
|
||||
packed_path.end(),
|
||||
[&](std::pair<NodeID, NodeID> &edge, const auto &) {
|
||||
BOOST_ASSERT(edge.first == unpacked_nodes.back());
|
||||
unpacked_nodes.push_back(edge.second);
|
||||
});
|
||||
unpackPath(
|
||||
facade, packed_path.begin(), packed_path.end(), [&](const auto &edge, const auto &) {
|
||||
BOOST_ASSERT(edge.first == unpacked_nodes.back());
|
||||
unpacked_nodes.push_back(edge.second);
|
||||
});
|
||||
|
||||
for (auto node_iter = unpacked_nodes.begin(); node_iter != std::prev(unpacked_nodes.end());
|
||||
node_iter++)
|
||||
{
|
||||
distance += computeEdgeDistance(facade, *node_iter);
|
||||
}
|
||||
distance = std::accumulate(unpacked_nodes.begin(),
|
||||
std::prev(unpacked_nodes.end()),
|
||||
EdgeDistance{0},
|
||||
[&](const EdgeDistance distance, const auto node_id) {
|
||||
return distance + computeEdgeDistance(facade, node_id);
|
||||
});
|
||||
}
|
||||
|
||||
adjustPathDistanceToPhantomNodes(unpacked_nodes, source_phantom, target_phantom, distance);
|
||||
distance =
|
||||
adjustPathDistanceToPhantomNodes(unpacked_nodes, source_phantom, target_phantom, distance);
|
||||
|
||||
return distance / 10.;
|
||||
return distance;
|
||||
}
|
||||
} // namespace ch
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace
|
||||
|
||||
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
|
||||
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
|
||||
const constexpr long double EARTH_RADIUS = 6372797.560856;
|
||||
const constexpr double EARTH_RADIUS = 6372797.560856;
|
||||
|
||||
class CheapRulerContainer
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user