less new names, forks consider road classes, api clean-up
This commit is contained in:
		
							parent
							
								
									7b755eea54
								
							
						
					
					
						commit
						ee5020baf3
					
				
							
								
								
									
										140
									
								
								features/guidance/roundabout.feature
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								features/guidance/roundabout.feature
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,140 @@
 | 
			
		||||
@routing  @guidance
 | 
			
		||||
Feature: Basic Roundabout
 | 
			
		||||
 | 
			
		||||
    Background:
 | 
			
		||||
        Given the profile "testbot"
 | 
			
		||||
        Given a grid size of 10 meters
 | 
			
		||||
 | 
			
		||||
    Scenario: Enter and Exit
 | 
			
		||||
        Given the node map
 | 
			
		||||
            |   |   | a  |   |   |
 | 
			
		||||
            |   |   | b  |   |   |
 | 
			
		||||
            | h | g |    | c | d |
 | 
			
		||||
            |   |   | e  |   |   |
 | 
			
		||||
            |   |   | f  |   |   |
 | 
			
		||||
 | 
			
		||||
       And the ways
 | 
			
		||||
            | nodes  | roundabout |
 | 
			
		||||
            | ab     | false      |
 | 
			
		||||
            | cd     | false      |
 | 
			
		||||
            | ef     | false      |
 | 
			
		||||
            | gh     | false      |
 | 
			
		||||
            | bcegb  | true       |
 | 
			
		||||
 | 
			
		||||
       When I route I should get
 | 
			
		||||
           | waypoints | route    | turns                             |
 | 
			
		||||
           | a,d       | ab,cd,cd | depart, roundabout-exit-1, arrive |
 | 
			
		||||
           | a,f       | ab,ef,ef | depart, roundabout-exit-2, arrive |
 | 
			
		||||
           | a,h       | ab,gh,gh | depart, roundabout-exit-3, arrive |
 | 
			
		||||
           | d,f       | cd,ef,ef | depart, roundabout-exit-1, arrive |
 | 
			
		||||
           | d,h       | cd,gh,gh | depart, roundabout-exit-2, arrive |
 | 
			
		||||
           | d,a       | cd,ab,ab | depart, roundabout-exit-3, arrive |
 | 
			
		||||
           | f,h       | ef,gh,gh | depart, roundabout-exit-1, arrive |
 | 
			
		||||
           | f,a       | ef,ab,ab | depart, roundabout-exit-2, arrive |
 | 
			
		||||
           | f,d       | ef,cd,cd | depart, roundabout-exit-3, arrive |
 | 
			
		||||
           | h,a       | gh,ab,ab | depart, roundabout-exit-1, arrive |
 | 
			
		||||
           | h,d       | gh,cd,cd | depart, roundabout-exit-2, arrive |
 | 
			
		||||
           | h,f       | gh,ef,ef | depart, roundabout-exit-3, arrive |
 | 
			
		||||
 | 
			
		||||
    Scenario: Only Enter
 | 
			
		||||
        Given the node map
 | 
			
		||||
            |   |   | a  |   |   |
 | 
			
		||||
            |   |   | b  |   |   |
 | 
			
		||||
            | h | g |    | c | d |
 | 
			
		||||
            |   |   | e  |   |   |
 | 
			
		||||
            |   |   | f  |   |   |
 | 
			
		||||
 | 
			
		||||
       And the ways
 | 
			
		||||
            | nodes  | roundabout |
 | 
			
		||||
            | ab     | false      |
 | 
			
		||||
            | cd     | false      |
 | 
			
		||||
            | ef     | false      |
 | 
			
		||||
            | gh     | false      |
 | 
			
		||||
            | bcegb  | true       |
 | 
			
		||||
 | 
			
		||||
       When I route I should get
 | 
			
		||||
           | waypoints | route    | turns                            |
 | 
			
		||||
           | a,b       | ab,ab    | depart, arrive                   |
 | 
			
		||||
           | a,c       | ab,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | a,e       | ab,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | a,g       | ab,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | d,c       | cd,cd    | depart, arrive                   |
 | 
			
		||||
           | d,e       | cd,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | d,g       | cd,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | d,b       | cd,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | f,e       | ef,ef    | depart, arrive                   |
 | 
			
		||||
           | f,g       | ef,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | f,b       | ef,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | f,c       | ef,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | h,g       | gh,gh    | depart, arrive                   |
 | 
			
		||||
           | h,b       | gh,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | h,c       | gh,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
           | h,e       | gh,bcegb | depart, roundabout-enter, arrive |
 | 
			
		||||
 | 
			
		||||
    Scenario: Only Exit
 | 
			
		||||
        Given the node map
 | 
			
		||||
            |   |   | a  |   |   |
 | 
			
		||||
            |   |   | b  |   |   |
 | 
			
		||||
            | h | g |    | c | d |
 | 
			
		||||
            |   |   | e  |   |   |
 | 
			
		||||
            |   |   | f  |   |   |
 | 
			
		||||
 | 
			
		||||
       And the ways
 | 
			
		||||
            | nodes  | roundabout |
 | 
			
		||||
            | ab     | false      |
 | 
			
		||||
            | cd     | false      |
 | 
			
		||||
            | ef     | false      |
 | 
			
		||||
            | gh     | false      |
 | 
			
		||||
            | bcegb  | true       |
 | 
			
		||||
 | 
			
		||||
       When I route I should get
 | 
			
		||||
           | waypoints | route       | turns                             |
 | 
			
		||||
           | b,a       | ab,ab       | depart, arrive                    |
 | 
			
		||||
           | b,d       | bcegb,cd,cd | depart, roundabout-exit-1, arrive |
 | 
			
		||||
           | b,f       | bcegb,ef,ef | depart, roundabout-exit-2, arrive |
 | 
			
		||||
           | b,h       | bcegb,gh,gh | depart, roundabout-exit-3, arrive |
 | 
			
		||||
           | c,d       | cd,cd       | depart, arrive                    |
 | 
			
		||||
           | c,f       | bcegb,ef,ef | depart, roundabout-exit-1, arrive |
 | 
			
		||||
           | c,h       | bcegb,gh,gh | depart, roundabout-exit-2, arrive |
 | 
			
		||||
           | c,a       | bcegb,ab,ab | depart, roundabout-exit-3, arrive |
 | 
			
		||||
           | e,f       | ef,ef       | depart, arrive                    |
 | 
			
		||||
           | e,h       | bcegb,gh,gh | depart, roundabout-exit-1, arrive |
 | 
			
		||||
           | e,a       | bcegb,ab,ab | depart, roundabout-exit-2, arrive |
 | 
			
		||||
           | e,d       | bcegb,cd,cd | depart, roundabout-exit-3, arrive |
 | 
			
		||||
           | g,h       | gh,gh       | depart, arrive                    |
 | 
			
		||||
           | g,a       | bcegb,ab,ab | depart, roundabout-exit-1, arrive |
 | 
			
		||||
           | g,d       | bcegb,cd,cd | depart, roundabout-exit-2, arrive |
 | 
			
		||||
           | g,f       | bcegb,ef,ef | depart, roundabout-exit-3, arrive |
 | 
			
		||||
 | 
			
		||||
    Scenario: Drive Around
 | 
			
		||||
        Given the node map
 | 
			
		||||
            |   |   | a  |   |   |
 | 
			
		||||
            |   |   | b  |   |   |
 | 
			
		||||
            | h | g |    | c | d |
 | 
			
		||||
            |   |   | e  |   |   |
 | 
			
		||||
            |   |   | f  |   |   |
 | 
			
		||||
 | 
			
		||||
       And the ways
 | 
			
		||||
            | nodes  | roundabout |
 | 
			
		||||
            | ab     | false      |
 | 
			
		||||
            | cd     | false      |
 | 
			
		||||
            | ef     | false      |
 | 
			
		||||
            | gh     | false      |
 | 
			
		||||
            | bcegb  | true       |
 | 
			
		||||
 | 
			
		||||
       When I route I should get
 | 
			
		||||
           | waypoints | route       | turns          |
 | 
			
		||||
           | b,c       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | b,e       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | b,g       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | c,e       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | c,g       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | c,b       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | e,g       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | e,b       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | e,c       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | g,b       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | g,c       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
           | g,e       | bcegb,bcegb | depart, arrive |
 | 
			
		||||
 | 
			
		||||
     Scenario: Mixed Entry and Exit
 | 
			
		||||
@ -17,6 +17,7 @@
 | 
			
		||||
#include "util/node_based_graph.hpp"
 | 
			
		||||
#include "util/typedefs.hpp"
 | 
			
		||||
#include "util/deallocating_vector.hpp"
 | 
			
		||||
#include "util/name_table.hpp"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
@ -51,7 +52,8 @@ class EdgeBasedGraphFactory
 | 
			
		||||
                                   const std::unordered_set<NodeID> &traffic_lights,
 | 
			
		||||
                                   std::shared_ptr<const RestrictionMap> restriction_map,
 | 
			
		||||
                                   const std::vector<QueryNode> &node_info_list,
 | 
			
		||||
                                   SpeedProfileProperties speed_profile);
 | 
			
		||||
                                   SpeedProfileProperties speed_profile,
 | 
			
		||||
                                   const util::NameTable &name_table);
 | 
			
		||||
 | 
			
		||||
    void Run(const std::string &original_edge_data_filename,
 | 
			
		||||
             lua_State *lua_state,
 | 
			
		||||
@ -106,6 +108,8 @@ class EdgeBasedGraphFactory
 | 
			
		||||
 | 
			
		||||
    SpeedProfileProperties speed_profile;
 | 
			
		||||
 | 
			
		||||
    const util::NameTable &name_table;
 | 
			
		||||
 | 
			
		||||
    void CompressGeometry();
 | 
			
		||||
    unsigned RenumberEdges();
 | 
			
		||||
    void GenerateEdgeExpandedNodes();
 | 
			
		||||
 | 
			
		||||
@ -12,9 +12,12 @@
 | 
			
		||||
#include "extractor/guidance/classification_data.hpp"
 | 
			
		||||
#include "extractor/guidance/turn_instruction.hpp"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
namespace osrm
 | 
			
		||||
{
 | 
			
		||||
@ -331,6 +334,73 @@ inline bool isDistinct(const DirectionModifier first, const DirectionModifier se
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool requiresNameAnnounced(const std::string &from, const std::string &to)
 | 
			
		||||
{
 | 
			
		||||
    // FIXME, handle in profile to begin with?
 | 
			
		||||
    // this uses the encoding of references in the profile, which is very BAD
 | 
			
		||||
    // Input for this function should be a struct separating streetname, suffix (e.g. road,
 | 
			
		||||
    // boulevard, North, West ...), and a list of references
 | 
			
		||||
    std::string from_name = "", from_ref = "", to_name = "", to_ref = "";
 | 
			
		||||
 | 
			
		||||
    auto split = [](const std::string &name, std::string &out_name, std::string &out_ref)
 | 
			
		||||
    {
 | 
			
		||||
        const auto ref_begin = name.find_first_of('(');
 | 
			
		||||
        if (ref_begin != std::string::npos)
 | 
			
		||||
        {
 | 
			
		||||
            out_name = name.substr(0, ref_begin);
 | 
			
		||||
            out_ref = name.substr(ref_begin + 1, name.find_first_of(')') - 1);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            out_name = name;
 | 
			
		||||
            out_ref = "";
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    split(from, from_name, from_ref);
 | 
			
		||||
    split(to, to_name, to_ref);
 | 
			
		||||
 | 
			
		||||
    // check similarity of names
 | 
			
		||||
    if (from_name != "" && to_name != "")
 | 
			
		||||
    {
 | 
			
		||||
        if ((from_name.back() >= '0' && from_name.back() <= '9') ||
 | 
			
		||||
            (to_name.back() >= '0' && to_name.back() <= '9'))
 | 
			
		||||
            return from_name != to_name;
 | 
			
		||||
        if (from.find("Weg ") == 0 && to_name.find("Weg ") == 0)
 | 
			
		||||
            return from_name != to_name;
 | 
			
		||||
        auto from_itr = from_name.begin();
 | 
			
		||||
        auto to_itr = to_name.begin();
 | 
			
		||||
        for (; from_itr != from_name.end() && to_itr != to_name.end() && *from_itr == *to_itr;
 | 
			
		||||
             ++to_itr, ++from_itr)
 | 
			
		||||
        {
 | 
			
		||||
            /* do nothing */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const auto common_length = std::distance(from_name.begin(), from_itr);
 | 
			
		||||
        return (100 * common_length / std::min(to_name.length(), from_name.length())) < 80;
 | 
			
		||||
    }
 | 
			
		||||
    else if (from_ref != "" && to_ref != "")
 | 
			
		||||
    {
 | 
			
		||||
        // references are contained in one another
 | 
			
		||||
        if (from_ref.find(to_ref) != std::string::npos ||
 | 
			
		||||
            to_ref.find(from_ref) != std::string::npos)
 | 
			
		||||
            return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int getPriority( const FunctionalRoadClass road_class )
 | 
			
		||||
{
 | 
			
		||||
    const constexpr int road_priority[] = {10, 0, 10, 2, 10, 4, 10, 6, 10, 8, 10, 11, 10, 12, 10, 14};
 | 
			
		||||
    return road_priority[static_cast<int>(road_class)];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool canBeSeenAsFork(const FunctionalRoadClass first, const FunctionalRoadClass second)
 | 
			
		||||
{
 | 
			
		||||
    // forks require similar road categories
 | 
			
		||||
    return std::abs(getPriority(first) - getPriority(second)) <= 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace guidance
 | 
			
		||||
} // namespace extractor
 | 
			
		||||
} // namespace osrm
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,8 @@
 | 
			
		||||
#include "extractor/restriction_map.hpp"
 | 
			
		||||
#include "extractor/compressed_edge_container.hpp"
 | 
			
		||||
 | 
			
		||||
#include "util/name_table.hpp"
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
@ -53,7 +55,8 @@ class TurnAnalysis
 | 
			
		||||
                 const std::vector<QueryNode> &node_info_list,
 | 
			
		||||
                 const RestrictionMap &restriction_map,
 | 
			
		||||
                 const std::unordered_set<NodeID> &barrier_nodes,
 | 
			
		||||
                 const CompressedEdgeContainer &compressed_edge_container);
 | 
			
		||||
                 const CompressedEdgeContainer &compressed_edge_container,
 | 
			
		||||
                 const util::NameTable &name_table);
 | 
			
		||||
 | 
			
		||||
    // the entry into the turn analysis
 | 
			
		||||
    std::vector<TurnCandidate> getTurns(const NodeID from_node, const EdgeID via_eid) const;
 | 
			
		||||
@ -64,6 +67,7 @@ class TurnAnalysis
 | 
			
		||||
    const RestrictionMap &restriction_map;
 | 
			
		||||
    const std::unordered_set<NodeID> &barrier_nodes;
 | 
			
		||||
    const CompressedEdgeContainer &compressed_edge_container;
 | 
			
		||||
    const util::NameTable &name_table;
 | 
			
		||||
 | 
			
		||||
    // Check for restrictions/barriers and generate a list of valid and invalid turns present at the
 | 
			
		||||
    // node reached
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										26
									
								
								include/util/name_table.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								include/util/name_table.hpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
#ifndef OSRM_UTIL_NAME_TABLE_HPP
 | 
			
		||||
#define OSRM_UTIL_NAME_TABLE_HPP
 | 
			
		||||
 | 
			
		||||
#include "util/shared_memory_vector_wrapper.hpp"
 | 
			
		||||
#include "util/range_table.hpp"
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace osrm
 | 
			
		||||
{
 | 
			
		||||
namespace util
 | 
			
		||||
{
 | 
			
		||||
class NameTable
 | 
			
		||||
{
 | 
			
		||||
  private:
 | 
			
		||||
    //FIXME should this use shared memory
 | 
			
		||||
    RangeTable<16, false> m_name_table;
 | 
			
		||||
    ShM<char, false>::vector m_names_char_list;
 | 
			
		||||
  public:
 | 
			
		||||
    NameTable( const std::string &filename );
 | 
			
		||||
    std::string get_name_for_id(const unsigned name_id) const;
 | 
			
		||||
};
 | 
			
		||||
} // namespace util
 | 
			
		||||
} // namespace osrm
 | 
			
		||||
 | 
			
		||||
#endif // OSRM_UTIL_NAME_TABLE_HPP
 | 
			
		||||
@ -28,17 +28,23 @@ namespace json
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
const constexpr char *modifier_names[] = {"uturn",    "sharp right", "right", "slight right",
 | 
			
		||||
                                          "straight", "slight left", "left",  "sharp left"};
 | 
			
		||||
const constexpr char *modifier_names[] = {"uturn",
 | 
			
		||||
                                          "sharp right",
 | 
			
		||||
                                          "right",
 | 
			
		||||
                                          "slight right",
 | 
			
		||||
                                          "straight",
 | 
			
		||||
                                          "slight left",
 | 
			
		||||
                                          "left",
 | 
			
		||||
                                          "sharp left"};
 | 
			
		||||
 | 
			
		||||
// translations of TurnTypes. Not all types are exposed to the outside world.
 | 
			
		||||
// invalid types should never be returned as part of the API
 | 
			
		||||
const constexpr char *turn_type_names[] = {
 | 
			
		||||
    "invalid",    "no turn",     "invalid",        "new name",    "continue",       "turn",
 | 
			
		||||
    "turn",       "turn",        "turn",           "merge",       "ramp",           "ramp",
 | 
			
		||||
    "ramp",       "ramp",        "fork",           "end of road", "roundabout",     "invalid",
 | 
			
		||||
    "roundabout", "invalid",     "traffic circle", "invalid",     "traffic circle", "invalid",
 | 
			
		||||
    "invalid",    "restriction", "notification"};
 | 
			
		||||
    "invalid",        "no turn", "invalid",    "new name",    "continue",       "turn",
 | 
			
		||||
    "turn",           "turn",    "turn",       "turn",        "merge",          "ramp",
 | 
			
		||||
    "ramp",           "ramp",    "ramp",       "ramp",        "fork",           "end of road",
 | 
			
		||||
    "roundabout",     "invalid", "roundabout", "invalid",     "traffic circle", "invalid",
 | 
			
		||||
    "traffic circle", "invalid", "invalid",    "restriction", "notification"};
 | 
			
		||||
const constexpr char *waypoint_type_names[] = {"invalid", "arrive", "depart"};
 | 
			
		||||
 | 
			
		||||
// Check whether to include a modifier in the result of the API
 | 
			
		||||
@ -50,23 +56,6 @@ inline bool isValidModifier(const guidance::StepManeuver maneuver)
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool isMultiTurn(const TurnType type)
 | 
			
		||||
{
 | 
			
		||||
    return (type == TurnType::FirstTurn || type == TurnType::SecondTurn ||
 | 
			
		||||
            type == TurnType::ThirdTurn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline std::string getCount(const TurnType type)
 | 
			
		||||
{
 | 
			
		||||
    if (type == TurnType::FirstTurn)
 | 
			
		||||
        return "1";
 | 
			
		||||
    if (type == TurnType::SecondTurn)
 | 
			
		||||
        return "2";
 | 
			
		||||
    if (type == TurnType::ThirdTurn)
 | 
			
		||||
        return "3";
 | 
			
		||||
    return "0";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string instructionTypeToString(const TurnType type)
 | 
			
		||||
{
 | 
			
		||||
    return turn_type_names[static_cast<std::size_t>(type)];
 | 
			
		||||
@ -152,8 +141,6 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
 | 
			
		||||
    else
 | 
			
		||||
        step_maneuver.values["type"] = detail::waypointTypeToString(maneuver.waypoint_type);
 | 
			
		||||
 | 
			
		||||
    if (detail::isMultiTurn(maneuver.instruction.type))
 | 
			
		||||
        step_maneuver.values["count"] = detail::getCount(maneuver.instruction.type);
 | 
			
		||||
    if (detail::isValidModifier(maneuver))
 | 
			
		||||
        step_maneuver.values["modifier"] =
 | 
			
		||||
            detail::instructionModifierToString(maneuver.instruction.direction_modifier);
 | 
			
		||||
 | 
			
		||||
@ -34,12 +34,13 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
 | 
			
		||||
    const std::unordered_set<NodeID> &traffic_lights,
 | 
			
		||||
    std::shared_ptr<const RestrictionMap> restriction_map,
 | 
			
		||||
    const std::vector<QueryNode> &node_info_list,
 | 
			
		||||
    SpeedProfileProperties speed_profile)
 | 
			
		||||
    SpeedProfileProperties speed_profile,
 | 
			
		||||
    const util::NameTable &name_table)
 | 
			
		||||
    : m_max_edge_id(0), m_node_info_list(node_info_list),
 | 
			
		||||
      m_node_based_graph(std::move(node_based_graph)),
 | 
			
		||||
      m_restriction_map(std::move(restriction_map)), m_barrier_nodes(barrier_nodes),
 | 
			
		||||
      m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container),
 | 
			
		||||
      speed_profile(std::move(speed_profile))
 | 
			
		||||
      speed_profile(std::move(speed_profile)), name_table(name_table)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -123,10 +124,9 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeI
 | 
			
		||||
    // traverse arrays from start and end respectively
 | 
			
		||||
    for (const auto i : util::irange(0UL, geometry_size))
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(
 | 
			
		||||
            current_edge_source_coordinate_id ==
 | 
			
		||||
            m_compressed_edge_container.GetBucketReference(edge_id_2)[geometry_size - 1 - i]
 | 
			
		||||
                .node_id);
 | 
			
		||||
        BOOST_ASSERT(current_edge_source_coordinate_id ==
 | 
			
		||||
                     m_compressed_edge_container.GetBucketReference(
 | 
			
		||||
                                                     edge_id_2)[geometry_size - 1 - i].node_id);
 | 
			
		||||
        const NodeID current_edge_target_coordinate_id = forward_geometry[i].node_id;
 | 
			
		||||
        BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
 | 
			
		||||
 | 
			
		||||
@ -302,8 +302,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
 | 
			
		||||
    // Three nested loop look super-linear, but we are dealing with a (kind of)
 | 
			
		||||
    // linear number of turns only.
 | 
			
		||||
    util::Percent progress(m_node_based_graph->GetNumberOfNodes());
 | 
			
		||||
    guidance::TurnAnalysis turn_analysis( *m_node_based_graph, m_node_info_list,
 | 
			
		||||
                                       *m_restriction_map, m_barrier_nodes, m_compressed_edge_container );
 | 
			
		||||
    guidance::TurnAnalysis turn_analysis(*m_node_based_graph, m_node_info_list, *m_restriction_map,
 | 
			
		||||
                                         m_barrier_nodes, m_compressed_edge_container, name_table);
 | 
			
		||||
    for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes()))
 | 
			
		||||
    {
 | 
			
		||||
        // progress.printStatus(node_u);
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@
 | 
			
		||||
#include "util/timing_util.hpp"
 | 
			
		||||
#include "util/lua_util.hpp"
 | 
			
		||||
#include "util/graph_loader.hpp"
 | 
			
		||||
#include "util/name_table.hpp"
 | 
			
		||||
 | 
			
		||||
#include "util/typedefs.hpp"
 | 
			
		||||
 | 
			
		||||
@ -521,10 +522,12 @@ Extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_n
 | 
			
		||||
 | 
			
		||||
    compressed_edge_container.SerializeInternalVector(config.geometry_output_path);
 | 
			
		||||
 | 
			
		||||
    util::NameTable name_table(config.names_file_name);
 | 
			
		||||
 | 
			
		||||
    EdgeBasedGraphFactory edge_based_graph_factory(
 | 
			
		||||
        node_based_graph, compressed_edge_container, barrier_nodes, traffic_lights,
 | 
			
		||||
        std::const_pointer_cast<RestrictionMap const>(restriction_map),
 | 
			
		||||
        internal_to_external_node_map, speed_profile);
 | 
			
		||||
        internal_to_external_node_map, speed_profile, name_table);
 | 
			
		||||
 | 
			
		||||
    edge_based_graph_factory.Run(config.edge_output_path, lua_state,
 | 
			
		||||
                                 config.edge_segment_lookup_path, config.edge_penalty_path,
 | 
			
		||||
 | 
			
		||||
@ -55,10 +55,11 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
 | 
			
		||||
                           const std::vector<QueryNode> &node_info_list,
 | 
			
		||||
                           const RestrictionMap &restriction_map,
 | 
			
		||||
                           const std::unordered_set<NodeID> &barrier_nodes,
 | 
			
		||||
                           const CompressedEdgeContainer &compressed_edge_container)
 | 
			
		||||
                           const CompressedEdgeContainer &compressed_edge_container,
 | 
			
		||||
                           const util::NameTable &name_table)
 | 
			
		||||
    : node_based_graph(node_based_graph), node_info_list(node_info_list),
 | 
			
		||||
      restriction_map(restriction_map), barrier_nodes(barrier_nodes),
 | 
			
		||||
      compressed_edge_container(compressed_edge_container)
 | 
			
		||||
      compressed_edge_container(compressed_edge_container), name_table(name_table)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -784,7 +785,9 @@ TurnInstruction TurnAnalysis::getInstructionForObvious(const std::size_t num_can
 | 
			
		||||
    {
 | 
			
		||||
        const auto &in_data = node_based_graph.GetEdgeData(via_edge);
 | 
			
		||||
        const auto &out_data = node_based_graph.GetEdgeData(candidate.eid);
 | 
			
		||||
        if (in_data.name_id != out_data.name_id)
 | 
			
		||||
        if (in_data.name_id != out_data.name_id &&
 | 
			
		||||
            requiresNameAnnounced(name_table.get_name_for_id(in_data.name_id),
 | 
			
		||||
                                  name_table.get_name_for_id(out_data.name_id)))
 | 
			
		||||
            return {TurnType::NewName, getTurnDirection(candidate.angle)};
 | 
			
		||||
        else
 | 
			
		||||
            return {TurnType::Suppressed, getTurnDirection(candidate.angle)};
 | 
			
		||||
@ -859,6 +862,7 @@ std::vector<TurnCandidate> TurnAnalysis::handleThreeWayTurn(
 | 
			
		||||
                    angularDeviation(turn.angle, STRAIGHT_ANGLE) >
 | 
			
		||||
                1.4);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /* Two nearly straight turns -> FORK
 | 
			
		||||
                OOOOOOO
 | 
			
		||||
              /
 | 
			
		||||
@ -871,7 +875,26 @@ std::vector<TurnCandidate> TurnAnalysis::handleThreeWayTurn(
 | 
			
		||||
    {
 | 
			
		||||
        if (turn_candidates[1].valid && turn_candidates[2].valid)
 | 
			
		||||
        {
 | 
			
		||||
            assignFork(via_edge, turn_candidates[2], turn_candidates[1]);
 | 
			
		||||
            const auto left_class =
 | 
			
		||||
                node_based_graph.GetEdgeData(turn_candidates[2].eid).road_classification.road_class;
 | 
			
		||||
            const auto right_class =
 | 
			
		||||
                node_based_graph.GetEdgeData(turn_candidates[1].eid).road_classification.road_class;
 | 
			
		||||
            if (canBeSeenAsFork(left_class, right_class))
 | 
			
		||||
                assignFork(via_edge, turn_candidates[2], turn_candidates[1]);
 | 
			
		||||
            else if (getPriority(left_class) > getPriority(right_class))
 | 
			
		||||
            {
 | 
			
		||||
                turn_candidates[1].instruction =
 | 
			
		||||
                    getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[1]);
 | 
			
		||||
                turn_candidates[2].instruction = {findBasicTurnType(via_edge, turn_candidates[2]),
 | 
			
		||||
                                                  DirectionModifier::SlightLeft};
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                turn_candidates[2].instruction =
 | 
			
		||||
                    getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[2]);
 | 
			
		||||
                turn_candidates[1].instruction = {findBasicTurnType(via_edge, turn_candidates[1]),
 | 
			
		||||
                                                  DirectionModifier::SlightRight};
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
@ -1073,7 +1096,27 @@ void TurnAnalysis::handleDistinctConflict(const EdgeID via_edge,
 | 
			
		||||
    if (getTurnDirection(left.angle) == DirectionModifier::Straight ||
 | 
			
		||||
        getTurnDirection(left.angle) == DirectionModifier::SlightLeft ||
 | 
			
		||||
        getTurnDirection(right.angle) == DirectionModifier::SlightRight)
 | 
			
		||||
        assignFork(via_edge, left, right);
 | 
			
		||||
    {
 | 
			
		||||
        const auto left_class =
 | 
			
		||||
            node_based_graph.GetEdgeData(left.eid).road_classification.road_class;
 | 
			
		||||
        const auto right_class =
 | 
			
		||||
            node_based_graph.GetEdgeData(right.eid).road_classification.road_class;
 | 
			
		||||
        if (canBeSeenAsFork(left_class, right_class))
 | 
			
		||||
            assignFork(via_edge, left, right);
 | 
			
		||||
        else if (getPriority(left_class) > getPriority(right_class))
 | 
			
		||||
        {
 | 
			
		||||
            // FIXME this should possibly know about the actual candidates?
 | 
			
		||||
            right.instruction = getInstructionForObvious(4, via_edge, right);
 | 
			
		||||
            left.instruction = {findBasicTurnType(via_edge, left), DirectionModifier::SlightLeft};
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // FIXME this should possibly know about the actual candidates?
 | 
			
		||||
            left.instruction = getInstructionForObvious(4, via_edge, left);
 | 
			
		||||
            right.instruction = {findBasicTurnType(via_edge, right),
 | 
			
		||||
                                 DirectionModifier::SlightRight};
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto left_type = findBasicTurnType(via_edge, left);
 | 
			
		||||
    const auto right_type = findBasicTurnType(via_edge, right);
 | 
			
		||||
@ -1196,8 +1239,27 @@ std::vector<TurnCandidate> TurnAnalysis::handleComplexTurn(
 | 
			
		||||
    {
 | 
			
		||||
        if (fork_range.second - fork_range.first == 1)
 | 
			
		||||
        {
 | 
			
		||||
            assignFork(via_edge, turn_candidates[fork_range.second],
 | 
			
		||||
                       turn_candidates[fork_range.first]);
 | 
			
		||||
            auto &left = turn_candidates[fork_range.second];
 | 
			
		||||
            auto &right = turn_candidates[fork_range.first];
 | 
			
		||||
            const auto left_class =
 | 
			
		||||
                node_based_graph.GetEdgeData(left.eid).road_classification.road_class;
 | 
			
		||||
            const auto right_class =
 | 
			
		||||
                node_based_graph.GetEdgeData(right.eid).road_classification.road_class;
 | 
			
		||||
            if (canBeSeenAsFork(left_class, right_class))
 | 
			
		||||
                assignFork(via_edge, left, right);
 | 
			
		||||
            else if (getPriority(left_class) > getPriority(right_class))
 | 
			
		||||
            {
 | 
			
		||||
                right.instruction =
 | 
			
		||||
                    getInstructionForObvious(turn_candidates.size(), via_edge, right);
 | 
			
		||||
                left.instruction = {findBasicTurnType(via_edge, left),
 | 
			
		||||
                                    DirectionModifier::SlightLeft};
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                left.instruction = getInstructionForObvious(turn_candidates.size(), via_edge, left);
 | 
			
		||||
                right.instruction = {findBasicTurnType(via_edge, right),
 | 
			
		||||
                                     DirectionModifier::SlightRight};
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (fork_range.second - fork_range.second == 2)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										52
									
								
								src/util/name_table.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/util/name_table.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
#include "util/name_table.hpp"
 | 
			
		||||
#include "util/simple_logger.hpp"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
 | 
			
		||||
#include <boost/filesystem/fstream.hpp>
 | 
			
		||||
 | 
			
		||||
namespace osrm
 | 
			
		||||
{
 | 
			
		||||
namespace util
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
NameTable::NameTable(const std::string &filename)
 | 
			
		||||
{
 | 
			
		||||
    boost::filesystem::ifstream name_stream(filename, std::ios::binary);
 | 
			
		||||
 | 
			
		||||
    name_stream >> m_name_table;
 | 
			
		||||
 | 
			
		||||
    unsigned number_of_chars = 0;
 | 
			
		||||
    name_stream.read(reinterpret_cast<char *>(&number_of_chars), sizeof(number_of_chars));
 | 
			
		||||
    BOOST_ASSERT_MSG(0 != number_of_chars, "name file broken");
 | 
			
		||||
    m_names_char_list.resize(number_of_chars + 1); //+1 gives sentinel element
 | 
			
		||||
    name_stream.read(reinterpret_cast<char *>(&m_names_char_list[0]),
 | 
			
		||||
                     number_of_chars * sizeof(m_names_char_list[0]));
 | 
			
		||||
    if (0 == m_names_char_list.size())
 | 
			
		||||
    {
 | 
			
		||||
        util::SimpleLogger().Write(logWARNING) << "list of street names is empty";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string NameTable::get_name_for_id(const unsigned name_id) const
 | 
			
		||||
{
 | 
			
		||||
    if (std::numeric_limits<unsigned>::max() == name_id)
 | 
			
		||||
    {
 | 
			
		||||
        return "";
 | 
			
		||||
    }
 | 
			
		||||
    auto range = m_name_table.GetRange(name_id);
 | 
			
		||||
 | 
			
		||||
    std::string result;
 | 
			
		||||
    result.reserve(range.size());
 | 
			
		||||
    if (range.begin() != range.end())
 | 
			
		||||
    {
 | 
			
		||||
        result.resize(range.back() - range.front() + 1);
 | 
			
		||||
        std::copy(m_names_char_list.begin() + range.front(),
 | 
			
		||||
                  m_names_char_list.begin() + range.back() + 1, result.begin());
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
} // namespace util
 | 
			
		||||
} // namespace osrm
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user