correct handling of travel modes
This commit is contained in:
		
							parent
							
								
									65183e94c6
								
							
						
					
					
						commit
						2679c1cf0a
					
				@ -25,6 +25,22 @@ Feature: Testbot - Travel mode
 | 
			
		||||
        When I route I should get
 | 
			
		||||
            | from | to | route        | modes |
 | 
			
		||||
            | a    | d  | foo,foo,foo  | 1,3,1 |
 | 
			
		||||
            | b    | d  | foo,foo      | 3,1   |
 | 
			
		||||
 | 
			
		||||
    Scenario: Testbot - Compressed Modes
 | 
			
		||||
        Given the node map
 | 
			
		||||
            | a | b | c | d | e | f | g |
 | 
			
		||||
 | 
			
		||||
        And the ways
 | 
			
		||||
            | nodes | highway     | name   |
 | 
			
		||||
            | abc   | residential | road   |
 | 
			
		||||
            | cde   | river       | liquid |
 | 
			
		||||
            | efg   | residential | solid  |
 | 
			
		||||
 | 
			
		||||
        When I route I should get
 | 
			
		||||
            | from | to | route              | modes | turns                              |
 | 
			
		||||
            | a    | g  | road,liquid,solid  | 1,3,1 | head,straight,straight,destination |
 | 
			
		||||
            | c    | g  | liquid,solid       | 3,1   | head,straight,destination          |
 | 
			
		||||
 | 
			
		||||
    Scenario: Testbot - Modes in each direction, different forward/backward speeds
 | 
			
		||||
        Given the node map
 | 
			
		||||
 | 
			
		||||
@ -154,7 +154,7 @@ void SegmentList<DataFacadeT>::AddLeg(const std::vector<PathData> &leg_data,
 | 
			
		||||
                                      const bool is_via_leg,
 | 
			
		||||
                                      const DataFacade *facade)
 | 
			
		||||
{
 | 
			
		||||
    for (const PathData &path_data : leg_data)
 | 
			
		||||
    for (const auto &path_data : leg_data)
 | 
			
		||||
    {
 | 
			
		||||
        AppendSegment(facade->GetCoordinateOfNode(path_data.node), path_data);
 | 
			
		||||
    }
 | 
			
		||||
@ -196,32 +196,7 @@ template <typename DataFacadeT>
 | 
			
		||||
void SegmentList<DataFacadeT>::AppendSegment(const FixedPointCoordinate coordinate,
 | 
			
		||||
                                             const PathData &path_point)
 | 
			
		||||
{
 | 
			
		||||
    // if the start location is on top of a node, the first movement might be zero-length,
 | 
			
		||||
    // in which case we dont' add a new description, but instead update the existing one
 | 
			
		||||
    if ((1 == segments.size()) && (segments.front().location == coordinate))
 | 
			
		||||
    {
 | 
			
		||||
        if (path_point.segment_duration > 0)
 | 
			
		||||
        {
 | 
			
		||||
            segments.front().name_id = path_point.name_id;
 | 
			
		||||
            segments.front().travel_mode = path_point.travel_mode;
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // make sure mode changes are announced, even when there otherwise is no turn
 | 
			
		||||
    const auto getTurn = [](const PathData &path_point, const extractor::TravelMode previous_mode)
 | 
			
		||||
    {
 | 
			
		||||
        if (extractor::TurnInstruction::NoTurn == path_point.turn_instruction &&
 | 
			
		||||
            previous_mode != path_point.travel_mode && path_point.segment_duration > 0)
 | 
			
		||||
        {
 | 
			
		||||
            return extractor::TurnInstruction::GoStraight;
 | 
			
		||||
        }
 | 
			
		||||
        return path_point.turn_instruction;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // TODO check why we require .front() here
 | 
			
		||||
    const auto turn = segments.size() ? getTurn(path_point, segments.front().travel_mode)
 | 
			
		||||
                                      : path_point.turn_instruction;
 | 
			
		||||
    const auto turn = path_point.turn_instruction;
 | 
			
		||||
 | 
			
		||||
    segments.emplace_back(coordinate, path_point.name_id, path_point.segment_duration, 0.f, turn,
 | 
			
		||||
                          path_point.travel_mode);
 | 
			
		||||
@ -236,6 +211,30 @@ void SegmentList<DataFacadeT>::Finalize(const bool extract_alternative,
 | 
			
		||||
    if (segments.empty())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    // check if first two segments can be merged
 | 
			
		||||
    BOOST_ASSERT(segments.size() >= 2);
 | 
			
		||||
    if (segments[0].location == segments[1].location &&
 | 
			
		||||
        segments[1].turn_instruction == extractor::TurnInstruction::NoTurn)
 | 
			
		||||
    {
 | 
			
		||||
        segments[0].travel_mode = segments[1].travel_mode;
 | 
			
		||||
        segments[0].name_id = segments[1].name_id;
 | 
			
		||||
        // Other data??
 | 
			
		||||
        segments.erase(segments.begin() + 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // announce mode changes
 | 
			
		||||
    for (std::size_t i = 0; i + 1 < segments.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        auto &segment = segments[i];
 | 
			
		||||
        const auto next_mode = segments[i + 1].travel_mode;
 | 
			
		||||
        if (segment.travel_mode != next_mode &&
 | 
			
		||||
            segment.turn_instruction == extractor::TurnInstruction::NoTurn)
 | 
			
		||||
        {
 | 
			
		||||
            segment.turn_instruction = extractor::TurnInstruction::GoStraight;
 | 
			
		||||
            segment.necessary = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    segments[0].length = 0.f;
 | 
			
		||||
    for (const auto i : util::irange<std::size_t>(1, segments.size()))
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -44,8 +44,9 @@ inline util::json::Array AnnotateRoute(const std::vector<SegmentInformation> &ro
 | 
			
		||||
    extractor::TravelMode last_travel_mode = TRAVEL_MODE_DEFAULT;
 | 
			
		||||
 | 
			
		||||
    // Generate annotations for every segment
 | 
			
		||||
    for (const SegmentInformation &segment : route_segments)
 | 
			
		||||
    for (std::size_t i = 0; i < route_segments.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        const auto &segment = route_segments[i];
 | 
			
		||||
        util::json::Array json_instruction_row;
 | 
			
		||||
        extractor::TurnInstruction current_instruction = segment.turn_instruction;
 | 
			
		||||
        if (extractor::isTurnNecessary(current_instruction))
 | 
			
		||||
@ -89,8 +90,17 @@ inline util::json::Array AnnotateRoute(const std::vector<SegmentInformation> &ro
 | 
			
		||||
                json_instruction_row.values.push_back(
 | 
			
		||||
                    static_cast<std::uint32_t>(std::round(post_turn_bearing_value)));
 | 
			
		||||
 | 
			
		||||
                if (i + 1 < route_segments.size())
 | 
			
		||||
                {
 | 
			
		||||
                    // anounce next travel mode with turn
 | 
			
		||||
                    json_instruction_row.values.push_back(route_segments[i + 1].travel_mode);
 | 
			
		||||
                    last_travel_mode = segment.travel_mode;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    json_instruction_row.values.push_back(segment.travel_mode);
 | 
			
		||||
                    last_travel_mode = segment.travel_mode;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // pre turn bearing
 | 
			
		||||
                const double pre_turn_bearing_value = (segment.pre_turn_bearing / 10.);
 | 
			
		||||
 | 
			
		||||
@ -99,8 +99,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
 | 
			
		||||
                    (!force_loop_forward ||
 | 
			
		||||
                     forward_heap.GetData(node).parent !=
 | 
			
		||||
                         node) // if loops are forced, they are so at the source
 | 
			
		||||
                    &&
 | 
			
		||||
                    (!force_loop_reverse || reverse_heap.GetData(node).parent != node))
 | 
			
		||||
                    && (!force_loop_reverse || reverse_heap.GetData(node).parent != node))
 | 
			
		||||
                {
 | 
			
		||||
                    middle_node_id = node;
 | 
			
		||||
                    upper_bound = new_distance;
 | 
			
		||||
@ -290,7 +289,10 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
 | 
			
		||||
                unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
 | 
			
		||||
                const extractor::TurnInstruction turn_instruction =
 | 
			
		||||
                    facade->GetTurnInstructionForEdgeID(ed.id);
 | 
			
		||||
                const extractor::TravelMode travel_mode = facade->GetTravelModeForEdgeID(ed.id);
 | 
			
		||||
                const extractor::TravelMode travel_mode =
 | 
			
		||||
                    (unpacked_path.empty() && start_traversed_in_reverse)
 | 
			
		||||
                        ? phantom_node_pair.source_phantom.backward_travel_mode
 | 
			
		||||
                        : facade->GetTravelModeForEdgeID(ed.id);
 | 
			
		||||
 | 
			
		||||
                if (!facade->EdgeIsCompressed(ed.id))
 | 
			
		||||
                {
 | 
			
		||||
@ -364,11 +366,11 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
 | 
			
		||||
                BOOST_ASSERT(i < id_vector.size());
 | 
			
		||||
                BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0);
 | 
			
		||||
                unpacked_path.emplace_back(
 | 
			
		||||
                    PathData{id_vector[i],
 | 
			
		||||
                             phantom_node_pair.target_phantom.name_id,
 | 
			
		||||
                             extractor::TurnInstruction::NoTurn,
 | 
			
		||||
                             0,
 | 
			
		||||
                             phantom_node_pair.target_phantom.forward_travel_mode});
 | 
			
		||||
                    PathData{id_vector[i], phantom_node_pair.target_phantom.name_id,
 | 
			
		||||
                             extractor::TurnInstruction::NoTurn, 0,
 | 
			
		||||
                             target_traversed_in_reverse
 | 
			
		||||
                                 ? phantom_node_pair.target_phantom.backward_travel_mode
 | 
			
		||||
                                 : phantom_node_pair.target_phantom.forward_travel_mode});
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -560,6 +562,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
 | 
			
		||||
                        const bool force_loop_reverse) const
 | 
			
		||||
    {
 | 
			
		||||
        NodeID middle = SPECIAL_NODEID;
 | 
			
		||||
        distance = INVALID_EDGE_WEIGHT;
 | 
			
		||||
 | 
			
		||||
        std::vector<std::pair<NodeID, EdgeWeight>> forward_entry_points;
 | 
			
		||||
        std::vector<std::pair<NodeID, EdgeWeight>> reverse_entry_points;
 | 
			
		||||
@ -602,11 +605,10 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // TODO check if unordered_set might be faster
 | 
			
		||||
        // sort by id and increasing by distance
 | 
			
		||||
        auto entry_point_comparator =
 | 
			
		||||
            [](const std::pair<NodeID, EdgeWeight> &lhs, const std::pair<NodeID, EdgeWeight> &rhs)
 | 
			
		||||
        auto entry_point_comparator = [](const std::pair<NodeID, EdgeWeight> &lhs,
 | 
			
		||||
                                         const std::pair<NodeID, EdgeWeight> &rhs)
 | 
			
		||||
        {
 | 
			
		||||
            return lhs.first < rhs.first || (lhs.first == rhs.first && lhs.second < rhs.second);
 | 
			
		||||
        };
 | 
			
		||||
@ -614,6 +616,8 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
 | 
			
		||||
        std::sort(reverse_entry_points.begin(), reverse_entry_points.end(), entry_point_comparator);
 | 
			
		||||
 | 
			
		||||
        NodeID last_id = SPECIAL_NODEID;
 | 
			
		||||
        forward_core_heap.Clear();
 | 
			
		||||
        reverse_core_heap.Clear();
 | 
			
		||||
        for (const auto p : forward_entry_points)
 | 
			
		||||
        {
 | 
			
		||||
            if (p.first == last_id)
 | 
			
		||||
 | 
			
		||||
@ -180,6 +180,7 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeI
 | 
			
		||||
                reverse_geometry[geometry_size - 1 - i].second, forward_dist_prefix_sum[i],
 | 
			
		||||
                reverse_dist_prefix_sum[i], m_compressed_edge_container.GetPositionForID(edge_id_1),
 | 
			
		||||
                false, INVALID_COMPONENTID, i, forward_data.travel_mode, reverse_data.travel_mode);
 | 
			
		||||
 | 
			
		||||
            m_edge_based_node_is_startpoint.push_back(forward_data.startpoint ||
 | 
			
		||||
                                                      reverse_data.startpoint);
 | 
			
		||||
            current_edge_source_coordinate_id = current_edge_target_coordinate_id;
 | 
			
		||||
@ -483,7 +484,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
 | 
			
		||||
                    (edge_is_compressed ? m_compressed_edge_container.GetPositionForID(edge_form_u)
 | 
			
		||||
                                        : node_v),
 | 
			
		||||
                    edge_data1.name_id, turn_instruction, edge_is_compressed,
 | 
			
		||||
                    edge_data2.travel_mode);
 | 
			
		||||
                    edge_data1.travel_mode);
 | 
			
		||||
 | 
			
		||||
                ++original_edges_counter;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user