Calculate the real route length for classification

This commit is contained in:
Patrick Niklaus 2015-02-12 11:44:52 +01:00
parent 38d7db49c8
commit b3fa03043d
2 changed files with 22 additions and 34 deletions

View File

@ -72,16 +72,9 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
const std::string GetDescriptor() const final { return descriptor_string; } const std::string GetDescriptor() const final { return descriptor_string; }
TraceClassification classify(double trace_length, const std::vector<PhantomNode>& matched_nodes, int removed_points) const TraceClassification classify(float trace_length, float matched_length, int removed_points) const
{ {
double matching_length = 0; double distance_feature = -std::log(trace_length) + std::log(matched_length);
for (const auto current_node : osrm::irange<std::size_t>(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);
// matched to the same point // matched to the same point
if (!std::isfinite(distance_feature)) if (!std::isfinite(distance_feature))
@ -189,11 +182,12 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
// call the actual map matching // call the actual map matching
JSON::Object debug_info; JSON::Object debug_info;
float matched_length;
std::vector<PhantomNode> matched_nodes; std::vector<PhantomNode> 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 // 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) if (classification.first == ClassifierT::ClassLabel::POSITIVE)
{ {
json_result.values["confidence"] = classification.second; json_result.values["confidence"] = classification.second;

View File

@ -144,23 +144,6 @@ template <class DataFacadeT> class MapMatching final
// 29 32.21683062 // 29 32.21683062
// 30 34.56991141 // 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, double get_network_distance(const PhantomNode &source_phantom,
const PhantomNode &target_phantom) const const PhantomNode &target_phantom) const
{ {
@ -253,6 +236,7 @@ template <class DataFacadeT> class MapMatching final
void operator()(const Matching::CandidateLists &timestamp_list, void operator()(const Matching::CandidateLists &timestamp_list,
const std::vector<FixedPointCoordinate> coordinate_list, const std::vector<FixedPointCoordinate> coordinate_list,
std::vector<PhantomNode>& matched_nodes, std::vector<PhantomNode>& matched_nodes,
float& matched_length,
JSON::Object& _debug_info) const JSON::Object& _debug_info) const
{ {
std::vector<bool> breakage(timestamp_list.size(), true); std::vector<bool> breakage(timestamp_list.size(), true);
@ -262,11 +246,13 @@ template <class DataFacadeT> class MapMatching final
// TODO for the viterbi values we actually only need the current and last row // TODO for the viterbi values we actually only need the current and last row
std::vector<std::vector<double>> viterbi; std::vector<std::vector<double>> viterbi;
std::vector<std::vector<std::size_t>> parents; std::vector<std::vector<std::size_t>> parents;
std::vector<std::vector<float>> segment_lengths;
std::vector<std::vector<bool>> pruned; std::vector<std::vector<bool>> pruned;
for (const auto& l : timestamp_list) for (const auto& l : timestamp_list)
{ {
viterbi.emplace_back(l.size(), -std::numeric_limits<double>::infinity()); viterbi.emplace_back(l.size(), -std::numeric_limits<double>::infinity());
parents.emplace_back(l.size(), 0); parents.emplace_back(l.size(), 0);
segment_lengths.emplace_back(l.size(), 0);
pruned.emplace_back(l.size(), true); pruned.emplace_back(l.size(), true);
} }
@ -326,6 +312,7 @@ template <class DataFacadeT> class MapMatching final
auto& current_viterbi = viterbi[t]; auto& current_viterbi = viterbi[t];
auto& current_pruned = pruned[t]; auto& current_pruned = pruned[t];
auto& current_parents = parents[t]; auto& current_parents = parents[t];
auto& current_lengths = segment_lengths[t];
const auto& current_timestamps_list = timestamp_list[t]; const auto& current_timestamps_list = timestamp_list[t];
const auto& current_coordinate = coordinate_list[t]; const auto& current_coordinate = coordinate_list[t];
@ -344,10 +331,14 @@ template <class DataFacadeT> class MapMatching final
continue; continue;
// get distance diff between loc1/2 and locs/s_prime // get distance diff between loc1/2 and locs/s_prime
const auto d_t = get_distance_difference(prev_coordinate, const auto network_distance = get_network_distance(prev_unbroken_timestamps_list[s].first,
current_coordinate,
prev_unbroken_timestamps_list[s].first,
current_timestamps_list[s_prime].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 // very low probability transition -> prune
if (d_t > 500) if (d_t > 500)
continue; continue;
@ -361,8 +352,8 @@ template <class DataFacadeT> class MapMatching final
makeJSONSafe(prev_viterbi[s]), makeJSONSafe(prev_viterbi[s]),
makeJSONSafe(emission_pr), makeJSONSafe(emission_pr),
makeJSONSafe(transition_pr), makeJSONSafe(transition_pr),
get_network_distance(prev_unbroken_timestamps_list[s].first, current_timestamps_list[s_prime].first), network_distance,
coordinate_calculation::great_circle_distance(prev_coordinate, current_coordinate) great_circle_distance
); );
_debug_states.values[prev_unbroken_timestamp] _debug_states.values[prev_unbroken_timestamp]
.get<JSONVariantArray>().get().values[s] .get<JSONVariantArray>().get().values[s]
@ -374,6 +365,7 @@ template <class DataFacadeT> class MapMatching final
{ {
current_viterbi[s_prime] = new_value; current_viterbi[s_prime] = new_value;
current_parents[s_prime] = s; current_parents[s_prime] = s;
current_lengths[s_prime] = network_distance;
current_pruned[s_prime] = false; current_pruned[s_prime] = false;
breakage[t] = false; breakage[t] = false;
} }
@ -410,6 +402,7 @@ template <class DataFacadeT> class MapMatching final
} }
reconstructed_indices.emplace_front(initial_timestamp, parent_index); reconstructed_indices.emplace_front(initial_timestamp, parent_index);
matched_length = 0.0f;
matched_nodes.resize(reconstructed_indices.size()); matched_nodes.resize(reconstructed_indices.size());
for (auto i = 0u; i < reconstructed_indices.size(); ++i) for (auto i = 0u; i < reconstructed_indices.size(); ++i)
{ {
@ -417,6 +410,7 @@ template <class DataFacadeT> class MapMatching final
auto location_index = reconstructed_indices[i].second; auto location_index = reconstructed_indices[i].second;
matched_nodes[i] = timestamp_list[timestamp_index][location_index].first; matched_nodes[i] = timestamp_list[timestamp_index][location_index].first;
matched_length += segment_lengths[timestamp_index][location_index];
_debug_states.values[timestamp_index] _debug_states.values[timestamp_index]
.get<JSONVariantArray>().get().values[location_index] .get<JSONVariantArray>().get().values[location_index]