From b3fa03043d604ca443bbf7a10f3500da0ba8f11e Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Thu, 12 Feb 2015 11:44:52 +0100 Subject: [PATCH] Calculate the real route length for classification --- plugins/map_matching.hpp | 16 ++++-------- routing_algorithms/map_matching.hpp | 40 ++++++++++++----------------- 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/plugins/map_matching.hpp b/plugins/map_matching.hpp index f4dec3676..0f9a94c80 100644 --- a/plugins/map_matching.hpp +++ b/plugins/map_matching.hpp @@ -72,16 +72,9 @@ template class MapMatchingPlugin : public BasePlugin const std::string GetDescriptor() const final { return descriptor_string; } - TraceClassification classify(double trace_length, const std::vector& matched_nodes, int removed_points) const + TraceClassification classify(float trace_length, float matched_length, int removed_points) const { - double matching_length = 0; - for (const auto current_node : osrm::irange(0, matched_nodes.size()-1)) - { - matching_length += coordinate_calculation::great_circle_distance( - matched_nodes[current_node].location, - matched_nodes[current_node + 1].location); - } - double distance_feature = -std::log(trace_length) + std::log(matching_length); + double distance_feature = -std::log(trace_length) + std::log(matched_length); // matched to the same point if (!std::isfinite(distance_feature)) @@ -189,11 +182,12 @@ template class MapMatchingPlugin : public BasePlugin // call the actual map matching JSON::Object debug_info; + float matched_length; std::vector matched_nodes; - search_engine_ptr->map_matching(candidates_lists, input_coords, matched_nodes, debug_info); + search_engine_ptr->map_matching(candidates_lists, input_coords, matched_nodes, matched_length, debug_info); // classify result - TraceClassification classification = classify(trace_length, matched_nodes, input_coords.size() - matched_nodes.size()); + TraceClassification classification = classify(trace_length, matched_length, input_coords.size() - matched_nodes.size()); if (classification.first == ClassifierT::ClassLabel::POSITIVE) { json_result.values["confidence"] = classification.second; diff --git a/routing_algorithms/map_matching.hpp b/routing_algorithms/map_matching.hpp index 0f2cc0c0c..a87a739eb 100644 --- a/routing_algorithms/map_matching.hpp +++ b/routing_algorithms/map_matching.hpp @@ -144,23 +144,6 @@ template class MapMatching final // 29 32.21683062 // 30 34.56991141 - double get_distance_difference(const FixedPointCoordinate &location1, - const FixedPointCoordinate &location2, - const PhantomNode &source_phantom, - const PhantomNode &target_phantom) const - { - // great circle distance of two locations - median/avg dist table(candidate list1/2) - const auto network_distance = get_network_distance(source_phantom, target_phantom); - const auto great_circle_distance = - coordinate_calculation::great_circle_distance(location1, location2); - - if (great_circle_distance > network_distance) - { - return great_circle_distance - network_distance; - } - return network_distance - great_circle_distance; - } - double get_network_distance(const PhantomNode &source_phantom, const PhantomNode &target_phantom) const { @@ -253,6 +236,7 @@ template class MapMatching final void operator()(const Matching::CandidateLists ×tamp_list, const std::vector coordinate_list, std::vector& matched_nodes, + float& matched_length, JSON::Object& _debug_info) const { std::vector breakage(timestamp_list.size(), true); @@ -262,11 +246,13 @@ template class MapMatching final // TODO for the viterbi values we actually only need the current and last row std::vector> viterbi; std::vector> parents; + std::vector> segment_lengths; std::vector> pruned; for (const auto& l : timestamp_list) { viterbi.emplace_back(l.size(), -std::numeric_limits::infinity()); parents.emplace_back(l.size(), 0); + segment_lengths.emplace_back(l.size(), 0); pruned.emplace_back(l.size(), true); } @@ -326,6 +312,7 @@ template class MapMatching final auto& current_viterbi = viterbi[t]; auto& current_pruned = pruned[t]; auto& current_parents = parents[t]; + auto& current_lengths = segment_lengths[t]; const auto& current_timestamps_list = timestamp_list[t]; const auto& current_coordinate = coordinate_list[t]; @@ -344,10 +331,14 @@ template class MapMatching final continue; // get distance diff between loc1/2 and locs/s_prime - const auto d_t = get_distance_difference(prev_coordinate, - current_coordinate, - prev_unbroken_timestamps_list[s].first, - current_timestamps_list[s_prime].first); + const auto network_distance = get_network_distance(prev_unbroken_timestamps_list[s].first, + current_timestamps_list[s_prime].first); + const auto great_circle_distance = + coordinate_calculation::great_circle_distance(prev_coordinate, + current_coordinate); + + const auto d_t = std::abs(network_distance - great_circle_distance); + // very low probability transition -> prune if (d_t > 500) continue; @@ -361,8 +352,8 @@ template class MapMatching final makeJSONSafe(prev_viterbi[s]), makeJSONSafe(emission_pr), makeJSONSafe(transition_pr), - get_network_distance(prev_unbroken_timestamps_list[s].first, current_timestamps_list[s_prime].first), - coordinate_calculation::great_circle_distance(prev_coordinate, current_coordinate) + network_distance, + great_circle_distance ); _debug_states.values[prev_unbroken_timestamp] .get().get().values[s] @@ -374,6 +365,7 @@ template class MapMatching final { current_viterbi[s_prime] = new_value; current_parents[s_prime] = s; + current_lengths[s_prime] = network_distance; current_pruned[s_prime] = false; breakage[t] = false; } @@ -410,6 +402,7 @@ template class MapMatching final } reconstructed_indices.emplace_front(initial_timestamp, parent_index); + matched_length = 0.0f; matched_nodes.resize(reconstructed_indices.size()); for (auto i = 0u; i < reconstructed_indices.size(); ++i) { @@ -417,6 +410,7 @@ template class MapMatching final auto location_index = reconstructed_indices[i].second; matched_nodes[i] = timestamp_list[timestamp_index][location_index].first; + matched_length += segment_lengths[timestamp_index][location_index]; _debug_states.values[timestamp_index] .get().get().values[location_index]