Port fix for gap logic

This commit is contained in:
Patrick Niklaus 2016-11-02 19:42:48 +00:00
parent 42afcdf115
commit 3905074a81
No known key found for this signature in database
GPG Key ID: E426891B5F978B1B

View File

@ -176,56 +176,29 @@ class MapMatching final : public BasicRoutingInterface<DataFacadeT, MapMatching<
prev_unbroken_timestamps.push_back(initial_timestamp); prev_unbroken_timestamps.push_back(initial_timestamp);
for (auto t = initial_timestamp + 1; t < candidates_list.size(); ++t) for (auto t = initial_timestamp + 1; t < candidates_list.size(); ++t)
{ {
// breakage recover has removed all previous good points
bool trace_split = prev_unbroken_timestamps.empty();
const bool gap_in_trace = [&, use_timestamps]() {
// use temporal information if available to determine a split // use temporal information if available to determine a split
if (use_timestamps) if (use_timestamps)
{ {
trace_split = return trace_timestamps[t] - trace_timestamps[prev_unbroken_timestamps.back()] >
trace_split || max_broken_time;
(trace_timestamps[t] - trace_timestamps[prev_unbroken_timestamps.back()] >
max_broken_time);
} }
else else
{ {
trace_split = return t - prev_unbroken_timestamps.back() > MAX_BROKEN_STATES;
trace_split || (t - prev_unbroken_timestamps.back() > MAX_BROKEN_STATES);
} }
}();
if (trace_split) if (!gap_in_trace)
{ {
std::size_t split_index = t;
if (breakage_begin != map_matching::INVALID_STATE)
{
split_index = breakage_begin;
breakage_begin = map_matching::INVALID_STATE;
}
split_points.push_back(split_index);
// note: this preserves everything before split_index
model.Clear(split_index);
std::size_t new_start = model.initialize(split_index);
// no new start was found -> stop viterbi calculation
if (new_start == map_matching::INVALID_STATE)
{
break;
}
prev_unbroken_timestamps.clear();
prev_unbroken_timestamps.push_back(new_start);
// Important: We potentially go back here!
// However since t > new_start >= breakge_begin
// we can only reset trace_coordindates.size() times.
t = new_start + 1;
}
BOOST_ASSERT(!prev_unbroken_timestamps.empty()); BOOST_ASSERT(!prev_unbroken_timestamps.empty());
const std::size_t prev_unbroken_timestamp = prev_unbroken_timestamps.back(); const std::size_t prev_unbroken_timestamp = prev_unbroken_timestamps.back();
const auto &prev_viterbi = model.viterbi[prev_unbroken_timestamp]; const auto &prev_viterbi = model.viterbi[prev_unbroken_timestamp];
const auto &prev_pruned = model.pruned[prev_unbroken_timestamp]; const auto &prev_pruned = model.pruned[prev_unbroken_timestamp];
const auto &prev_unbroken_timestamps_list = candidates_list[prev_unbroken_timestamp]; const auto &prev_unbroken_timestamps_list =
candidates_list[prev_unbroken_timestamp];
const auto &prev_coordinate = trace_coordinates[prev_unbroken_timestamp]; const auto &prev_coordinate = trace_coordinates[prev_unbroken_timestamp];
auto &current_viterbi = model.viterbi[t]; auto &current_viterbi = model.viterbi[t];
@ -238,7 +211,7 @@ class MapMatching final : public BasicRoutingInterface<DataFacadeT, MapMatching<
const auto haversine_distance = util::coordinate_calculation::haversineDistance( const auto haversine_distance = util::coordinate_calculation::haversineDistance(
prev_coordinate, current_coordinate); prev_coordinate, current_coordinate);
// assumes minumum of 0.1 m/s // assumes minumum of 0.1 m/s
const int duration_uppder_bound = const int duration_upper_bound =
((haversine_distance + max_distance_delta) * 0.25) * 10; ((haversine_distance + max_distance_delta) * 0.25) * 10;
// compute d_t for this timestamp and the next one // compute d_t for this timestamp and the next one
@ -249,9 +222,9 @@ class MapMatching final : public BasicRoutingInterface<DataFacadeT, MapMatching<
continue; continue;
} }
for (const auto s_prime : util::irange<std::size_t>(0UL, current_viterbi.size())) for (const auto s_prime :
util::irange<std::size_t>(0UL, current_viterbi.size()))
{ {
const double emission_pr = emission_log_probabilities[t][s_prime]; const double emission_pr = emission_log_probabilities[t][s_prime];
double new_value = prev_viterbi[s] + emission_pr; double new_value = prev_viterbi[s] + emission_pr;
if (current_viterbi[s_prime] > new_value) if (current_viterbi[s_prime] > new_value)
@ -274,7 +247,7 @@ class MapMatching final : public BasicRoutingInterface<DataFacadeT, MapMatching<
reverse_core_heap, reverse_core_heap,
prev_unbroken_timestamps_list[s].phantom_node, prev_unbroken_timestamps_list[s].phantom_node,
current_timestamps_list[s_prime].phantom_node, current_timestamps_list[s_prime].phantom_node,
duration_uppder_bound); duration_upper_bound);
} }
else else
{ {
@ -326,6 +299,39 @@ class MapMatching final : public BasicRoutingInterface<DataFacadeT, MapMatching<
} }
} }
// breakage recover has removed all previous good points
const bool trace_split = prev_unbroken_timestamps.empty();
if (trace_split || gap_in_trace)
{
std::size_t split_index = t;
if (breakage_begin != map_matching::INVALID_STATE)
{
split_index = breakage_begin;
breakage_begin = map_matching::INVALID_STATE;
}
split_points.push_back(split_index);
// note: this preserves everything before split_index
model.Clear(split_index);
std::size_t new_start = model.initialize(split_index);
// no new start was found -> stop viterbi calculation
if (new_start == map_matching::INVALID_STATE)
{
break;
}
prev_unbroken_timestamps.clear();
prev_unbroken_timestamps.push_back(new_start);
// Important: We potentially go back here!
// However since t > new_start >= breakge_begin
// we can only reset trace_coordindates.size() times.
t = new_start;
// note: the head of the loop will call ++t, hence the next
// iteration will actually be on new_start+1
}
}
if (!prev_unbroken_timestamps.empty()) if (!prev_unbroken_timestamps.empty())
{ {
split_points.push_back(prev_unbroken_timestamps.back() + 1); split_points.push_back(prev_unbroken_timestamps.back() + 1);