diff --git a/features/testbot/projection.feature b/features/testbot/projection.feature index 6d330b237..805ddc233 100644 --- a/features/testbot/projection.feature +++ b/features/testbot/projection.feature @@ -36,3 +36,38 @@ Feature: Projection to nearest point on road | from | to | route | distance | | d | b | abc,abc | 0m | | b | d | abc,abc | 0m | + + + Scenario: Projection results negative duration + Given the profile file "testbot" extended with + """ + api_version = 1 + function segment_function (segment) + segment.weight = 5.5 + segment.duration = 2.8 + end + """ + + Given the node locations + | node | lon | lat | + | e | -51.218994 | -30.023866 | + | f | -51.218918 | -30.023741 | + | 1 | -51.219109 | -30.023766 | + | 2 | -51.219109 | -30.023764 | + | 3 | -51.219109 | -30.023763 | + | 4 | -51.219109 | -30.023762 | + | 5 | -51.219109 | -30.023761 | + | 6 | -51.219109 | -30.023756 | + + And the ways + | nodes | + | ef | + + When I route I should get + | waypoints | route | distance | time | weight | + | 1,4 | ef,ef | 0.4m | 0.1s | 0.1 | + | 2,4 | ef,ef | 0.1m | 0s | 0 | + | 3,4 | ef,ef | 0.1m | 0s | 0 | + | 4,4 | ef,ef | 0m | 0s | 0 | + | 5,4 | ef,ef | 0.1m | 0s | 0.1 | + | 6,4 | ef,ef | 0.6m | 0.1s | 0.2 | diff --git a/include/engine/guidance/assemble_leg.hpp b/include/engine/guidance/assemble_leg.hpp index 4ab1db02c..5e1e2d6f2 100644 --- a/include/engine/guidance/assemble_leg.hpp +++ b/include/engine/guidance/assemble_leg.hpp @@ -170,10 +170,13 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade, weight = weight + target_weight; if (route_data.empty()) { - duration -= (target_traversed_in_reverse ? source_node.reverse_duration - : source_node.forward_duration); weight -= (target_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight); + duration -= (target_traversed_in_reverse ? source_node.reverse_duration + : source_node.forward_duration); + // use rectified linear unit function to avoid negative duration values + // due to flooring errors in phantom snapping + duration = std::max(0, duration); } std::string summary; diff --git a/include/engine/guidance/assemble_steps.hpp b/include/engine/guidance/assemble_steps.hpp index 0f52995d3..ee3771cb5 100644 --- a/include/engine/guidance/assemble_steps.hpp +++ b/include/engine/guidance/assemble_steps.hpp @@ -223,9 +223,11 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa // | |---------| source_weight // | |---| target_weight const EdgeWeight weight = target_weight - source_weight; - const EdgeWeight duration = target_duration - source_duration; BOOST_ASSERT(weight >= 0); - BOOST_ASSERT(duration >= 0); + + // use rectified linear unit function to avoid negative duration values + // due to flooring errors in phantom snapping + const EdgeWeight duration = std::max(0, target_duration - source_duration); steps.push_back(RouteStep{source_node.name_id, facade.GetNameForID(source_node.name_id).to_string(),