osrm-backend icon indicating copy to clipboard operation
osrm-backend copied to clipboard

How to use angle in map-matching.

Open Rejudge-F opened this issue 2 years ago • 8 comments

Hi team,I think angle is an important factor in map matching, how can I use it in osrm. I found transition_probability only rely on const auto d_t = std::abs(network_distance - haversine_distance); but I think the angle between pre-current phantom node and trace coordinates should also be taken into, i modified it slightly(the commented part of the code), want to hear team opinion. I tested about 100 angle-related cases, and the accuracy rate has greatly improved.

// include/engine/map_matching/hidden_markov_model.hpp
struct TransitionAngleLogProbability
{
    double sigma_z;
    double log_sigma_z;

    TransitionAngleLogProbability(const double sigma_z) : sigma_z(sigma_z), log_sigma_z(std::log(sigma_z))
    {
    }

    double operator()(const double distance) const
    {
        return -0.5 * (log_2_pi + (distance / sigma_z) * (distance / sigma_z)) - log_sigma_z;
    }
};
// src/engine/routing_algorithms/map_matching.cpp:222
// compute d_t for this timestamp and the next one
for (const auto s: util::irange<std::size_t>(0UL, prev_viterbi.size())) {
if (prev_pruned[s]) {
    continue;
}

for (const auto s_prime: util::irange<std::size_t>(0UL, current_viterbi.size())) {
    const double emission_pr = emission_log_probabilities[t][s_prime];
    double new_value = prev_viterbi[s] + emission_pr;
    if (current_viterbi[s_prime] > new_value) {
        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);

    // get distance diff between loc1/2 and locs/s_prime
    const auto d_t = std::abs(network_distance - haversine_distance);

    // very low probability transition -> prune
    if (d_t >= max_distance_delta) {
        continue;
    }

    const double transition_pr = transition_log_probability(d_t);
    new_value += transition_pr;

//                        calculate angle transition probability
//                        const PhantomNodeWithDistance &pre_phantom_node = prev_unbroken_timestamps_list[s];
//                        const PhantomNodeWithDistance &current_phantom_node = current_timestamps_list[s_prime];
//
//                        FixedLongitude translate_longitude =
//                                prev_coordinate.lon - pre_phantom_node.phantom_node.location.lon;
//                        FixedLatitude translate_latitude =
//                                prev_coordinate.lat - pre_phantom_node.phantom_node.location.lat;
//
//                        double transition_angle = util::coordinate_calculation::computeAngle(
//                                util::Coordinate(current_phantom_node.phantom_node.location.lon + translate_longitude,
//                                                 current_phantom_node.phantom_node.location.lat + translate_latitude),
//                                prev_coordinate, current_coordinate);
//
//                        // norm angle to
//                        transition_angle = transition_angle > 180 ? 360 - transition_angle : transition_angle;
//
//                        const double transition_angle_pr = transition_angle_log_probability(transition_angle);
//                        new_value += transition_angle_pr;

    if (new_value > current_viterbi[s_prime]) {
        current_viterbi[s_prime] = new_value;
        current_parents[s_prime] = std::make_pair(prev_unbroken_timestamp, s);
        current_lengths[s_prime] = network_distance;
        current_pruned[s_prime] = false;
        model.breakage[t] = false;
    }
}
}

Rejudge-F avatar Feb 06 '23 03:02 Rejudge-F