diff --git a/features/car/traffic_light_penalties.feature b/features/car/traffic_light_penalties.feature index ceb56d3a4..1d9bbe01f 100644 --- a/features/car/traffic_light_penalties.feature +++ b/features/car/traffic_light_penalties.feature @@ -37,3 +37,26 @@ Feature: Car - Handle traffic lights | 3 | 4 | 13.1s | no turn with traffic light | | g | j | 18.7s | turn with no traffic light | | k | n | 20.7s | turn with traffic light | + + + Scenario: Tarrif Signal Geometry + Given the query options + | overview | full | + | geometries | polyline | + + Given the node map + """ + a - b - c + """ + + And the ways + | nodes | highway | + | abc | primary | + + And the nodes + | node | highway | + | b | traffic_signals | + + When I route I should get + | from | to | route | geometry | + | a | c | abc,abc | _ibE_ibE?gJ?gJ | diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index a81b55fc4..637e108c9 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -11,6 +11,7 @@ #include "util/coordinate.hpp" #include "util/coordinate_calculation.hpp" +#include #include #include @@ -20,7 +21,6 @@ namespace engine { namespace guidance { - // Extracts the geometry for each segment and calculates the traveled distance // Combines the geometry form the phantom node with the PathData // to the full route geometry. @@ -54,8 +54,8 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, const auto source_node_id = reversed_source ? source_node.reverse_segment_id.id : source_node.forward_segment_id.id; const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id; - const std::vector source_geometry = - facade.GetUncompressedForwardGeometry(source_geometry_id); + std::vector source_geometry = facade.GetUncompressedForwardGeometry(source_geometry_id); + geometry.osm_node_ids.push_back( facade.GetOSMNodeIDOfNode(source_geometry[source_segment_start_coordinate])); @@ -78,21 +78,26 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, } prev_coordinate = coordinate; - geometry.annotations.emplace_back(LegGeometry::Annotation{ - current_distance, - // NOTE: we want annotations to include only the duration/weight - // of the segment itself. For segments immediately before - // a turn, the duration_until_turn/weight_until_turn values - // include the turn cost. To counter this, we subtract - // the duration_of_turn/weight_of_turn value, which is 0 for - // non-preceeding-turn segments, but contains the turn value - // for segments before a turn. - (path_point.duration_until_turn - path_point.duration_of_turn) / 10., - (path_point.weight_until_turn - path_point.weight_of_turn) / - facade.GetWeightMultiplier(), - path_point.datasource_id}); - geometry.locations.push_back(std::move(coordinate)); - geometry.osm_node_ids.push_back(facade.GetOSMNodeIDOfNode(path_point.turn_via_node)); + + const auto osm_node_id = facade.GetOSMNodeIDOfNode(path_point.turn_via_node); + if (osm_node_id != geometry.osm_node_ids.back()) + { + geometry.annotations.emplace_back(LegGeometry::Annotation{ + current_distance, + // NOTE: we want annotations to include only the duration/weight + // of the segment itself. For segments immediately before + // a turn, the duration_until_turn/weight_until_turn values + // include the turn cost. To counter this, we subtract + // the duration_of_turn/weight_of_turn value, which is 0 for + // non-preceeding-turn segments, but contains the turn value + // for segments before a turn. + (path_point.duration_until_turn - path_point.duration_of_turn) / 10., + (path_point.weight_until_turn - path_point.weight_of_turn) / + facade.GetWeightMultiplier(), + path_point.datasource_id}); + geometry.locations.push_back(std::move(coordinate)); + geometry.osm_node_ids.push_back(osm_node_id); + } } current_distance = util::coordinate_calculation::haversineDistance(prev_coordinate, target_node.location); diff --git a/include/engine/routing_algorithms/routing_base.hpp b/include/engine/routing_algorithms/routing_base.hpp index 0556f566e..d8556a17f 100644 --- a/include/engine/routing_algorithms/routing_base.hpp +++ b/include/engine/routing_algorithms/routing_base.hpp @@ -134,24 +134,13 @@ void annotatePath(const FacadeT &facade, BOOST_ASSERT(phantom_node_pair.target_phantom.forward_segment_id.id == target_node_id || phantom_node_pair.target_phantom.reverse_segment_id.id == target_node_id); - auto node_from = unpacked_nodes.begin(), node_last = std::prev(unpacked_nodes.end()); - for (auto edge = unpacked_edges.begin(); node_from != node_last; ++node_from, ++edge) - { - const auto &edge_data = facade.GetEdgeData(*edge); - const auto turn_id = edge_data.turn_id; // edge-based graph edge index - const auto node_id = *node_from; // edge-based graph node index - const auto name_index = facade.GetNameIndex(node_id); - const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id); - const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id); - const auto classes = facade.GetClassData(node_id); - - const auto geometry_index = facade.GetGeometryIndex(node_id); - std::vector id_vector; - - std::vector weight_vector; - std::vector duration_vector; - std::vector datasource_vector; + // datastructures to hold extracted data from geometry + std::vector id_vector; + std::vector weight_vector; + std::vector duration_vector; + std::vector datasource_vector; + const auto get_segment_geometry = [&](const auto geometry_index) { if (geometry_index.forward) { id_vector = facade.GetUncompressedForwardGeometry(geometry_index.id); @@ -166,6 +155,21 @@ void annotatePath(const FacadeT &facade, duration_vector = facade.GetUncompressedReverseDurations(geometry_index.id); datasource_vector = facade.GetUncompressedReverseDatasources(geometry_index.id); } + }; + + auto node_from = unpacked_nodes.begin(), node_last = std::prev(unpacked_nodes.end()); + for (auto edge = unpacked_edges.begin(); node_from != node_last; ++node_from, ++edge) + { + const auto &edge_data = facade.GetEdgeData(*edge); + const auto turn_id = edge_data.turn_id; // edge-based graph edge index + const auto node_id = *node_from; // edge-based graph node index + const auto name_index = facade.GetNameIndex(node_id); + const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id); + const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id); + const auto classes = facade.GetClassData(node_id); + + const auto geometry_index = facade.GetGeometryIndex(node_id); + get_segment_geometry(geometry_index); BOOST_ASSERT(id_vector.size() > 0); BOOST_ASSERT(datasource_vector.size() > 0); @@ -218,21 +222,14 @@ void annotatePath(const FacadeT &facade, } std::size_t start_index = 0, end_index = 0; - std::vector id_vector; - std::vector weight_vector; - std::vector duration_vector; - std::vector datasource_vector; const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id; - const auto target_geometry_id = facade.GetGeometryIndex(target_node_id).id; - const auto is_local_path = source_geometry_id == target_geometry_id && unpacked_path.empty(); + const auto target_geometry = facade.GetGeometryIndex(target_node_id); + const auto is_local_path = source_geometry_id == target_geometry.id && unpacked_path.empty(); + + get_segment_geometry(target_geometry); if (target_traversed_in_reverse) { - id_vector = facade.GetUncompressedReverseGeometry(target_geometry_id); - weight_vector = facade.GetUncompressedReverseWeights(target_geometry_id); - duration_vector = facade.GetUncompressedReverseDurations(target_geometry_id); - datasource_vector = facade.GetUncompressedReverseDatasources(target_geometry_id); - if (is_local_path) { start_index = @@ -248,11 +245,6 @@ void annotatePath(const FacadeT &facade, start_index = phantom_node_pair.source_phantom.fwd_segment_position; } end_index = phantom_node_pair.target_phantom.fwd_segment_position; - - id_vector = facade.GetUncompressedForwardGeometry(target_geometry_id); - weight_vector = facade.GetUncompressedForwardWeights(target_geometry_id); - duration_vector = facade.GetUncompressedForwardDurations(target_geometry_id); - datasource_vector = facade.GetUncompressedForwardDatasources(target_geometry_id); } // Given the following compressed geometry: