1 #ifndef OSRM_GUIDANCE_PARSING_TOOLKIT_HPP_
2 #define OSRM_GUIDANCE_PARSING_TOOLKIT_HPP_
3 
4 #include <cstdint>
5 #include <string>
6 
7 #include <boost/algorithm/string.hpp>
8 #include <boost/tokenizer.hpp>
9 
10 #include "util/attributes.hpp"
11 
12 namespace osrm
13 {
14 namespace extractor
15 {
16 namespace guidance
17 {
18 
19 // Public service vehicle lanes and similar can introduce additional lanes into the lane string that
20 // are not specifically marked for left/right turns. This function can be used from the profile to
21 // trim the lane string appropriately
22 //
23 // left|throught|
24 // in combination with lanes:psv:forward=1
25 // will be corrected to left|throught, since the final lane is not drivable.
26 // This is in contrast to a situation with lanes:psv:forward=0 (or not set) where left|through|
27 // represents left|through|through
28 OSRM_ATTR_WARN_UNUSED
29 inline std::string
trimLaneString(std::string lane_string,std::int32_t count_left,std::int32_t count_right)30 trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t count_right)
31 {
32     if (count_left)
33     {
34         bool sane = count_left < static_cast<std::int32_t>(lane_string.size());
35         for (std::int32_t i = 0; i < count_left; ++i)
36             // this is adjusted for our fake pipe. The moment cucumber can handle multiple escaped
37             // pipes, the '&' part can be removed
38             if (lane_string[i] != '|')
39             {
40                 sane = false;
41                 break;
42             }
43 
44         if (sane)
45         {
46             lane_string.erase(lane_string.begin(), lane_string.begin() + count_left);
47         }
48     }
49     if (count_right)
50     {
51         bool sane = count_right < static_cast<std::int32_t>(lane_string.size());
52         for (auto itr = lane_string.rbegin();
53              itr != lane_string.rend() && itr != lane_string.rbegin() + count_right;
54              ++itr)
55         {
56             if (*itr != '|')
57             {
58                 sane = false;
59                 break;
60             }
61         }
62         if (sane)
63             lane_string.resize(lane_string.size() - count_right);
64     }
65     return lane_string;
66 }
67 
68 // https://github.com/Project-OSRM/osrm-backend/issues/2638
69 // It can happen that some lanes are not drivable by car. Here we handle this tagging scheme
70 // (vehicle:lanes) to filter out not-allowed roads
71 // lanes=3
72 // turn:lanes=left|through|through|right
73 // vehicle:lanes=yes|yes|no|yes
74 // bicycle:lanes=yes|no|designated|yes
75 OSRM_ATTR_WARN_UNUSED
applyAccessTokens(std::string lane_string,const std::string & access_tokens)76 inline std::string applyAccessTokens(std::string lane_string, const std::string &access_tokens)
77 {
78     typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
79     boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
80     tokenizer tokens(lane_string, sep);
81     tokenizer access(access_tokens, sep);
82 
83     // strings don't match, don't do anything
84     if (std::distance(std::begin(tokens), std::end(tokens)) !=
85         std::distance(std::begin(access), std::end(access)))
86         return lane_string;
87 
88     std::string result_string = "";
89     const static std::string yes = "yes";
90 
91     for (auto token_itr = std::begin(tokens), access_itr = std::begin(access);
92          token_itr != std::end(tokens);
93          ++token_itr, ++access_itr)
94     {
95         if (*access_itr == yes)
96         {
97             // we have to add this in front, because the next token could be invalid. Doing this on
98             // non-empty strings makes sure that the token string will be valid in the end
99             if (!result_string.empty())
100                 result_string += '|';
101 
102             result_string += *token_itr;
103         }
104     }
105     return result_string;
106 }
107 
108 } // namespace guidance
109 } // namespace extractor
110 } // namespace osrm
111 
112 #endif // OSRM_GUIDANCE_PARSING_TOOLKIT_HPP_
113