1 #include "extractor/restriction_filter.hpp"
2 #include "util/node_based_graph.hpp"
3 #include "util/timing_util.hpp"
4 #include "util/typedefs.hpp"
5 
6 #include <algorithm>
7 #include <boost/assert.hpp>
8 
9 namespace osrm
10 {
11 namespace extractor
12 {
13 
14 std::vector<TurnRestriction>
removeInvalidRestrictions(std::vector<TurnRestriction> restrictions,const util::NodeBasedDynamicGraph & node_based_graph)15 removeInvalidRestrictions(std::vector<TurnRestriction> restrictions,
16                           const util::NodeBasedDynamicGraph &node_based_graph)
17 {
18     util::UnbufferedLog log;
19     log << "Removing invalid restrictions...";
20     TIMER_START(remove_invalid_restrictions);
21 
22     const auto is_valid_edge = [&node_based_graph](const auto from, const auto to) {
23         const auto eid = node_based_graph.FindEdge(from, to);
24         if (eid == SPECIAL_EDGEID)
25         {
26             util::Log(logDEBUG) << "Restriction has invalid edge: " << from << ", " << to;
27             return false;
28         }
29 
30         const auto &edge_data = node_based_graph.GetEdgeData(eid);
31         if (edge_data.reversed)
32         {
33             util::Log(logDEBUG) << "Restriction has non-traversable edge: " << from << ", " << to;
34             return false;
35         }
36         return true;
37     };
38 
39     const auto is_valid_node = [is_valid_edge](const auto &node_restriction) {
40         return is_valid_edge(node_restriction.from, node_restriction.via) &&
41                is_valid_edge(node_restriction.via, node_restriction.to);
42     };
43 
44     const auto is_valid_way = [is_valid_edge](const auto &way_restriction) {
45         if (!is_valid_edge(way_restriction.from, way_restriction.via.front()))
46             return false;
47 
48         const auto invalid_it = std::adjacent_find(
49             way_restriction.via.begin(),
50             way_restriction.via.end(),
51             [&](auto via_from, auto via_to) { return !is_valid_edge(via_from, via_to); });
52         if (invalid_it != way_restriction.via.end())
53             return false;
54 
55         return is_valid_edge(way_restriction.via.back(), way_restriction.to);
56     };
57 
58     const auto is_invalid = [is_valid_way, is_valid_node](const auto &restriction) {
59         if (restriction.Type() == RestrictionType::NODE_RESTRICTION)
60         {
61             return !is_valid_node(restriction.AsNodeRestriction());
62         }
63         else
64         {
65             BOOST_ASSERT(restriction.Type() == RestrictionType::WAY_RESTRICTION);
66             return !is_valid_way(restriction.AsWayRestriction());
67         }
68     };
69 
70     const auto end_valid_restrictions =
71         std::remove_if(restrictions.begin(), restrictions.end(), is_invalid);
72     const auto num_removed = std::distance(end_valid_restrictions, restrictions.end());
73     restrictions.erase(end_valid_restrictions, restrictions.end());
74 
75     TIMER_STOP(remove_invalid_restrictions);
76     log << "removed " << num_removed << " invalid restrictions, after "
77         << TIMER_SEC(remove_invalid_restrictions) << "s";
78 
79     return restrictions;
80 }
81 
82 } // namespace extractor
83 } // namespace osrm
84