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