Upgrade clang-format to version 15 (#6859)

This commit is contained in:
Dennis Luxen
2024-05-06 09:14:46 +02:00
committed by GitHub
parent b503e96a98
commit 7f9d591ab7
156 changed files with 2357 additions and 1894 deletions
+6 -6
View File
@@ -65,12 +65,12 @@ void benchmark(BenchStaticRTree &rtree, unsigned num_queries)
util::FixedLatitude{lat_udist(mt_rand)});
}
benchmarkQuery(queries, "raw RTree queries (1 result)", [&rtree](const util::Coordinate &q) {
return rtree.Nearest(q, 1);
});
benchmarkQuery(queries, "raw RTree queries (10 results)", [&rtree](const util::Coordinate &q) {
return rtree.Nearest(q, 10);
});
benchmarkQuery(queries,
"raw RTree queries (1 result)",
[&rtree](const util::Coordinate &q) { return rtree.Nearest(q, 1); });
benchmarkQuery(queries,
"raw RTree queries (10 results)",
[&rtree](const util::Coordinate &q) { return rtree.Nearest(q, 10); });
}
} // namespace osrm::benchmarks
+20 -12
View File
@@ -619,7 +619,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
util::UnbufferedLog log;
log << "initializing node priorities...";
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, remaining_nodes.size(), PQGrainSize),
[&](const auto &range) {
[&](const auto &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto x = range.begin(), end = range.end(); x != end; ++x)
{
@@ -656,7 +657,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
tbb::parallel_for(
tbb::blocked_range<NodeID>(0, remaining_nodes.size(), IndependentGrainSize),
[&](const auto &range) {
[&](const auto &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
// determine independent node set
for (auto i = range.begin(), end = range.end(); i != end; ++i)
@@ -669,9 +671,9 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
// sort all remaining nodes to the beginning of the sequence
const auto begin_independent_nodes = std::stable_partition(
remaining_nodes.begin(), remaining_nodes.end(), [](RemainingNodeData node_data) {
return !node_data.is_independent;
});
remaining_nodes.begin(),
remaining_nodes.end(),
[](RemainingNodeData node_data) { return !node_data.is_independent; });
auto begin_independent_nodes_idx =
std::distance(remaining_nodes.begin(), begin_independent_nodes);
auto end_independent_nodes_idx = remaining_nodes.size();
@@ -680,7 +682,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
tbb::parallel_for(
tbb::blocked_range<NodeID>(
begin_independent_nodes_idx, end_independent_nodes_idx, ContractGrainSize),
[&](const auto &range) {
[&](const auto &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto position = range.begin(), end = range.end(); position != end; ++position)
{
@@ -699,7 +702,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
tbb::parallel_for(
tbb::blocked_range<NodeID>(
begin_independent_nodes_idx, end_independent_nodes_idx, DeleteGrainSize),
[&](const auto &range) {
[&](const auto &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto position = range.begin(), end = range.end(); position != end; ++position)
{
@@ -709,10 +713,13 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
});
// make sure we really sort each block
tbb::parallel_for(thread_data_list.data.range(), [&](const auto &range) {
for (auto &data : range)
tbb::parallel_sort(data->inserted_edges.begin(), data->inserted_edges.end());
});
tbb::parallel_for(thread_data_list.data.range(),
[&](const auto &range)
{
for (auto &data : range)
tbb::parallel_sort(data->inserted_edges.begin(),
data->inserted_edges.end());
});
// insert new edges
for (auto &data : thread_data_list.data)
@@ -743,7 +750,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
tbb::parallel_for(
tbb::blocked_range<NodeID>(
begin_independent_nodes_idx, end_independent_nodes_idx, NeighboursGrainSize),
[&](const auto &range) {
[&](const auto &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto position = range.begin(), end = range.end(); position != end; ++position)
{
+7 -6
View File
@@ -47,17 +47,18 @@ void printUnreachableStatistics(const Partition &partition,
for (auto node : cell.GetSourceNodes())
{
const auto &weights = cell.GetOutWeight(node);
invalid_sources += std::all_of(weights.begin(), weights.end(), [](auto weight) {
return weight == INVALID_EDGE_WEIGHT;
});
invalid_sources +=
std::all_of(weights.begin(),
weights.end(),
[](auto weight) { return weight == INVALID_EDGE_WEIGHT; });
}
for (auto node : cell.GetDestinationNodes())
{
const auto &weights = cell.GetInWeight(node);
invalid_destinations +=
std::all_of(weights.begin(), weights.end(), [](auto weight) {
return weight == INVALID_EDGE_WEIGHT;
});
std::all_of(weights.begin(),
weights.end(),
[](auto weight) { return weight == INVALID_EDGE_WEIGHT; });
}
}
+7 -6
View File
@@ -129,7 +129,8 @@ util::json::Object makeIntersection(const guidance::IntermediateIntersection &in
std::transform(intersection.entry.begin(),
intersection.entry.end(),
std::back_inserter(entry.values),
[](const bool has_entry) -> util::json::Value {
[](const bool has_entry) -> util::json::Value
{
if (has_entry)
return util::json::True();
else
@@ -151,11 +152,11 @@ util::json::Object makeIntersection(const guidance::IntermediateIntersection &in
{
util::json::Array classes;
classes.values.reserve(intersection.classes.size());
std::transform(
intersection.classes.begin(),
intersection.classes.end(),
std::back_inserter(classes.values),
[](const std::string &class_name) { return util::json::String{class_name}; });
std::transform(intersection.classes.begin(),
intersection.classes.end(),
std::back_inserter(classes.values),
[](const std::string &class_name)
{ return util::json::String{class_name}; });
result.values["classes"] = std::move(classes);
}
+5 -3
View File
@@ -43,9 +43,11 @@ std::vector<util::Coordinate> douglasPeucker(std::vector<util::Coordinate>::cons
}
std::vector<util::FloatCoordinate> projected_coordinates(size);
std::transform(begin, end, projected_coordinates.begin(), [](const util::Coordinate coord) {
return util::web_mercator::fromWGS84(coord);
});
std::transform(begin,
end,
projected_coordinates.begin(),
[](const util::Coordinate coord)
{ return util::web_mercator::fromWGS84(coord); });
std::vector<bool> is_necessary(size, false);
BOOST_ASSERT(is_necessary.size() >= 2);
+2 -3
View File
@@ -9,9 +9,8 @@ bool EngineConfig::IsValid() const
// leads to an empty path
const bool all_path_are_empty = storage_config.GetPath("").empty();
const auto unlimited_or_more_than = [](const auto v, const auto limit) {
return v == -1 || v > limit;
};
const auto unlimited_or_more_than = [](const auto v, const auto limit)
{ return v == -1 || v > limit; };
const bool limits_valid =
unlimited_or_more_than(max_locations_distance_table, 2) &&
+9 -10
View File
@@ -40,22 +40,21 @@ unsigned calculateOverviewZoomLevel(const std::vector<LegGeometry> &leg_geometri
std::vector<util::Coordinate> assembleOverview(const std::vector<LegGeometry> &leg_geometries,
const bool use_simplification)
{
auto overview_size =
std::accumulate(leg_geometries.begin(),
leg_geometries.end(),
0,
[](const std::size_t sum, const LegGeometry &leg_geometry) {
return sum + leg_geometry.locations.size();
}) -
leg_geometries.size() + 1;
auto overview_size = std::accumulate(leg_geometries.begin(),
leg_geometries.end(),
0,
[](const std::size_t sum, const LegGeometry &leg_geometry)
{ return sum + leg_geometry.locations.size(); }) -
leg_geometries.size() + 1;
std::vector<util::Coordinate> overview_geometry;
overview_geometry.reserve(overview_size);
using GeometryIter = decltype(overview_geometry)::const_iterator;
auto leg_reverse_index = leg_geometries.size();
const auto insert_without_overlap = [&leg_reverse_index, &overview_geometry](GeometryIter begin,
GeometryIter end) {
const auto insert_without_overlap =
[&leg_reverse_index, &overview_geometry](GeometryIter begin, GeometryIter end)
{
// not the last leg
if (leg_reverse_index > 1)
{
+15 -12
View File
@@ -7,18 +7,21 @@ namespace osrm::engine::guidance
Route assembleRoute(const std::vector<RouteLeg> &route_legs)
{
auto distance = std::accumulate(
route_legs.begin(), route_legs.end(), 0., [](const double sum, const RouteLeg &leg) {
return sum + leg.distance;
});
auto duration = std::accumulate(
route_legs.begin(), route_legs.end(), 0., [](const double sum, const RouteLeg &leg) {
return sum + leg.duration;
});
auto weight = std::accumulate(
route_legs.begin(), route_legs.end(), 0., [](const double sum, const RouteLeg &leg) {
return sum + leg.weight;
});
auto distance =
std::accumulate(route_legs.begin(),
route_legs.end(),
0.,
[](const double sum, const RouteLeg &leg) { return sum + leg.distance; });
auto duration =
std::accumulate(route_legs.begin(),
route_legs.end(),
0.,
[](const double sum, const RouteLeg &leg) { return sum + leg.duration; });
auto weight =
std::accumulate(route_legs.begin(),
route_legs.end(),
0.,
[](const double sum, const RouteLeg &leg) { return sum + leg.weight; });
return Route{distance, duration, weight};
}
@@ -102,7 +102,8 @@ bool isStaggeredIntersection(const RouteStepIterator step_prior_to_intersection,
// If adjusted, make sure to check validity of the is_right/is_left classification below
const constexpr auto MAX_STAGGERED_DISTANCE = 3; // debatable, but keep short to be on safe side
const auto angle = [](const RouteStep &step) {
const auto angle = [](const RouteStep &step)
{
const auto &intersection = step.intersections.front();
const auto entry_bearing = util::bearing::reverse(intersection.bearings[intersection.in]);
const auto exit_bearing = intersection.bearings[intersection.out];
+12 -6
View File
@@ -59,7 +59,8 @@ double findTotalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_ste
// c
// |
// d
const auto use_total_angle = [&]() {
const auto use_total_angle = [&]()
{
// only consider actual turns in combination:
if (angularDeviation(total_angle, 180) < 0.5 * NARROW_TURN_ANGLE)
return false;
@@ -99,7 +100,8 @@ inline void handleSliproad(RouteStepIterator sliproad_step)
{
// find the next step after the sliproad step itself (this is not necessarily the next step,
// since we might have to skip over traffic lights/node penalties)
auto next_step = [&sliproad_step]() {
auto next_step = [&sliproad_step]()
{
auto next_step = findNextTurn(sliproad_step);
while (isTrafficLightStep(*next_step))
{
@@ -196,7 +198,8 @@ void AdjustToCombinedTurnStrategy::operator()(RouteStep &step_at_turn_location,
: getTurnDirection(angle);
// a turn that is a new name or straight (turn/continue)
const auto is_non_turn = [](const RouteStep &step) {
const auto is_non_turn = [](const RouteStep &step)
{
return hasTurnType(step, TurnType::NewName) ||
(hasTurnType(step, TurnType::Turn) &&
hasModifier(step, DirectionModifier::Straight)) ||
@@ -307,7 +310,8 @@ void SegregatedTurnStrategy::operator()(RouteStep &step_at_turn_location,
// Used to control updating of the modifier based on turn direction
bool update_modifier_for_turn_direction = true;
const auto calculate_turn_angle = [](const RouteStep &entry_step, const RouteStep &exit_step) {
const auto calculate_turn_angle = [](const RouteStep &entry_step, const RouteStep &exit_step)
{
return util::bearing::angleBetween(entry_step.maneuver.bearing_before,
exit_step.maneuver.bearing_after);
};
@@ -316,7 +320,8 @@ void SegregatedTurnStrategy::operator()(RouteStep &step_at_turn_location,
const auto turn_angle = calculate_turn_angle(step_at_turn_location, transfer_from_step);
const auto turn_direction = getTurnDirection(turn_angle);
const auto is_straight_step = [](const RouteStep &step) {
const auto is_straight_step = [](const RouteStep &step)
{
return ((hasTurnType(step, TurnType::NewName) || hasTurnType(step, TurnType::Continue) ||
hasTurnType(step, TurnType::Suppressed) || hasTurnType(step, TurnType::Turn)) &&
(hasModifier(step, DirectionModifier::Straight) ||
@@ -324,7 +329,8 @@ void SegregatedTurnStrategy::operator()(RouteStep &step_at_turn_location,
hasModifier(step, DirectionModifier::SlightRight)));
};
const auto is_turn_step = [](const RouteStep &step) {
const auto is_turn_step = [](const RouteStep &step)
{
return (hasTurnType(step, TurnType::Turn) || hasTurnType(step, TurnType::Continue) ||
hasTurnType(step, TurnType::NewName) || hasTurnType(step, TurnType::Suppressed));
};
+123 -112
View File
@@ -17,7 +17,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
const double min_distance_needed_for_lane_change)
{
// Lane anticipation works on contiguous ranges of short steps that have lane information
const auto is_short_has_lanes = [&](const RouteStep &step) {
const auto is_short_has_lanes = [&](const RouteStep &step)
{
const auto has_lanes = step.intersections.front().lanes.lanes_in_turn > 0;
if (!has_lanes)
@@ -45,7 +46,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
std::vector<StepIterRange> quick_lanes_ranges;
const auto range_back_inserter = [&](StepIterRange range) {
const auto range_back_inserter = [&](StepIterRange range)
{
if (std::distance(range.first, range.second) > 1)
quick_lanes_ranges.push_back(std::move(range));
};
@@ -58,7 +60,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
// Walk backwards over all turns, constraining possible turn lanes.
// Later turn lanes constrain earlier ones: we have to anticipate lane changes.
const auto constrain_lanes = [&](const StepIterRange &turns) {
const auto constrain_lanes = [&](const StepIterRange &turns)
{
const std::reverse_iterator<StepIter> rev_first{turns.second};
const std::reverse_iterator<StepIter> rev_last{turns.first};
@@ -74,127 +77,135 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
// segment for a lane switch, but the total distance shouldn't be unlimited.
double distance_to_constrained = 0.0;
util::for_each_pair(rev_first, rev_last, [&](RouteStep &current, RouteStep &previous) {
const auto current_inst = current.maneuver.instruction;
const auto current_lanes = current.intersections.front().lanes;
// Constrain the previous turn's lanes
auto &previous_lanes = previous.intersections.front().lanes;
const auto previous_inst = previous.maneuver.instruction;
// Lane mapping (N:M) from previous lanes (N) to current lanes (M), with:
// N > M, N > 1 fan-in situation, constrain N lanes to min(N,M) shared lanes
// otherwise nothing to constrain
const bool lanes_to_constrain = previous_lanes.lanes_in_turn > 1;
const bool lanes_fan_in = previous_lanes.lanes_in_turn > current_lanes.lanes_in_turn;
// only prevent use lanes due to making all turns. don't make turns during curvy
// segments
if (previous_inst.type == TurnType::Suppressed)
distance_to_constrained += previous.distance;
else
distance_to_constrained = 0.;
const auto lane_delta = previous_lanes.lanes_in_turn - current_lanes.lanes_in_turn;
const auto can_make_all_turns =
distance_to_constrained > lane_delta * min_distance_needed_for_lane_change;
if (!lanes_to_constrain || !lanes_fan_in || can_make_all_turns)
return;
// We do not have a mapping from lanes to lanes. All we have is the lanes in the turn
// and all the lanes at that situation. To perfectly handle lane anticipation in cases
// where lanes in the turn fan in but for example the overall lanes at that location
// fan out, we would have to know the asymmetric mapping of lanes. This is currently
// not possible at the moment. In the following we implement a heuristic instead.
const LaneID current_num_lanes_right_of_turn = current.NumLanesToTheRight();
const LaneID current_num_lanes_left_of_turn = current.NumLanesToTheLeft();
// 0/ Tag keep straight with the next turn's direction if available
const auto previous_is_straight =
!isLeftTurn(previous_inst) && !isRightTurn(previous_inst);
if (previous_is_straight)
util::for_each_pair(
rev_first,
rev_last,
[&](RouteStep &current, RouteStep &previous)
{
if (isLeftTurn(current_inst) || is_straight_left.count(&current) > 0)
is_straight_left.insert(&previous);
else if (isRightTurn(current_inst) || is_straight_right.count(&current) > 0)
is_straight_right.insert(&previous);
}
const auto current_inst = current.maneuver.instruction;
const auto current_lanes = current.intersections.front().lanes;
// 1/ How to anticipate left, right:
const auto anticipate_for_left_turn = [&] {
// Current turn is left turn, already keep left during previous turn.
// This implies constraining the rightmost lanes in previous step.
LaneID new_first_lane_from_the_right =
previous_lanes.first_lane_from_the_right // start from rightmost lane
+ previous_lanes.lanes_in_turn // one past leftmost lane
- current_lanes.lanes_in_turn; // back number of new lanes
// Constrain the previous turn's lanes
auto &previous_lanes = previous.intersections.front().lanes;
const auto previous_inst = previous.maneuver.instruction;
// The leftmost target lanes might not be involved in the turn. Figure out
// how many lanes are to the left and not in the turn.
new_first_lane_from_the_right -=
std::min(current_num_lanes_left_of_turn, current_lanes.lanes_in_turn);
// Lane mapping (N:M) from previous lanes (N) to current lanes (M), with:
// N > M, N > 1 fan-in situation, constrain N lanes to min(N,M) shared lanes
// otherwise nothing to constrain
const bool lanes_to_constrain = previous_lanes.lanes_in_turn > 1;
const bool lanes_fan_in =
previous_lanes.lanes_in_turn > current_lanes.lanes_in_turn;
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
};
// only prevent use lanes due to making all turns. don't make turns during curvy
// segments
if (previous_inst.type == TurnType::Suppressed)
distance_to_constrained += previous.distance;
else
distance_to_constrained = 0.;
const auto anticipate_for_right_turn = [&] {
// Current turn is right turn, already keep right during the previous turn.
// This implies constraining the leftmost lanes in the previous turn step.
LaneID new_first_lane_from_the_right = previous_lanes.first_lane_from_the_right;
const auto lane_delta = previous_lanes.lanes_in_turn - current_lanes.lanes_in_turn;
const auto can_make_all_turns =
distance_to_constrained > lane_delta * min_distance_needed_for_lane_change;
// The rightmost target lanes might not be involved in the turn. Figure out
// how many lanes are to the right and not in the turn.
new_first_lane_from_the_right +=
std::min(current_num_lanes_right_of_turn, current_lanes.lanes_in_turn);
if (!lanes_to_constrain || !lanes_fan_in || can_make_all_turns)
return;
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
};
// We do not have a mapping from lanes to lanes. All we have is the lanes in the
// turn and all the lanes at that situation. To perfectly handle lane anticipation
// in cases where lanes in the turn fan in but for example the overall lanes at that
// location fan out, we would have to know the asymmetric mapping of lanes. This is
// currently not possible at the moment. In the following we implement a heuristic
// instead.
const LaneID current_num_lanes_right_of_turn = current.NumLanesToTheRight();
const LaneID current_num_lanes_left_of_turn = current.NumLanesToTheLeft();
// 2/ When to anticipate a left, right turn
if (isLeftTurn(current_inst))
anticipate_for_left_turn();
else if (isRightTurn(current_inst))
anticipate_for_right_turn();
else // keepStraight
{
// Heuristic: we do not have a from-lanes -> to-lanes mapping. What we use
// here instead in addition is the number of all lanes (not only the lanes
// in a turn):
//
// -v-v v-v- straight follows
// | | | |
// <- v v -> keep straight here
// | |
// <-| |->
//
// A route from the top left to the bottom right here goes over a keep
// straight. If we handle all keep straights as right turns (in right-sided
// driving), we wrongly guide the user to the rightmost lanes in the first turn.
// Not only is this wrong but the opposite of what we expect.
//
// The following implements a heuristic to determine a keep straight's
// direction in relation to the next step. In the above example we would get:
//
// coming from right, going to left (in direction of way) -> handle as left turn
// 0/ Tag keep straight with the next turn's direction if available
const auto previous_is_straight =
!isLeftTurn(previous_inst) && !isRightTurn(previous_inst);
if (is_straight_left.count(&current) > 0)
if (previous_is_straight)
{
if (isLeftTurn(current_inst) || is_straight_left.count(&current) > 0)
is_straight_left.insert(&previous);
else if (isRightTurn(current_inst) || is_straight_right.count(&current) > 0)
is_straight_right.insert(&previous);
}
// 1/ How to anticipate left, right:
const auto anticipate_for_left_turn = [&]
{
// Current turn is left turn, already keep left during previous turn.
// This implies constraining the rightmost lanes in previous step.
LaneID new_first_lane_from_the_right =
previous_lanes.first_lane_from_the_right // start from rightmost lane
+ previous_lanes.lanes_in_turn // one past leftmost lane
- current_lanes.lanes_in_turn; // back number of new lanes
// The leftmost target lanes might not be involved in the turn. Figure out
// how many lanes are to the left and not in the turn.
new_first_lane_from_the_right -=
std::min(current_num_lanes_left_of_turn, current_lanes.lanes_in_turn);
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
};
const auto anticipate_for_right_turn = [&]
{
// Current turn is right turn, already keep right during the previous turn.
// This implies constraining the leftmost lanes in the previous turn step.
LaneID new_first_lane_from_the_right = previous_lanes.first_lane_from_the_right;
// The rightmost target lanes might not be involved in the turn. Figure out
// how many lanes are to the right and not in the turn.
new_first_lane_from_the_right +=
std::min(current_num_lanes_right_of_turn, current_lanes.lanes_in_turn);
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
};
// 2/ When to anticipate a left, right turn
if (isLeftTurn(current_inst))
anticipate_for_left_turn();
else if (is_straight_right.count(&current) > 0)
else if (isRightTurn(current_inst))
anticipate_for_right_turn();
else // FIXME: right-sided driving
anticipate_for_right_turn();
}
else // keepStraight
{
// Heuristic: we do not have a from-lanes -> to-lanes mapping. What we use
// here instead in addition is the number of all lanes (not only the lanes
// in a turn):
//
// -v-v v-v- straight follows
// | | | |
// <- v v -> keep straight here
// | |
// <-| |->
//
// A route from the top left to the bottom right here goes over a keep
// straight. If we handle all keep straights as right turns (in right-sided
// driving), we wrongly guide the user to the rightmost lanes in the first turn.
// Not only is this wrong but the opposite of what we expect.
//
// The following implements a heuristic to determine a keep straight's
// direction in relation to the next step. In the above example we would get:
//
// coming from right, going to left (in direction of way) -> handle as left turn
if (previous_inst.type == TurnType::Suppressed &&
current_inst.type == TurnType::Suppressed && previous.mode == current.mode &&
previous_lanes == current_lanes)
{
previous.ElongateBy(current);
current.Invalidate();
}
});
if (is_straight_left.count(&current) > 0)
anticipate_for_left_turn();
else if (is_straight_right.count(&current) > 0)
anticipate_for_right_turn();
else // FIXME: right-sided driving
anticipate_for_right_turn();
}
if (previous_inst.type == TurnType::Suppressed &&
current_inst.type == TurnType::Suppressed && previous.mode == current.mode &&
previous_lanes == current_lanes)
{
previous.ElongateBy(current);
current.Invalidate();
}
});
};
std::for_each(begin(quick_lanes_ranges), end(quick_lanes_ranges), constrain_lanes);
+21 -16
View File
@@ -77,7 +77,8 @@ void processRoundaboutExits(const RouteStepIterator begin, const RouteStepIterat
return;
}
const auto passes_exit_or_leaves_roundabout = [](auto const &step) {
const auto passes_exit_or_leaves_roundabout = [](auto const &step)
{
return staysOnRoundabout(step.maneuver.instruction) ||
leavesRoundabout(step.maneuver.instruction);
};
@@ -142,9 +143,8 @@ void processRoundaboutExits(const RouteStepIterator begin, const RouteStepIterat
// instructions in between
void processRoundaboutGroups(const std::pair<RouteStepIterator, RouteStepIterator> &range)
{
const auto leaves_roundabout = [](auto const &step) {
return leavesRoundabout(step.maneuver.instruction);
};
const auto leaves_roundabout = [](auto const &step)
{ return leavesRoundabout(step.maneuver.instruction); };
auto itr = range.first;
while (itr != range.second)
@@ -174,9 +174,8 @@ void processRoundaboutGroups(const std::pair<RouteStepIterator, RouteStepIterato
std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps)
{
// check if a step has roundabout type
const auto has_roundabout_type = [](auto const &step) {
return hasRoundaboutType(step.maneuver.instruction);
};
const auto has_roundabout_type = [](auto const &step)
{ return hasRoundaboutType(step.maneuver.instruction); };
const auto first_roundabout_type =
std::find_if(steps.begin(), steps.end(), has_roundabout_type);
@@ -193,7 +192,8 @@ std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps)
// this group by paradigm does might contain intermediate roundabout instructions, when they are
// directly connected. Otherwise it will be a sequence containing everything from enter to exit.
// If we already start on the roundabout, the first valid place will be steps.begin().
const auto is_on_roundabout = [&currently_on_roundabout](const auto &step) {
const auto is_on_roundabout = [&currently_on_roundabout](const auto &step)
{
if (currently_on_roundabout)
{
if (leavesRoundabout(step.maneuver.instruction))
@@ -327,10 +327,13 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
}
// and update the leg geometry indices for the removed entry
std::for_each(steps.begin(), steps.end(), [offset](RouteStep &step) {
step.geometry_begin -= offset;
step.geometry_end -= offset;
});
std::for_each(steps.begin(),
steps.end(),
[offset](RouteStep &step)
{
step.geometry_begin -= offset;
step.geometry_end -= offset;
});
auto &first_step = steps.front();
auto bearing = first_bearing;
@@ -645,16 +648,18 @@ void applyOverrides(const datafacade::BaseDataFacade &facade,
auto step_to_update = std::find_if(
current_step_it,
route_iter,
[&leg_geometry, &via_node_coords](const auto &step) {
[&leg_geometry, &via_node_coords](const auto &step)
{
util::Log(logDEBUG) << "Leg geom from " << step.geometry_begin << " to "
<< step.geometry_end << std::endl;
// iterators over geometry of current step
auto begin = leg_geometry.locations.begin() + step.geometry_begin;
auto end = leg_geometry.locations.begin() + step.geometry_end;
auto via_match = std::find_if(begin, end, [&](const auto &location) {
return location == via_node_coords;
});
auto via_match = std::find_if(begin,
end,
[&](const auto &location)
{ return location == via_node_coords; });
if (via_match != end)
{
util::Log(logDEBUG)
+27 -25
View File
@@ -15,19 +15,20 @@ std::vector<RouteStep> suppressShortNameSegments(std::vector<RouteStep> steps)
return steps;
// we remove only name changes that don't offer additional information
const auto name_change_without_lanes = [](const RouteStep &step) {
return hasTurnType(step, TurnType::NewName) && !hasLanes(step);
};
const auto name_change_without_lanes = [](const RouteStep &step)
{ return hasTurnType(step, TurnType::NewName) && !hasLanes(step); };
// check if the next step is not important enough to announce
const auto can_be_extended_to = [](const RouteStep &step) {
const auto can_be_extended_to = [](const RouteStep &step)
{
const auto is_not_arrive = !hasWaypointType(step);
const auto is_silent = !hasTurnType(step) || hasTurnType(step, TurnType::Suppressed);
return is_not_arrive && is_silent;
};
const auto suppress = [](RouteStep &from_step, RouteStep &onto_step) {
const auto suppress = [](RouteStep &from_step, RouteStep &onto_step)
{
from_step.ElongateBy(onto_step);
onto_step.Invalidate();
};
@@ -36,28 +37,29 @@ std::vector<RouteStep> suppressShortNameSegments(std::vector<RouteStep> steps)
// only available for a very short time
const auto reduce_verbosity_if_possible =
[suppress, can_be_extended_to](RouteStepIterator &current_turn_itr,
RouteStepIterator &previous_turn_itr) {
if (haveSameName(*previous_turn_itr, *current_turn_itr))
RouteStepIterator &previous_turn_itr)
{
if (haveSameName(*previous_turn_itr, *current_turn_itr))
suppress(*previous_turn_itr, *current_turn_itr);
else
{
// remember the location of the name change so we can advance the previous turn
const auto location_of_name_change = current_turn_itr;
auto distance = current_turn_itr->distance;
// sum up all distances that can be relevant to the name change
while (can_be_extended_to(*(current_turn_itr + 1)) &&
distance < NAME_SEGMENT_CUTOFF_LENGTH)
{
++current_turn_itr;
distance += current_turn_itr->distance;
}
if (distance < NAME_SEGMENT_CUTOFF_LENGTH)
suppress(*previous_turn_itr, *current_turn_itr);
else
{
// remember the location of the name change so we can advance the previous turn
const auto location_of_name_change = current_turn_itr;
auto distance = current_turn_itr->distance;
// sum up all distances that can be relevant to the name change
while (can_be_extended_to(*(current_turn_itr + 1)) &&
distance < NAME_SEGMENT_CUTOFF_LENGTH)
{
++current_turn_itr;
distance += current_turn_itr->distance;
}
if (distance < NAME_SEGMENT_CUTOFF_LENGTH)
suppress(*previous_turn_itr, *current_turn_itr);
else
previous_turn_itr = location_of_name_change;
}
};
previous_turn_itr = location_of_name_change;
}
};
BOOST_ASSERT(!hasTurnType(steps.back()) && hasWaypointType(steps.back()));
for (auto previous_turn_itr = steps.begin(), current_turn_itr = std::next(previous_turn_itr);
+4 -4
View File
@@ -93,10 +93,10 @@ Hint Hint::FromBase64(const std::string &base64Hint)
bool Hint::IsValid(const util::Coordinate new_input_coordinates,
const datafacade::BaseDataFacade &facade) const
{
const auto all_valid =
std::all_of(segment_hints.begin(), segment_hints.end(), [&](const auto &seg_hint) {
return seg_hint.IsValid(new_input_coordinates, facade);
});
const auto all_valid = std::all_of(segment_hints.begin(),
segment_hints.end(),
[&](const auto &seg_hint)
{ return seg_hint.IsValid(new_input_coordinates, facade); });
if (!all_valid)
{
return false;
+12 -10
View File
@@ -50,7 +50,8 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
// sort by forward id, then by reverse id and then by distance
std::sort(candidates.begin(),
candidates.end(),
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs) {
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs)
{
return lhs.phantom_node.forward_segment_id.id <
rhs.phantom_node.forward_segment_id.id ||
(lhs.phantom_node.forward_segment_id.id ==
@@ -65,7 +66,8 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
auto new_end =
std::unique(candidates.begin(),
candidates.end(),
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs) {
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs)
{
return lhs.phantom_node.forward_segment_id.id ==
rhs.phantom_node.forward_segment_id.id &&
lhs.phantom_node.reverse_segment_id.id ==
@@ -95,9 +97,8 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
// sort by distance to make pruning effective
std::sort(candidates.begin(),
candidates.end(),
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs) {
return lhs.distance < rhs.distance;
});
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs)
{ return lhs.distance < rhs.distance; });
}
}
@@ -133,7 +134,8 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
if (max_radius_map_matching > 0 && std::any_of(parameters.radiuses.begin(),
parameters.radiuses.end(),
[&](const auto &radius) {
[&](const auto &radius)
{
if (!radius)
return false;
return *radius > max_radius_map_matching;
@@ -192,7 +194,8 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
tidied.parameters.radiuses.begin(),
tidied.parameters.radiuses.end(),
search_radiuses.begin(),
[default_radius = this->default_radius](const boost::optional<double> &maybe_radius) {
[default_radius = this->default_radius](const boost::optional<double> &maybe_radius)
{
if (maybe_radius)
{
return *maybe_radius * RADIUS_MULTIPLIER;
@@ -212,9 +215,8 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
filterCandidates(tidied.parameters.coordinates, candidates_lists);
if (std::all_of(candidates_lists.begin(),
candidates_lists.end(),
[](const std::vector<PhantomNodeWithDistance> &candidates) {
return candidates.empty();
}))
[](const std::vector<PhantomNodeWithDistance> &candidates)
{ return candidates.empty(); }))
{
return Error("NoSegment",
std::string("Could not find a matching segment for any coordinate."),
+4 -4
View File
@@ -251,7 +251,8 @@ std::vector<std::size_t> getEdgeIndex(const std::vector<RTreeLeaf> &edges)
// as the sort condition
std::sort(sorted_edge_indexes.begin(),
sorted_edge_indexes.end(),
[&edges](const std::size_t &left, const std::size_t &right) -> bool {
[&edges](const std::size_t &left, const std::size_t &right) -> bool
{
return (edges[left].u != edges[right].u) ? edges[left].u < edges[right].u
: edges[left].v < edges[right].v;
});
@@ -430,9 +431,8 @@ void encodeVectorTile(const DataFacadeBase &facade,
{
vtzero::tile_builder tile;
const auto get_geometry_id = [&facade](auto edge) {
return facade.GetGeometryIndex(edge.forward_segment_id.id).id;
};
const auto get_geometry_id = [&facade](auto edge)
{ return facade.GetGeometryIndex(edge.forward_segment_id.id).id; };
// Convert tile coordinates into mercator coordinates
double min_mercator_lon, min_mercator_lat, max_mercator_lon, max_mercator_lat;
+19 -17
View File
@@ -137,7 +137,8 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
std::vector<bool> waypoint_legs(route_parameters.coordinates.size(), false);
std::for_each(route_parameters.waypoints.begin(),
route_parameters.waypoints.end(),
[&](const std::size_t waypoint_index) {
[&](const std::size_t waypoint_index)
{
BOOST_ASSERT(waypoint_index < waypoint_legs.size());
waypoint_legs[waypoint_index] = true;
});
@@ -156,22 +157,23 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
else
{
const auto all_in_same_component =
[](const std::vector<PhantomNodeCandidates> &waypoint_candidates) {
return std::any_of(waypoint_candidates.front().begin(),
waypoint_candidates.front().end(),
// For each of the first possible phantoms, check if all other
// positions in the list have a phantom from the same component.
[&](const PhantomNode &phantom) {
const auto component_id = phantom.component.id;
return std::all_of(
std::next(waypoint_candidates.begin()),
std::end(waypoint_candidates),
[component_id](const PhantomNodeCandidates &candidates) {
return candidatesHaveComponent(candidates,
component_id);
});
});
};
[](const std::vector<PhantomNodeCandidates> &waypoint_candidates)
{
return std::any_of(waypoint_candidates.front().begin(),
waypoint_candidates.front().end(),
// For each of the first possible phantoms, check if all other
// positions in the list have a phantom from the same component.
[&](const PhantomNode &phantom)
{
const auto component_id = phantom.component.id;
return std::all_of(
std::next(waypoint_candidates.begin()),
std::end(waypoint_candidates),
[component_id](const PhantomNodeCandidates &candidates) {
return candidatesHaveComponent(candidates, component_id);
});
});
};
if (!all_in_same_component(snapped_phantoms))
{
@@ -223,9 +223,8 @@ RandIt filterViaCandidatesByStretch(RandIt first,
const auto stretch_weight_limit =
(1. + parameters.kAtMostLongerBy) * from_alias<double>(weight);
const auto over_weight_limit = [=](const auto via) {
return from_alias<double>(via.weight) > stretch_weight_limit;
};
const auto over_weight_limit = [=](const auto via)
{ return from_alias<double>(via.weight) > stretch_weight_limit; };
return std::remove_if(first, last, over_weight_limit);
}
@@ -298,13 +297,15 @@ RandIt filterPackedPathsByCellSharing(RandIt first,
for (const auto &edge : shortest_path.path)
cells.insert(get_cell(std::get<1>(edge)));
const auto over_sharing_limit = [&](const auto &packed) {
const auto over_sharing_limit = [&](const auto &packed)
{
if (packed.path.empty())
{ // don't remove routes with single-node (empty) path
return false;
}
const auto not_seen = [&](const PackedEdge edge) {
const auto not_seen = [&](const PackedEdge edge)
{
const auto source_cell = get_cell(std::get<0>(edge));
const auto target_cell = get_cell(std::get<1>(edge));
return cells.count(source_cell) < 1 && cells.count(target_cell) < 1;
@@ -364,7 +365,8 @@ RandIt filterPackedPathsByLocalOptimality(const WeightedViaNodePackedPath &path,
BOOST_ASSERT(path.via.weight != INVALID_EDGE_WEIGHT);
// node == parent_in_main_heap(parent_in_side_heap(v)) -> plateaux at `node`
const auto has_plateaux_at_node = [&](const NodeID node, const Heap &fst, const Heap &snd) {
const auto has_plateaux_at_node = [&](const NodeID node, const Heap &fst, const Heap &snd)
{
BOOST_ASSERT(fst.WasInserted(node));
auto const parent = fst.GetData(node).parent;
return snd.WasInserted(parent) && snd.GetData(parent).parent == node;
@@ -374,7 +376,8 @@ RandIt filterPackedPathsByLocalOptimality(const WeightedViaNodePackedPath &path,
// tree from t overlap. An edge is part of such a plateaux around `v` if:
// v == parent_in_reverse_search(parent_in_forward_search(v)).
// Here we calculate the last node on the plateaux in either direction.
const auto plateaux_end = [&](NodeID node, const Heap &fst, const Heap &snd) {
const auto plateaux_end = [&](NodeID node, const Heap &fst, const Heap &snd)
{
BOOST_ASSERT(node != SPECIAL_NODEID);
BOOST_ASSERT(fst.WasInserted(node));
BOOST_ASSERT(snd.WasInserted(node));
@@ -388,7 +391,8 @@ RandIt filterPackedPathsByLocalOptimality(const WeightedViaNodePackedPath &path,
return node;
};
const auto is_not_locally_optimal = [&](const auto &packed) {
const auto is_not_locally_optimal = [&](const auto &packed)
{
BOOST_ASSERT(packed.via.node != path.via.node);
BOOST_ASSERT(packed.via.weight != INVALID_EDGE_WEIGHT);
BOOST_ASSERT(packed.via.node != SPECIAL_NODEID);
@@ -475,14 +479,16 @@ RandIt filterUnpackedPathsBySharing(RandIt first,
nodes.insert(begin(shortest_path.nodes), end(shortest_path.nodes));
const auto over_sharing_limit = [&](auto &unpacked) {
const auto over_sharing_limit = [&](auto &unpacked)
{
if (unpacked.edges.empty())
{ // don't remove routes with single-node (empty) path
return false;
}
EdgeDuration total_duration = {0};
const auto add_if_seen = [&](const EdgeDuration duration, const NodeID node) {
const auto add_if_seen = [&](const EdgeDuration duration, const NodeID node)
{
auto node_duration = facade.GetNodeDuration(node);
total_duration += node_duration;
if (nodes.count(node) > 0)
@@ -533,9 +539,8 @@ RandIt filterAnnotatedRoutesByStretch(RandIt first,
const auto stretch_duration_limit =
(1. + parameters.kAtMostLongerBy) * from_alias<double>(shortest_route_duration);
const auto over_duration_limit = [=](const auto &route) {
return from_alias<double>(route.duration()) > stretch_duration_limit;
};
const auto over_duration_limit = [=](const auto &route)
{ return from_alias<double>(route.duration()) > stretch_duration_limit; };
return std::remove_if(first, last, over_duration_limit);
}
@@ -837,9 +842,9 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &sear
it = filterViaCandidatesByStretch(begin(candidate_vias), it, shortest_path_weight, parameters);
// Pre-rank by weight; sharing filtering below then discards by similarity.
std::sort(begin(candidate_vias), it, [](const auto lhs, const auto rhs) {
return lhs.weight < rhs.weight;
});
std::sort(begin(candidate_vias),
it,
[](const auto lhs, const auto rhs) { return lhs.weight < rhs.weight; });
// Filtered and ranked candidate range
const auto candidate_vias_first = begin(candidate_vias);
@@ -850,7 +855,8 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &sear
// The recursive path unpacking below destructs heaps.
// We need to save all packed paths from the heaps upfront.
const auto extract_packed_path_from_heaps = [&](WeightedViaNode via) {
const auto extract_packed_path_from_heaps = [&](WeightedViaNode via)
{
auto packed_path = retrievePackedPathFromHeap(forward_heap, reverse_heap, via.node);
return WeightedViaNodePackedPath{via, std::move(packed_path)};
@@ -928,9 +934,8 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &sear
std::vector<InternalRouteResult> routes;
routes.reserve(number_of_unpacked_paths);
const auto unpacked_path_to_route = [&](const WeightedViaNodeUnpackedPath &path) {
return extractRoute(facade, path.via.weight, endpoint_candidates, path.nodes, path.edges);
};
const auto unpacked_path_to_route = [&](const WeightedViaNodeUnpackedPath &path)
{ return extractRoute(facade, path.via.weight, endpoint_candidates, path.nodes, path.edges); };
std::transform(unpacked_paths_first,
unpacked_paths_last,
@@ -45,15 +45,16 @@ InternalRouteResult directShortestPathSearch(SearchEngineData<ch::Algorithm> &en
unpacked_nodes.reserve(packed_leg.size());
unpacked_edges.reserve(packed_leg.size());
unpacked_nodes.push_back(packed_leg.front());
ch::unpackPath(facade,
packed_leg.begin(),
packed_leg.end(),
[&unpacked_nodes, &unpacked_edges](std::pair<NodeID, NodeID> &edge,
const auto &edge_id) {
BOOST_ASSERT(edge.first == unpacked_nodes.back());
unpacked_nodes.push_back(edge.second);
unpacked_edges.push_back(edge_id);
});
ch::unpackPath(
facade,
packed_leg.begin(),
packed_leg.end(),
[&unpacked_nodes, &unpacked_edges](std::pair<NodeID, NodeID> &edge, const auto &edge_id)
{
BOOST_ASSERT(edge.first == unpacked_nodes.back());
unpacked_nodes.push_back(edge.second);
unpacked_edges.push_back(edge_id);
});
}
return extractRoute(facade, weight, endpoint_candidates, unpacked_nodes, unpacked_edges);
@@ -95,7 +95,7 @@ void relaxOutgoingEdges(
const DataFacade<mld::Algorithm> &facade,
const typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap::HeapNode &heapNode,
typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &query_heap,
const Args &... args)
const Args &...args)
{
BOOST_ASSERT(!facade.ExcludeNode(heapNode.node));
@@ -280,49 +280,51 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
// Check if node is in the destinations list and update weights/durations
auto update_values =
[&](NodeID node, EdgeWeight weight, EdgeDuration duration, EdgeDistance distance) {
auto candidates = target_nodes_index.equal_range(node);
for (auto it = candidates.first; it != candidates.second;)
[&](NodeID node, EdgeWeight weight, EdgeDuration duration, EdgeDistance distance)
{
auto candidates = target_nodes_index.equal_range(node);
for (auto it = candidates.first; it != candidates.second;)
{
std::size_t index;
EdgeWeight target_weight;
EdgeDuration target_duration;
EdgeDistance target_distance;
std::tie(index, target_weight, target_duration, target_distance) = it->second;
const auto path_weight = weight + target_weight;
if (path_weight >= EdgeWeight{0})
{
std::size_t index;
EdgeWeight target_weight;
EdgeDuration target_duration;
EdgeDistance target_distance;
std::tie(index, target_weight, target_duration, target_distance) = it->second;
const auto path_duration = duration + target_duration;
const auto path_distance = distance + target_distance;
const auto path_weight = weight + target_weight;
if (path_weight >= EdgeWeight{0})
EdgeDistance nulldistance = {0};
auto &current_distance =
distances_table.empty() ? nulldistance : distances_table[index];
if (std::tie(path_weight, path_duration, path_distance) <
std::tie(weights_table[index], durations_table[index], current_distance))
{
const auto path_duration = duration + target_duration;
const auto path_distance = distance + target_distance;
EdgeDistance nulldistance = {0};
auto &current_distance =
distances_table.empty() ? nulldistance : distances_table[index];
if (std::tie(path_weight, path_duration, path_distance) <
std::tie(weights_table[index], durations_table[index], current_distance))
{
weights_table[index] = path_weight;
durations_table[index] = path_duration;
current_distance = path_distance;
middle_nodes_table[index] = node;
}
// Remove node from destinations list
it = target_nodes_index.erase(it);
}
else
{
++it;
weights_table[index] = path_weight;
durations_table[index] = path_duration;
current_distance = path_distance;
middle_nodes_table[index] = node;
}
// Remove node from destinations list
it = target_nodes_index.erase(it);
}
};
else
{
++it;
}
}
};
auto insert_node = [&](NodeID node,
EdgeWeight initial_weight,
EdgeDuration initial_duration,
EdgeDistance initial_distance) {
EdgeDistance initial_distance)
{
if (target_nodes_index.count(node))
{
// Source and target on the same edge node. If target is not reachable directly via
+19 -18
View File
@@ -83,7 +83,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
const bool use_timestamps = trace_timestamps.size() > 1;
const auto median_sample_time = [&] {
const auto median_sample_time = [&]
{
if (use_timestamps)
{
return std::max(1u, getMedianSampleTime(trace_timestamps));
@@ -104,9 +105,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
std::transform(candidates_list[t].begin(),
candidates_list[t].end(),
emission_log_probabilities[t].begin(),
[&](const PhantomNodeWithDistance &candidate) {
return default_emission_log_probability(candidate.distance);
});
[&](const PhantomNodeWithDistance &candidate)
{ return default_emission_log_probability(candidate.distance); });
}
}
else
@@ -118,22 +118,19 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
{
map_matching::EmissionLogProbability emission_log_probability(
*trace_gps_precision[t]);
std::transform(
candidates_list[t].begin(),
candidates_list[t].end(),
emission_log_probabilities[t].begin(),
[&emission_log_probability](const PhantomNodeWithDistance &candidate) {
return emission_log_probability(candidate.distance);
});
std::transform(candidates_list[t].begin(),
candidates_list[t].end(),
emission_log_probabilities[t].begin(),
[&emission_log_probability](const PhantomNodeWithDistance &candidate)
{ return emission_log_probability(candidate.distance); });
}
else
{
std::transform(candidates_list[t].begin(),
candidates_list[t].end(),
emission_log_probabilities[t].begin(),
[&](const PhantomNodeWithDistance &candidate) {
return default_emission_log_probability(candidate.distance);
});
[&](const PhantomNodeWithDistance &candidate)
{ return default_emission_log_probability(candidate.distance); });
}
}
}
@@ -158,7 +155,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
for (auto t = initial_timestamp + 1; t < candidates_list.size(); ++t)
{
const auto step_time = [&] {
const auto step_time = [&]
{
if (use_timestamps)
{
return trace_timestamps[t] - trace_timestamps[prev_unbroken_timestamps.back()];
@@ -169,7 +167,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
}
}();
const auto max_distance_delta = [&] {
const auto max_distance_delta = [&]
{
if (use_timestamps)
{
return step_time * facade.GetMapMatchingMaxSpeed();
@@ -180,7 +179,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
}
}();
const bool gap_in_trace = [&]() {
const bool gap_in_trace = [&]()
{
// use temporal information if available to determine a split
// but do not determine split by timestamps if wasn't asked about it
if (use_timestamps && allow_splitting)
@@ -419,7 +419,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
util::for_each_pair(
reconstructed_indices,
[&trace_distance, &trace_coordinates](const std::pair<std::size_t, std::size_t> &prev,
const std::pair<std::size_t, std::size_t> &curr) {
const std::pair<std::size_t, std::size_t> &curr)
{
trace_distance += util::coordinate_calculation::greatCircleDistance(
trace_coordinates[prev.first], trace_coordinates[curr.first]);
});
@@ -25,9 +25,8 @@ std::vector<NodeID> getForwardLoopNodes(const PhantomEndpointCandidates &endpoin
auto requires_loop =
std::any_of(endpoint_candidates.target_phantoms.begin(),
endpoint_candidates.target_phantoms.end(),
[&](const auto &target_phantom) {
return requiresForwardLoop(source_phantom, target_phantom);
});
[&](const auto &target_phantom)
{ return requiresForwardLoop(source_phantom, target_phantom); });
if (requires_loop)
{
res.push_back(source_phantom.forward_segment_id.id);
@@ -57,9 +56,8 @@ std::vector<NodeID> getBackwardLoopNodes(const PhantomEndpointCandidates &endpoi
auto requires_loop =
std::any_of(endpoint_candidates.target_phantoms.begin(),
endpoint_candidates.target_phantoms.end(),
[&](const auto &target_phantom) {
return requiresBackwardLoop(source_phantom, target_phantom);
});
[&](const auto &target_phantom)
{ return requiresBackwardLoop(source_phantom, target_phantom); });
if (requires_loop)
{
res.push_back(source_phantom.reverse_segment_id.id);
@@ -86,7 +84,8 @@ PhantomEndpoints endpointsFromCandidates(const PhantomEndpointCandidates &candid
{
auto source_it = std::find_if(candidates.source_phantoms.begin(),
candidates.source_phantoms.end(),
[&path](const auto &source_phantom) {
[&path](const auto &source_phantom)
{
return path.front() == source_phantom.forward_segment_id.id ||
path.front() == source_phantom.reverse_segment_id.id;
});
@@ -94,7 +93,8 @@ PhantomEndpoints endpointsFromCandidates(const PhantomEndpointCandidates &candid
auto target_it = std::find_if(candidates.target_phantoms.begin(),
candidates.target_phantoms.end(),
[&path](const auto &target_phantom) {
[&path](const auto &target_phantom)
{
return path.back() == target_phantom.forward_segment_id.id ||
path.back() == target_phantom.reverse_segment_id.id;
});
@@ -19,9 +19,8 @@ void unpackEdge(const DataFacade<Algorithm> &facade,
unpackPath(facade,
path.begin(),
path.end(),
[&unpacked_path](const std::pair<NodeID, NodeID> &edge, const auto & /* data */) {
unpacked_path.emplace_back(edge.first);
});
[&unpacked_path](const std::pair<NodeID, NodeID> &edge, const auto & /* data */)
{ unpacked_path.emplace_back(edge.first); });
unpacked_path.emplace_back(to);
}
+10 -11
View File
@@ -35,9 +35,8 @@ std::vector<TurnData> generateTurns(const datafacade &facade,
// it saves us a bunch of re-allocations during iteration.
directed_graph.reserve(edges.size() * 2);
const auto get_geometry_id = [&facade](auto edge) {
return facade.GetGeometryIndex(edge.forward_segment_id.id).id;
};
const auto get_geometry_id = [&facade](auto edge)
{ return facade.GetGeometryIndex(edge.forward_segment_id.id).id; };
// To build a tile, we can only rely on the r-tree to quickly find all data visible within the
// tile itself. The Rtree returns a series of segments that may or may not offer turns
@@ -215,10 +214,10 @@ std::vector<TurnData> getTileTurns(const DataFacade<ch::Algorithm> &facade,
//
// would offer a backward edge at `b` to `a` (due to the oneway from a to b)
// but could also offer a shortcut (b-c-a) from `b` to `a` which is longer.
EdgeID edge_id = facade.FindSmallestEdge(
approach_node, exit_node, [](const contractor::QueryEdge::EdgeData &data) {
return data.forward && !data.shortcut;
});
EdgeID edge_id = facade.FindSmallestEdge(approach_node,
exit_node,
[](const contractor::QueryEdge::EdgeData &data)
{ return data.forward && !data.shortcut; });
// Depending on how the graph is constructed, we might have to look for
// a backwards edge instead. They're equivalent, just one is available for
@@ -227,10 +226,10 @@ std::vector<TurnData> getTileTurns(const DataFacade<ch::Algorithm> &facade,
// If we didn't find a forward edge, try for a backward one
if (SPECIAL_EDGEID == edge_id)
{
edge_id = facade.FindSmallestEdge(
exit_node, approach_node, [](const contractor::QueryEdge::EdgeData &data) {
return data.backward && !data.shortcut;
});
edge_id = facade.FindSmallestEdge(exit_node,
approach_node,
[](const contractor::QueryEdge::EdgeData &data)
{ return data.backward && !data.shortcut; });
}
BOOST_ASSERT_MSG(edge_id == SPECIAL_EDGEID || !facade.GetEdgeData(edge_id).shortcut,
+51 -35
View File
@@ -151,7 +151,8 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
NodeID current_edge_source_coordinate_id = node_u;
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id) {
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id)
{
if (edge_based_node_id == SPECIAL_NODEID)
{
return SegmentID{SPECIAL_SEGMENTID, false};
@@ -409,7 +410,8 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
NodeID current_edge_source_coordinate_id = node_u;
const EdgeData &forward_data = m_node_based_graph.GetEdgeData(eid);
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id) {
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id)
{
if (edge_based_node_id == SPECIAL_NODEID)
{
return SegmentID{SPECIAL_SEGMENTID, false};
@@ -532,7 +534,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
TurnPenalty turn_duration_penalty;
};
auto const transfer_data = [&](const EdgeWithData &edge_with_data) {
auto const transfer_data = [&](const EdgeWithData &edge_with_data)
{
m_edge_based_edge_list.push_back(edge_with_data.edge);
turn_weight_penalties.push_back(edge_with_data.turn_weight_penalty);
turn_duration_penalties.push_back(edge_with_data.turn_duration_penalty);
@@ -568,7 +571,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
// First part of the pipeline generates iterator ranges of IDs in sets of GRAINSIZE
tbb::filter<void, tbb::blocked_range<NodeID>> generator_stage(
tbb::filter_mode::serial_in_order, [&](tbb::flow_control &fc) {
tbb::filter_mode::serial_in_order,
[&](tbb::flow_control &fc)
{
if (current_node < node_count)
{
auto next_node = std::min(current_node + GRAINSIZE, node_count);
@@ -599,7 +604,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const auto &turn_angle,
const auto &road_legs_on_the_right,
const auto &road_legs_on_the_left,
const auto &edge_geometries) {
const auto &edge_geometries)
{
const auto &edge_data1 = m_node_based_graph.GetEdgeData(node_based_edge_from);
const auto &edge_data2 = m_node_based_graph.GetEdgeData(node_based_edge_to);
@@ -710,7 +716,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
//
tbb::filter<tbb::blocked_range<NodeID>, EdgesPipelineBufferPtr> processor_stage(
tbb::filter_mode::parallel,
[&](const tbb::blocked_range<NodeID> &intersection_node_range) {
[&](const tbb::blocked_range<NodeID> &intersection_node_range)
{
auto buffer = std::make_shared<EdgesPipelineBuffer>();
buffer->nodes_processed = intersection_node_range.size();
@@ -795,16 +802,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const auto turn =
std::find_if(connected_roads.begin(),
connected_roads.end(),
[edge = outgoing_edge.edge](const auto &road) {
return road.eid == edge;
});
[edge = outgoing_edge.edge](const auto &road)
{ return road.eid == edge; });
OSRM_ASSERT(turn != connected_roads.end(),
m_coordinates[intersection_node]);
std::vector<ExtractionTurnLeg> road_legs_on_the_right;
std::vector<ExtractionTurnLeg> road_legs_on_the_left;
auto get_connected_road_info = [&](const auto &connected_edge) {
auto get_connected_road_info = [&](const auto &connected_edge)
{
const auto &edge_data =
m_node_based_graph.GetEdgeData(connected_edge.eid);
@@ -1012,9 +1019,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
auto const has_unconditional =
std::any_of(restrictions.begin(),
restrictions.end(),
[](const auto &restriction) {
return restriction->IsUnconditional();
});
[](const auto &restriction)
{ return restriction->IsUnconditional(); });
if (has_unconditional)
continue;
@@ -1120,7 +1126,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
util::Percent routing_progress(log, node_count);
std::vector<EdgeWithData> delayed_data;
tbb::filter<EdgesPipelineBufferPtr, void> output_stage(
tbb::filter_mode::serial_in_order, [&](auto buffer) {
tbb::filter_mode::serial_in_order,
[&](auto buffer)
{
routing_progress.PrintAddition(buffer->nodes_processed);
m_connectivity_checksum = buffer->checksum.update_checksum(m_connectivity_checksum);
@@ -1140,7 +1148,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
std::for_each(buffer->turn_to_ebn_map.begin(),
buffer->turn_to_ebn_map.end(),
[&global_turn_to_ebn_map](const auto &p) {
[&global_turn_to_ebn_map](const auto &p)
{
// TODO: log conflicts here
global_turn_to_ebn_map.insert(p);
});
@@ -1178,26 +1187,32 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
return std::vector<NodeID>{turn_edges.second.first, turn_edges.second.second};
});
std::for_each(std::next(turns.begin()), turns.end(), [&](const auto &turn) {
std::vector<std::vector<NodeID>> next_node_sequences;
const auto next_turn_edges = global_turn_to_ebn_map.equal_range(turn);
for (auto &node_sequence : node_sequences)
{
const auto found_it = std::find_if(
next_turn_edges.first, next_turn_edges.second, [&](const auto &turn_edges) {
const auto pre_turn_edge = turn_edges.second.first;
return (node_sequence.back() == pre_turn_edge);
});
std::for_each(std::next(turns.begin()),
turns.end(),
[&](const auto &turn)
{
std::vector<std::vector<NodeID>> next_node_sequences;
const auto next_turn_edges = global_turn_to_ebn_map.equal_range(turn);
for (auto &node_sequence : node_sequences)
{
const auto found_it = std::find_if(
next_turn_edges.first,
next_turn_edges.second,
[&](const auto &turn_edges)
{
const auto pre_turn_edge = turn_edges.second.first;
return (node_sequence.back() == pre_turn_edge);
});
if (found_it != next_turn_edges.second)
{
const auto post_turn_edge = found_it->second.second;
node_sequence.push_back(post_turn_edge);
next_node_sequences.push_back(std::move(node_sequence));
}
}
node_sequences = std::move(next_node_sequences);
});
if (found_it != next_turn_edges.second)
{
const auto post_turn_edge = found_it->second.second;
node_sequence.push_back(post_turn_edge);
next_node_sequences.push_back(std::move(node_sequence));
}
}
node_sequences = std::move(next_node_sequences);
});
for (const auto &node_sequence : node_sequences)
{
@@ -1237,7 +1252,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
// Now, update the turn_id property on every EdgeBasedEdge - it will equal the position in the
// m_edge_based_edge_list array for each object.
tbb::parallel_for(tbb::blocked_range<NodeID>(0, m_edge_based_edge_list.size()),
[this](const tbb::blocked_range<NodeID> &range) {
[this](const tbb::blocked_range<NodeID> &range)
{
for (auto x = range.begin(), end = range.end(); x != end; ++x)
{
m_edge_based_edge_list[x].data.turn_id = x;
+42 -25
View File
@@ -460,10 +460,10 @@ void ExtractionContainers::PrepareNodes()
util::UnbufferedLog log;
log << "Sorting all nodes ... " << std::flush;
TIMER_START(sorting_nodes);
tbb::parallel_sort(
all_nodes_list.begin(), all_nodes_list.end(), [](const auto &left, const auto &right) {
return left.node_id < right.node_id;
});
tbb::parallel_sort(all_nodes_list.begin(),
all_nodes_list.end(),
[](const auto &left, const auto &right)
{ return left.node_id < right.node_id; });
TIMER_STOP(sorting_nodes);
log << "ok, after " << TIMER_SEC(sorting_nodes) << "s";
}
@@ -629,7 +629,8 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
// Remove all remaining edges. They are invalid because there are no corresponding nodes for
// them. This happens when using osmosis with bbox or polygon to extract smaller areas.
auto markSourcesInvalid = [](InternalExtractorEdge &edge) {
auto markSourcesInvalid = [](InternalExtractorEdge &edge)
{
util::Log(logDEBUG) << "Found invalid node reference " << edge.result.source;
edge.result.source = SPECIAL_NODEID;
edge.result.osm_source_id = SPECIAL_OSM_NODEID;
@@ -743,7 +744,8 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
// Remove all remaining edges. They are invalid because there are no corresponding nodes for
// them. This happens when using osmosis with bbox or polygon to extract smaller areas.
auto markTargetsInvalid = [](InternalExtractorEdge &edge) {
auto markTargetsInvalid = [](InternalExtractorEdge &edge)
{
util::Log(logDEBUG) << "Found invalid node reference " << edge.result.target;
edge.result.target = SPECIAL_NODEID;
};
@@ -898,7 +900,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
<< " maneuver overrides...";
TIMER_START(identify_maneuver_override_ways);
const auto mark_ids = [&](auto const &external_maneuver_override) {
const auto mark_ids = [&](auto const &external_maneuver_override)
{
NodesOfWay dummy_segment{MAX_OSM_WAYID, {MAX_OSM_NODEID, MAX_OSM_NODEID}};
const auto &turn_path = external_maneuver_override.turn_path;
maneuver_override_ways[turn_path.From()] = dummy_segment;
@@ -918,7 +921,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
std::for_each(
external_maneuver_overrides_list.begin(), external_maneuver_overrides_list.end(), mark_ids);
const auto set_ids = [&](size_t way_list_idx, auto const &way_id) {
const auto set_ids = [&](size_t way_list_idx, auto const &way_id)
{
auto itr = maneuver_override_ways.find(way_id);
if (itr != maneuver_override_ways.end())
{
@@ -984,7 +988,8 @@ void ExtractionContainers::PrepareTrafficSignals(
void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways)
{
auto const osm_node_to_internal_nbn = [&](auto const osm_node) {
auto const osm_node_to_internal_nbn = [&](auto const osm_node)
{
auto internal = mapExternalToInternalNodeID(
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
if (internal == SPECIAL_NODEID)
@@ -994,8 +999,9 @@ void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuv
return internal;
};
const auto strings_to_turn_type_and_direction = [](const std::string &turn_string,
const std::string &direction_string) {
const auto strings_to_turn_type_and_direction =
[](const std::string &turn_string, const std::string &direction_string)
{
auto result = std::make_pair(guidance::TurnType::MaxTurnType,
guidance::DirectionModifier::MaxDirectionModifier);
@@ -1059,7 +1065,8 @@ void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuv
// Returns true on successful transformation, false in case of invalid references.
// Later, the UnresolvedManeuverOverride will be converted into a final ManeuverOverride
// once the edge-based-node IDs are generated by the edge-based-graph-factory
const auto transform = [&](const auto &external_type, auto &internal_type) {
const auto transform = [&](const auto &external_type, auto &internal_type)
{
if (external_type.turn_path.Type() == TurnPathType::VIA_WAY_TURN_PATH)
{
auto const &external = external_type.turn_path.AsViaWayPath();
@@ -1092,11 +1099,12 @@ void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuv
};
const auto transform_into_internal_types =
[&](const InputManeuverOverride &external_maneuver_override) {
UnresolvedManeuverOverride internal_maneuver_override;
if (transform(external_maneuver_override, internal_maneuver_override))
internal_maneuver_overrides.push_back(std::move(internal_maneuver_override));
};
[&](const InputManeuverOverride &external_maneuver_override)
{
UnresolvedManeuverOverride internal_maneuver_override;
if (transform(external_maneuver_override, internal_maneuver_override))
internal_maneuver_overrides.push_back(std::move(internal_maneuver_override));
};
// Transforming the overrides into the dedicated internal types
{
@@ -1124,7 +1132,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
// Enter invalid IDs into the map to indicate that we want to find out about
// nodes of these ways.
const auto mark_ids = [&](auto const &turn_restriction) {
const auto mark_ids = [&](auto const &turn_restriction)
{
NodesOfWay dummy_segment{MAX_OSM_WAYID, {MAX_OSM_NODEID, MAX_OSM_NODEID}};
const auto &turn_path = turn_restriction.turn_path;
restriction_ways[turn_path.From()] = dummy_segment;
@@ -1142,7 +1151,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
std::for_each(restrictions_list.begin(), restrictions_list.end(), mark_ids);
// Update the values for all ways already sporting SPECIAL_NODEID
const auto set_ids = [&](const size_t way_list_idx, auto const &way_id) {
const auto set_ids = [&](const size_t way_list_idx, auto const &way_id)
{
auto itr = restriction_ways.find(way_id);
if (itr != restriction_ways.end())
{
@@ -1178,7 +1188,8 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
std::unordered_set<OSMNodeID> bidirectional_signals;
const auto mark_signals = [&](auto const &traffic_signal) {
const auto mark_signals = [&](auto const &traffic_signal)
{
if (traffic_signal.second == TrafficLightClass::DIRECTION_FORWARD ||
traffic_signal.second == TrafficLightClass::DIRECTION_REVERSE)
{
@@ -1193,7 +1204,8 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
std::for_each(external_traffic_signals.begin(), external_traffic_signals.end(), mark_signals);
// Extract all the segments that lead up to unidirectional traffic signals.
const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) {
const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/)
{
const auto node_start_offset =
used_node_id_list.begin() + way_node_id_offsets[way_list_idx];
const auto node_end_offset =
@@ -1227,7 +1239,9 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments);
util::for_each_pair(
signal_segments, [](const auto pair_a, const auto pair_b) {
signal_segments,
[](const auto pair_a, const auto pair_b)
{
if (pair_a.first == pair_b.first)
{
// If a node is appearing multiple times in this map, then it's ambiguous.
@@ -1252,7 +1266,8 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways)
{
auto const to_internal = [&](auto const osm_node) {
auto const to_internal = [&](auto const osm_node)
{
auto internal = mapExternalToInternalNodeID(
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
if (internal == SPECIAL_NODEID)
@@ -1264,7 +1279,8 @@ void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction
// Transform an OSMRestriction (based on WayIDs) into an OSRM restriction (base on NodeIDs).
// Returns true on successful transformation, false in case of invalid references.
const auto transform = [&](const auto &external_type, auto &internal_type) {
const auto transform = [&](const auto &external_type, auto &internal_type)
{
if (external_type.turn_path.Type() == TurnPathType::VIA_WAY_TURN_PATH)
{
auto const &external = external_type.turn_path.AsViaWayPath();
@@ -1293,7 +1309,8 @@ void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction
return internal_type.Valid();
};
const auto transform_into_internal_types = [&](InputTurnRestriction &external_restriction) {
const auto transform_into_internal_types = [&](InputTurnRestriction &external_restriction)
{
TurnRestriction restriction;
if (transform(external_restriction, restriction))
{
+21 -11
View File
@@ -442,9 +442,12 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
ExtractionRelationContainer relations;
const auto buffer_reader = [](osmium::io::Reader &reader) {
const auto buffer_reader = [](osmium::io::Reader &reader)
{
return tbb::filter<void, SharedBuffer>(
tbb::filter_mode::serial_in_order, [&reader](tbb::flow_control &fc) {
tbb::filter_mode::serial_in_order,
[&reader](tbb::flow_control &fc)
{
if (auto buffer = reader.read())
{
return std::make_shared<osmium::memory::Buffer>(std::move(buffer));
@@ -466,7 +469,9 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
osmium_location_handler_type location_handler(location_cache);
tbb::filter<SharedBuffer, SharedBuffer> location_cacher(
tbb::filter_mode::serial_in_order, [&location_handler](SharedBuffer buffer) {
tbb::filter_mode::serial_in_order,
[&location_handler](SharedBuffer buffer)
{
osmium::apply(buffer->begin(), buffer->end(), location_handler);
return buffer;
});
@@ -475,7 +480,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
tbb::filter<SharedBuffer, ParsedBuffer> buffer_transformer(
tbb::filter_mode::parallel,
// NOLINTNEXTLINE(performance-unnecessary-value-param)
[&](const SharedBuffer buffer) {
[&](const SharedBuffer buffer)
{
ParsedBuffer parsed_buffer;
parsed_buffer.buffer = buffer;
scripting_environment.ProcessElements(*buffer,
@@ -495,7 +501,9 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
unsigned number_of_restrictions = 0;
unsigned number_of_maneuver_overrides = 0;
tbb::filter<ParsedBuffer, void> buffer_storage(
tbb::filter_mode::serial_in_order, [&](const ParsedBuffer &parsed_buffer) {
tbb::filter_mode::serial_in_order,
[&](const ParsedBuffer &parsed_buffer)
{
number_of_nodes += parsed_buffer.resulting_nodes.size();
// put parsed objects thru extractor callbacks
for (const auto &result : parsed_buffer.resulting_nodes)
@@ -524,7 +532,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
tbb::filter<SharedBuffer, std::shared_ptr<ExtractionRelationContainer>> buffer_relation_cache(
tbb::filter_mode::parallel,
// NOLINTNEXTLINE(performance-unnecessary-value-param)
[&](const SharedBuffer buffer) {
[&](const SharedBuffer buffer)
{
if (!buffer)
return std::shared_ptr<ExtractionRelationContainer>{};
@@ -562,7 +571,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
tbb::filter<std::shared_ptr<ExtractionRelationContainer>, void> buffer_storage_relation(
tbb::filter_mode::serial_in_order,
// NOLINTNEXTLINE(performance-unnecessary-value-param)
[&](const std::shared_ptr<ExtractionRelationContainer> parsed_relations) {
[&](const std::shared_ptr<ExtractionRelationContainer> parsed_relations)
{
number_of_relations += parsed_relations->GetRelationsNum();
relations.Merge(std::move(*parsed_relations));
});
@@ -749,7 +759,8 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
segregated_edges,
turn_lane_map);
const auto create_edge_based_edges = [&]() {
const auto create_edge_based_edges = [&]()
{
// scoped to release intermediate data structures right after the call
RestrictionMap unconditional_node_restriction_map(restriction_graph);
ConditionalRestrictionMap conditional_node_restriction_map(restriction_graph);
@@ -795,9 +806,8 @@ void Extractor::BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_seg
auto start_point_count = std::accumulate(edge_based_node_segments.begin(),
edge_based_node_segments.end(),
0,
[](const size_t so_far, const auto &segment) {
return so_far + (segment.is_startpoint ? 1 : 0);
});
[](const size_t so_far, const auto &segment)
{ return so_far + (segment.is_startpoint ? 1 : 0); });
if (start_point_count == 0)
{
throw util::exception("There are no snappable edges left after processing. Are you "
+60 -54
View File
@@ -140,7 +140,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
InternalExtractorEdge::WeightData forward_weight_data;
InternalExtractorEdge::WeightData backward_weight_data;
const auto toValueByEdgeOrByMeter = [&nodes](const double by_way, const double by_meter) {
const auto toValueByEdgeOrByMeter = [&nodes](const double by_way, const double by_meter)
{
using Value = detail::ByEdgeOrByMeterValue;
// get value by weight per edge
if (by_way >= 0)
@@ -194,7 +195,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
}
}
const auto classStringToMask = [this](const std::string &class_name) {
const auto classStringToMask = [this](const std::string &class_name)
{
auto iter = classes_map.find(class_name);
if (iter == classes_map.end())
{
@@ -212,7 +214,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
return iter->second;
}
};
const auto classesToMask = [&](const auto &classes) {
const auto classesToMask = [&](const auto &classes)
{
ClassData mask = 0;
for (const auto &name_and_flag : classes)
{
@@ -232,7 +235,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
const ClassData forward_classes = classesToMask(parsed_way.forward_classes);
const ClassData backward_classes = classesToMask(parsed_way.backward_classes);
const auto laneStringToDescription = [](const std::string &lane_string) -> TurnLaneDescription {
const auto laneStringToDescription = [](const std::string &lane_string) -> TurnLaneDescription
{
if (lane_string.empty())
return {};
@@ -332,7 +336,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
road_classification.SetNumberOfLanes(std::max(road_deduced_num_lanes, // len(turn:lanes)
road_classification.GetNumberOfLanes()));
const auto GetNameID = [this, &parsed_way](bool is_forward) -> NameID {
const auto GetNameID = [this, &parsed_way](bool is_forward) -> NameID
{
const std::string &ref = is_forward ? parsed_way.forward_ref : parsed_way.backward_ref;
// Get the unique identifier for the street name, destination, and ref
const auto name_iterator = string_map.find(MapKey(parsed_way.name,
@@ -418,30 +423,31 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
forward_classes,
parsed_way.forward_travel_mode,
parsed_way.is_left_hand_driving});
util::for_each_pair(
nodes, [&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node) {
NodeBasedEdgeWithOSM edge = {
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
{0}, // weight
{0}, // duration
{0}, // distance
{}, // geometry id
static_cast<AnnotationID>(annotation_data_id),
{true,
in_backward_direction && !split_edge,
split_edge,
parsed_way.roundabout,
parsed_way.circular,
parsed_way.is_startpoint,
parsed_way.forward_restricted,
road_classification,
parsed_way.highway_turn_classification,
parsed_way.access_turn_classification}};
util::for_each_pair(nodes,
[&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node)
{
NodeBasedEdgeWithOSM edge = {
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
{0}, // weight
{0}, // duration
{0}, // distance
{}, // geometry id
static_cast<AnnotationID>(annotation_data_id),
{true,
in_backward_direction && !split_edge,
split_edge,
parsed_way.roundabout,
parsed_way.circular,
parsed_way.is_startpoint,
parsed_way.forward_restricted,
road_classification,
parsed_way.highway_turn_classification,
parsed_way.access_turn_classification}};
external_memory.all_edges_list.push_back(
InternalExtractorEdge(edge, forward_weight_data, forward_duration_data, {}));
});
external_memory.all_edges_list.push_back(InternalExtractorEdge(
edge, forward_weight_data, forward_duration_data, {}));
});
}
if (in_backward_direction && (!in_forward_direction || split_edge))
@@ -452,38 +458,38 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
backward_classes,
parsed_way.backward_travel_mode,
parsed_way.is_left_hand_driving});
util::for_each_pair(
nodes, [&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node) {
NodeBasedEdgeWithOSM edge = {
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
{0}, // weight
{0}, // duration
{0}, // distance
{}, // geometry id
static_cast<AnnotationID>(annotation_data_id),
{false,
true,
split_edge,
parsed_way.roundabout,
parsed_way.circular,
parsed_way.is_startpoint,
parsed_way.backward_restricted,
road_classification,
parsed_way.highway_turn_classification,
parsed_way.access_turn_classification}};
util::for_each_pair(nodes,
[&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node)
{
NodeBasedEdgeWithOSM edge = {
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
{0}, // weight
{0}, // duration
{0}, // distance
{}, // geometry id
static_cast<AnnotationID>(annotation_data_id),
{false,
true,
split_edge,
parsed_way.roundabout,
parsed_way.circular,
parsed_way.is_startpoint,
parsed_way.backward_restricted,
road_classification,
parsed_way.highway_turn_classification,
parsed_way.access_turn_classification}};
external_memory.all_edges_list.push_back(
InternalExtractorEdge(edge, backward_weight_data, backward_duration_data, {}));
});
external_memory.all_edges_list.push_back(InternalExtractorEdge(
edge, backward_weight_data, backward_duration_data, {}));
});
}
std::transform(nodes.begin(),
nodes.end(),
std::back_inserter(external_memory.used_node_id_list),
[](const osmium::NodeRef &ref) {
return OSMNodeID{static_cast<std::uint64_t>(ref.ref())};
});
[](const osmium::NodeRef &ref)
{ return OSMNodeID{static_cast<std::uint64_t>(ref.ref())}; });
auto way_id = OSMWayID{static_cast<std::uint64_t>(input_way.id())};
external_memory.ways_list.push_back(way_id);
+21 -17
View File
@@ -37,7 +37,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
// restriction path.
std::unordered_set<NodeID> incompressible_via_nodes;
const auto remember_via_nodes = [&](const auto &restriction) {
const auto remember_via_nodes = [&](const auto &restriction)
{
if (restriction.turn_path.Type() == TurnPathType::VIA_NODE_TURN_PATH)
{
incompressible_via_nodes.insert(restriction.turn_path.AsViaNodePath().via);
@@ -186,16 +187,17 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
*/
const auto selectAnnotation =
[&node_data_container](const AnnotationID front_annotation,
const AnnotationID back_annotation) {
// A lane has tags: u - (front) - v - (back) - w
// During contraction, we keep only one of the tags. Usually the one closer
// to the intersection is preferred. If its empty, however, we keep the
// non-empty one
if (node_data_container[back_annotation].lane_description_id ==
INVALID_LANE_DESCRIPTIONID)
return front_annotation;
return back_annotation;
};
const AnnotationID back_annotation)
{
// A lane has tags: u - (front) - v - (back) - w
// During contraction, we keep only one of the tags. Usually the one closer
// to the intersection is preferred. If its empty, however, we keep the
// non-empty one
if (node_data_container[back_annotation].lane_description_id ==
INVALID_LANE_DESCRIPTIONID)
return front_annotation;
return back_annotation;
};
graph.GetEdgeData(forward_e1).annotation_data = selectAnnotation(
fwd_edge_data1.annotation_data, fwd_edge_data2.annotation_data);
@@ -250,10 +252,10 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
roads_on_the_left);
scripting_environment.ProcessTurn(extraction_turn);
auto update_direction_penalty = [&extraction_turn, weight_multiplier](
bool signal,
EdgeDuration &duration_penalty,
EdgeWeight &weight_penalty) {
auto update_direction_penalty =
[&extraction_turn, weight_multiplier](
bool signal, EdgeDuration &duration_penalty, EdgeWeight &weight_penalty)
{
if (signal)
{
duration_penalty = to_alias<EdgeDuration>(extraction_turn.duration *
@@ -303,7 +305,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
auto apply_e2_to_e1 = [&graph](EdgeID edge1,
EdgeID edge2,
EdgeWeight &weight_penalty,
EdgeDuration &duration_penalty) {
EdgeDuration &duration_penalty)
{
auto &edge1_data = graph.GetEdgeData(edge1);
const auto &edge2_data = graph.GetEdgeData(edge2);
edge1_data.weight += edge2_data.weight;
@@ -345,7 +348,8 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
// Set a dummy empty penalty weight if opposite value exists.
auto set_dummy_penalty = [](EdgeWeight &weight_penalty,
EdgeDuration &duration_penalty,
EdgeWeight &other_weight_penalty) {
EdgeWeight &other_weight_penalty)
{
if (weight_penalty == INVALID_EDGE_WEIGHT &&
other_weight_penalty != INVALID_EDGE_WEIGHT)
{
@@ -88,9 +88,8 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
std::vector<util::Coordinate> coordinates) const
{
// check if the coordinate is equal to the interseciton coordinate
const auto not_same_as_start = [&](const util::Coordinate coordinate) {
return node_coordinates[traversed_in_reverse ? to_node : intersection_node] != coordinate;
};
const auto not_same_as_start = [&](const util::Coordinate coordinate)
{ return node_coordinates[traversed_in_reverse ? to_node : intersection_node] != coordinate; };
// this is only used for debug purposes in assertions. We don't want warnings about it
(void)not_same_as_start;
@@ -176,7 +175,8 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
* information on the very first turn angle (requires knowledge about previous road) and the
* respective lane widths.
*/
const bool first_coordinate_is_far_away = [&first_distance, considered_lanes]() {
const bool first_coordinate_is_far_away = [&first_distance, considered_lanes]()
{
const auto required_distance =
considered_lanes * ASSUMED_LANE_WIDTH + LOOKAHEAD_DISTANCE_WITHOUT_LANES;
return first_distance > required_distance;
@@ -256,7 +256,8 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
* possible negative:
* http://www.openstreetmap.org/search?query=52.514503%2013.32252#map=19/52.51450/13.32252
*/
const auto straight_distance_and_index = [&]() {
const auto straight_distance_and_index = [&]()
{
auto straight_distance = segment_distances[1];
std::size_t index;
@@ -276,7 +277,8 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
const auto straight_distance = straight_distance_and_index.second;
const auto straight_index = straight_distance_and_index.first;
const bool starts_of_without_turn = [&]() {
const bool starts_of_without_turn = [&]()
{
return straight_distance >=
considered_lanes * ASSUMED_LANE_WIDTH + LOOKAHEAD_DISTANCE_WITHOUT_LANES;
}();
@@ -435,7 +437,8 @@ CoordinateExtractor::ExtractCoordinateAtLength(const double distance,
auto length_cache_itr = length_cache.begin() + 1;
// find the end of the segment containing the coordinate which is at least distance away
const auto find_coordinate_at_distance = [distance, &accumulated_distance, &length_cache_itr](
const util::Coordinate /*coordinate*/) mutable {
const util::Coordinate /*coordinate*/) mutable
{
const auto result = (accumulated_distance + *length_cache_itr) >= distance;
if (!result)
{
@@ -468,18 +471,19 @@ util::Coordinate CoordinateExtractor::ExtractCoordinateAtLength(
// checks (via its state) for an accumulated distance
const auto coordinate_at_distance =
[distance, &accumulated_distance, last_coordinate = coordinates.front()](
const util::Coordinate coordinate) mutable {
const double segment_distance =
util::coordinate_calculation::greatCircleDistance(last_coordinate, coordinate);
const auto result = (accumulated_distance + segment_distance) >= distance;
if (!result)
{
accumulated_distance += segment_distance;
last_coordinate = coordinate;
}
const util::Coordinate coordinate) mutable
{
const double segment_distance =
util::coordinate_calculation::greatCircleDistance(last_coordinate, coordinate);
const auto result = (accumulated_distance + segment_distance) >= distance;
if (!result)
{
accumulated_distance += segment_distance;
last_coordinate = coordinate;
}
return result;
};
return result;
};
// find the begin of the segment containing the coordinate
const auto coordinate_after =
@@ -514,9 +518,8 @@ util::Coordinate CoordinateExtractor::GetCoordinateCloseToTurn(const NodeID from
// the compressed edges contain node ids, we transfer them to coordinates accessing the
// node_coordinates array
const auto compressedGeometryToCoordinate =
[this](const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge) {
return node_coordinates[compressed_edge.node_id];
};
[this](const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge)
{ return node_coordinates[compressed_edge.node_id]; };
// return the first coordinate that is reasonably far away from the start node
const util::Coordinate start_coordinate = node_coordinates[start_node];
@@ -526,10 +529,11 @@ util::Coordinate CoordinateExtractor::GetCoordinateCloseToTurn(const NodeID from
// away from the first entry
const auto far_enough_away =
[start_coordinate, compressedGeometryToCoordinate](
const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge) {
return util::coordinate_calculation::greatCircleDistance(
compressedGeometryToCoordinate(compressed_edge), start_coordinate) > 1;
};
const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge)
{
return util::coordinate_calculation::greatCircleDistance(
compressedGeometryToCoordinate(compressed_edge), start_coordinate) > 1;
};
// find the first coordinate, that is at least unequal to the begin of the edge
if (traversed_in_reverse)
@@ -614,7 +618,8 @@ CoordinateExtractor::GetMaxDeviation(std::vector<util::Coordinate>::const_iterat
const util::Coordinate straight_end) const
{
// compute the deviation of a single coordinate from a straight line
auto get_single_deviation = [&](const util::Coordinate coordinate) {
auto get_single_deviation = [&](const util::Coordinate coordinate)
{
// find the projected coordinate
auto coord_between = util::coordinate_calculation::projectPointOnSegment(
straight_begin, straight_end, coordinate)
@@ -626,10 +631,11 @@ CoordinateExtractor::GetMaxDeviation(std::vector<util::Coordinate>::const_iterat
// note: we don't accumulate here but rather compute the maximum. The functor passed here is not
// summing up anything.
return std::accumulate(
range_begin, range_end, 0.0, [&](const double current, const util::Coordinate coordinate) {
return std::max(current, get_single_deviation(coordinate));
});
return std::accumulate(range_begin,
range_end,
0.0,
[&](const double current, const util::Coordinate coordinate)
{ return std::max(current, get_single_deviation(coordinate)); });
}
bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinates,
@@ -645,7 +651,8 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
return true;
// TODO we might have to fix this to better compensate for errors due to repeated coordinates
const bool takes_an_actual_turn = [&coordinates]() {
const bool takes_an_actual_turn = [&coordinates]()
{
const auto begin_bearing =
util::coordinate_calculation::bearing(coordinates[0], coordinates[1]);
const auto end_bearing = util::coordinate_calculation::bearing(
@@ -660,7 +667,8 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
const auto get_deviation = [](const util::Coordinate line_start,
const util::Coordinate line_end,
const util::Coordinate point) {
const util::Coordinate point)
{
// find the projected coordinate
auto coord_between =
util::coordinate_calculation::projectPointOnSegment(line_start, line_end, point).second;
@@ -669,19 +677,22 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
};
// a curve needs to be on one side of the coordinate array
const bool all_same_side = [&]() {
const bool all_same_side = [&]()
{
if (coordinates.size() <= 3)
return true;
const bool ccw = util::coordinate_calculation::isCCW(
coordinates.front(), coordinates.back(), coordinates[1]);
return std::all_of(
coordinates.begin() + 2, coordinates.end() - 1, [&](const util::Coordinate coordinate) {
const bool compare_ccw = util::coordinate_calculation::isCCW(
coordinates.front(), coordinates.back(), coordinate);
return ccw == compare_ccw;
});
return std::all_of(coordinates.begin() + 2,
coordinates.end() - 1,
[&](const util::Coordinate coordinate)
{
const bool compare_ccw = util::coordinate_calculation::isCCW(
coordinates.front(), coordinates.back(), coordinate);
return ccw == compare_ccw;
});
}();
if (!all_same_side)
@@ -694,13 +705,16 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
double maximum_deviation = 0;
std::tie(has_up_down_deviation, maximum_deviation_index, maximum_deviation) =
[&coordinates, get_deviation]() -> std::tuple<bool, std::size_t, double> {
const auto increasing = [&](const util::Coordinate lhs, const util::Coordinate rhs) {
[&coordinates, get_deviation]() -> std::tuple<bool, std::size_t, double>
{
const auto increasing = [&](const util::Coordinate lhs, const util::Coordinate rhs)
{
return get_deviation(coordinates.front(), coordinates.back(), lhs) <
get_deviation(coordinates.front(), coordinates.back(), rhs);
};
const auto decreasing = [&](const util::Coordinate lhs, const util::Coordinate rhs) {
const auto decreasing = [&](const util::Coordinate lhs, const util::Coordinate rhs)
{
return get_deviation(coordinates.front(), coordinates.back(), lhs) >
get_deviation(coordinates.front(), coordinates.back(), rhs);
};
@@ -744,7 +758,8 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
BOOST_ASSERT(coordinates.size() >= 3);
// Compute all turn angles along the road
const auto turn_angles = [coordinates]() {
const auto turn_angles = [coordinates]()
{
std::vector<double> turn_angles;
turn_angles.reserve(coordinates.size() - 2);
for (std::size_t index = 0; index + 2 < coordinates.size(); ++index)
@@ -755,10 +770,9 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
return turn_angles;
}();
const bool curve_is_valid = [&turn_angles,
&segment_distances,
&segment_length,
&considered_lane_width]() {
const bool curve_is_valid =
[&turn_angles, &segment_distances, &segment_length, &considered_lane_width]()
{
// internal state for our lamdae
bool last_was_straight = false;
// a turn angle represents two segments between three coordinates. We initialize the
@@ -769,8 +783,9 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
// every call to the lamda requires a call to the distances. They need to be aligned
BOOST_ASSERT(segment_distances.size() == turn_angles.size() + 2);
const auto detect_invalid_curve = [&](const double previous_angle,
const double current_angle) {
const auto detect_invalid_curve =
[&](const double previous_angle, const double current_angle)
{
const auto both_actually_turn =
(util::angularDeviation(previous_angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE) &&
(util::angularDeviation(current_angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE);
@@ -822,7 +837,8 @@ bool CoordinateExtractor::IsDirectOffset(const std::vector<util::Coordinate> &co
const std::uint8_t considered_lanes) const
{
// check if a given length is with half a lane of the assumed lane offset
const auto IsCloseToLaneDistance = [considered_lanes](const double width) {
const auto IsCloseToLaneDistance = [considered_lanes](const double width)
{
// a road usually is connected to the middle of the lanes. So the lane-offset has to
// consider half to road
const auto lane_offset = 0.5 * considered_lanes * ASSUMED_LANE_WIDTH;
@@ -856,7 +872,8 @@ bool CoordinateExtractor::IsDirectOffset(const std::vector<util::Coordinate> &co
const auto segment_offset_past_thirty_meters =
std::find_if(segment_distances.begin() + offset_index,
segment_distances.end(),
[accumulated_distance = 0.](const auto value) mutable {
[accumulated_distance = 0.](const auto value) mutable
{
accumulated_distance += value;
return value >= 30;
});
@@ -888,20 +905,21 @@ CoordinateExtractor::PrepareLengthCache(const std::vector<util::Coordinate> &coo
// sentinel
// NOLINTNEXTLINE(bugprone-unused-return-value)
// We're only interested in the side effect of the lambda, not the return value
[[maybe_unused]] auto _ = std::find_if(
std::next(std::begin(coordinates)),
std::end(coordinates),
[last_coordinate = coordinates.front(),
limit,
&segment_distances,
accumulated_distance = 0.](const util::Coordinate current_coordinate) mutable {
const auto distance = util::coordinate_calculation::greatCircleDistance(
last_coordinate, current_coordinate);
accumulated_distance += distance;
last_coordinate = current_coordinate;
segment_distances.push_back(distance);
return accumulated_distance >= limit;
});
[[maybe_unused]] auto _ =
std::find_if(std::next(std::begin(coordinates)),
std::end(coordinates),
[last_coordinate = coordinates.front(),
limit,
&segment_distances,
accumulated_distance = 0.](const util::Coordinate current_coordinate) mutable
{
const auto distance = util::coordinate_calculation::greatCircleDistance(
last_coordinate, current_coordinate);
accumulated_distance += distance;
last_coordinate = current_coordinate;
segment_distances.push_back(distance);
return accumulated_distance >= limit;
});
return segment_distances;
}
@@ -916,19 +934,18 @@ CoordinateExtractor::TrimCoordinatesToLength(std::vector<util::Coordinate> coord
double distance_to_current_coordinate = 0;
std::size_t coordinate_index = 0;
const auto compute_length =
[&coordinate_index, &distance_to_current_coordinate, &coordinates]() {
const auto new_distance =
distance_to_current_coordinate +
util::coordinate_calculation::greatCircleDistance(coordinates[coordinate_index - 1],
coordinates[coordinate_index]);
return new_distance;
};
const auto read_length_from_cache = [&length_cache, &coordinate_index]() {
return length_cache[coordinate_index];
const auto compute_length = [&coordinate_index, &distance_to_current_coordinate, &coordinates]()
{
const auto new_distance =
distance_to_current_coordinate +
util::coordinate_calculation::greatCircleDistance(coordinates[coordinate_index - 1],
coordinates[coordinate_index]);
return new_distance;
};
const auto read_length_from_cache = [&length_cache, &coordinate_index]()
{ return length_cache[coordinate_index]; };
bool use_cache = !length_cache.empty();
if (use_cache && length_cache.back() < desired_length && coordinates.size() >= 2)
@@ -1044,8 +1061,9 @@ CoordinateExtractor::SampleCoordinates(const std::vector<util::Coordinate> &coor
double carry_length = 0., total_length = 0.;
// interpolate coordinates as long as we are not past the desired length
const auto add_samples_until_length_limit = [&](const util::Coordinate previous_coordinate,
const util::Coordinate current_coordinate) {
const auto add_samples_until_length_limit =
[&](const util::Coordinate previous_coordinate, const util::Coordinate current_coordinate)
{
// pretend to have found an element and stop the sampling
if (total_length > max_sample_length)
return true;
@@ -67,9 +67,8 @@ getEdgeCoordinates(const extractor::CompressedEdgeContainer &compressed_geometri
std::transform(geometry.begin(),
geometry.end(),
std::back_inserter(result),
[&node_coordinates](const auto &compressed_edge) {
return node_coordinates[compressed_edge.node_id];
});
[&node_coordinates](const auto &compressed_edge)
{ return node_coordinates[compressed_edge.node_id]; });
// filter duplicated coordinates
result.erase(std::unique(result.begin(), result.end()), result.end());
@@ -95,7 +94,8 @@ double findClosestOppositeBearing(const IntersectionEdgeGeometries &edge_geometr
const auto min = std::min_element(
edge_geometries.begin(),
edge_geometries.end(),
[bearing = util::bearing::reverse(bearing)](const auto &lhs, const auto &rhs) {
[bearing = util::bearing::reverse(bearing)](const auto &lhs, const auto &rhs)
{
return util::angularDeviation(lhs.perceived_bearing, bearing) <
util::angularDeviation(rhs.perceived_bearing, bearing);
});
@@ -128,7 +128,7 @@ std::pair<bool, double> findMergedBearing(const util::NodeBasedDynamicGraph &gra
{
// In some intersections, turning roads can introduce artificial turns if we merge here.
// Consider a scenario like:
// 
//  
// a . g - f
// | .
// | .
@@ -136,7 +136,7 @@ std::pair<bool, double> findMergedBearing(const util::NodeBasedDynamicGraph &gra
// d-b--------e
// |
// c
// 
//  
// Merging `bgf` and `be` would introduce an angle, even though d-b-e is perfectly straight
// We don't change the angle, if such an opposite road exists
return {false, entry.perceived_bearing};
@@ -239,9 +239,10 @@ getIntersectionOutgoingGeometries(const util::NodeBasedDynamicGraph &graph,
}
// Sort edges in the clockwise bearings order
std::sort(edge_geometries.begin(), edge_geometries.end(), [](const auto &lhs, const auto &rhs) {
return lhs.perceived_bearing < rhs.perceived_bearing;
});
std::sort(edge_geometries.begin(),
edge_geometries.end(),
[](const auto &lhs, const auto &rhs)
{ return lhs.perceived_bearing < rhs.perceived_bearing; });
return edge_geometries;
}
} // namespace
@@ -317,9 +318,8 @@ getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,
neighbor_geometries.begin(),
std::find_if(neighbor_geometries.begin(),
neighbor_geometries.end(),
[&graph, &intersection_node](const auto &road) {
return graph.GetTarget(road.eid) == intersection_node;
}));
[&graph, &intersection_node](const auto &road)
{ return graph.GetTarget(road.eid) == intersection_node; }));
BOOST_ASSERT(static_cast<std::size_t>(neighbor_curr) != neighbor_geometries.size());
const auto neighbor_prev = (neighbor_curr + neighbor_edges - 1) % neighbor_edges;
const auto neighbor_next = (neighbor_curr + 1) % neighbor_edges;
@@ -403,10 +403,11 @@ getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,
inline auto findEdge(const IntersectionEdgeGeometries &geometries, const EdgeID &edge)
{
const auto it = std::lower_bound(
geometries.begin(), geometries.end(), edge, [](const auto &geometry, const auto edge) {
return geometry.eid < edge;
});
const auto it =
std::lower_bound(geometries.begin(),
geometries.end(),
edge,
[](const auto &geometry, const auto edge) { return geometry.eid < edge; });
BOOST_ASSERT(it != geometries.end() && it->eid == edge);
return it;
}
@@ -425,9 +426,10 @@ template <typename RestrictionsRange>
bool isTurnRestricted(const RestrictionsRange &restrictions, const NodeID to)
{
// Check if any of the restrictions would prevent a turn to 'to'
return std::any_of(restrictions.begin(), restrictions.end(), [&to](const auto &restriction) {
return restriction->IsTurnRestricted(to);
});
return std::any_of(restrictions.begin(),
restrictions.end(),
[&to](const auto &restriction)
{ return restriction->IsTurnRestricted(to); });
}
bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph,
@@ -614,9 +616,8 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
IntersectionViewData uturn{{SPECIAL_EDGEID, 0., 0., 0.}, false, 0.};
std::size_t allowed_uturns_number = 0;
const auto is_uturn = [](const auto angle) {
return std::fabs(angle) < std::numeric_limits<double>::epsilon();
};
const auto is_uturn = [](const auto angle)
{ return std::fabs(angle) < std::numeric_limits<double>::epsilon(); };
for (const auto &outgoing_edge : outgoing_edges)
{
@@ -665,9 +666,9 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
// 2) use turn angle if the smallest arc between turn and initial angles passes 0°
const auto use_turn_angle = (turn_angle > 270 && initial_angle < 90) ||
(turn_angle < 90 && initial_angle > 270);
const auto adjusted_angle = is_uturn(initial_angle)
? (turn_angle > 180. ? 360. : 0.)
: use_turn_angle ? turn_angle : initial_angle;
const auto adjusted_angle = is_uturn(initial_angle) ? (turn_angle > 180. ? 360. : 0.)
: use_turn_angle ? turn_angle
: initial_angle;
pre_intersection_view.push_back({road, adjusted_angle});
}
}
@@ -680,12 +681,11 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
}
// Order roads in counter-clockwise order starting from the U-turn edge in the OSM order
std::stable_sort(pre_intersection_view.begin(),
pre_intersection_view.end(),
[](const auto &lhs, const auto &rhs) {
return std::tie(lhs.second, lhs.first.angle) <
std::tie(rhs.second, rhs.first.angle);
});
std::stable_sort(
pre_intersection_view.begin(),
pre_intersection_view.end(),
[](const auto &lhs, const auto &rhs)
{ return std::tie(lhs.second, lhs.first.angle) < std::tie(rhs.second, rhs.first.angle); });
// Adjust perceived bearings to keep the initial OSM order with respect to the first edge
for (auto curr = pre_intersection_view.begin(), next = std::next(curr);
@@ -706,9 +706,8 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
auto no_uturn = std::none_of(pre_intersection_view.begin(),
pre_intersection_view.end(),
[&is_uturn](const IntersectionViewDataWithAngle &road) {
return is_uturn(road.first.angle);
});
[&is_uturn](const IntersectionViewDataWithAngle &road)
{ return is_uturn(road.first.angle); });
// After all of this, if we now don't have a u-turn, let's add one to the intersection.
// This is a hack to fix the triggered assertion ( see:
// https://github.com/Project-OSRM/osrm-backend/issues/6218 ). Ideally we would fix this more
@@ -27,7 +27,8 @@ inline auto makeCheckRoadForName(const NameID name_id,
const SuffixTable &suffix_table)
{
return [name_id, &node_based_graph, &node_data_container, &name_table, &suffix_table](
const MergableRoadDetector::MergableRoadData &road) {
const MergableRoadDetector::MergableRoadData &road)
{
// since we filter here, we don't want any other name than the one we are looking for
const auto road_name_id =
node_data_container
@@ -89,9 +90,8 @@ bool MergableRoadDetector::CanMergeRoad(const NodeID intersection_node,
* / -- \
* a ---- b - - /
*/
const auto road_target = [this](const MergableRoadData &road) {
return node_based_graph.GetTarget(road.eid);
};
const auto road_target = [this](const MergableRoadData &road)
{ return node_based_graph.GetTarget(road.eid); };
// TODO might have to skip over trivial intersections
if (road_target(lhs) == intersection_node || road_target(rhs) == intersection_node)
@@ -262,7 +262,8 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
if (angularDeviation(connector_turn->angle, ORTHOGONAL_ANGLE) > NARROW_TURN_ANGLE)
return false;
const auto num_lanes = [this](const MergableRoadData &road) {
const auto num_lanes = [this](const MergableRoadData &road)
{
return std::max<std::uint8_t>(
node_based_graph.GetEdgeData(road.eid).flags.road_classification.GetNumberOfLanes(), 1);
};
@@ -308,7 +309,8 @@ bool MergableRoadDetector::IsCircularShape(const NodeID intersection_node,
node_restriction_map,
barrier_nodes,
turn_lanes_data);
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) {
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length)
{
LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length);
SelectStraightmostRoadByNameAndOnlyChoice selector(
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(edge_id).annotation_data)
@@ -380,7 +382,8 @@ bool MergableRoadDetector::HaveSameDirection(const NodeID intersection_node,
node_restriction_map,
barrier_nodes,
turn_lanes_data);
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) {
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length)
{
LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length);
SelectStraightmostRoadByNameAndOnlyChoice selector(
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(edge_id).annotation_data)
@@ -424,7 +427,8 @@ bool MergableRoadDetector::HaveSameDirection(const NodeID intersection_node,
/* extract the number of lanes for a road
* restricts a vector to the last two thirds of the length
*/
const auto prune = [](auto &data_vector) {
const auto prune = [](auto &data_vector)
{
BOOST_ASSERT(data_vector.size() >= 3);
// erase the first third of the vector
data_vector.erase(data_vector.begin(), data_vector.begin() + data_vector.size() / 3);
@@ -493,7 +497,8 @@ bool MergableRoadDetector::IsTrafficIsland(const NodeID intersection_node,
return false;
// check if all entries at the destination or at the source are the same
const auto all_same_name_and_degree_three = [this](const NodeID nid) {
const auto all_same_name_and_degree_three = [this](const NodeID nid)
{
// check if the intersection found has degree three
if (node_based_graph.GetOutDegree(nid) != 3)
return false;
@@ -505,7 +510,8 @@ bool MergableRoadDetector::IsTrafficIsland(const NodeID intersection_node,
.GetAnnotation(node_based_graph.GetEdgeData(range.front()).annotation_data)
.name_id;
const auto has_required_name = [this, required_name_id](const auto edge_id) {
const auto has_required_name = [this, required_name_id](const auto edge_id)
{
const auto road_name_id =
node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(edge_id).annotation_data)
@@ -562,7 +568,8 @@ bool MergableRoadDetector::IsLinkRoad(const NodeID intersection_node,
barrier_nodes,
turn_lanes_data,
next_intersection_parameters);
const auto extract_name_id = [this](const MergableRoadData &road) {
const auto extract_name_id = [this](const MergableRoadData &road)
{
return node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
.name_id;
@@ -74,10 +74,12 @@ boost::optional<EdgeID> SelectRoadByNameOnlyChoiceAndStraightness::operator()(
const EdgeBasedNodeDataContainer &node_data_container) const
{
BOOST_ASSERT(!intersection.empty());
const auto comparator = [&](const IntersectionViewData &lhs, const IntersectionViewData &rhs) {
const auto comparator = [&](const IntersectionViewData &lhs, const IntersectionViewData &rhs)
{
// the score of an elemnt results in an ranking preferring valid entries, if required over
// invalid requested name_ids over non-requested narrow deviations over non-narrow
const auto score = [&](const IntersectionViewData &road) {
const auto score = [&](const IntersectionViewData &road)
{
double result_score = 0;
// since angular deviation is limited by 0-180, we add 360 for invalid
if (requires_entry && !road.entry_allowed)
@@ -127,10 +129,12 @@ boost::optional<EdgeID> SelectStraightmostRoadByNameAndOnlyChoice::operator()(
if (intersection.size() == 1)
return {};
const auto comparator = [&](const IntersectionViewData &lhs, const IntersectionViewData &rhs) {
const auto comparator = [&](const IntersectionViewData &lhs, const IntersectionViewData &rhs)
{
// the score of an elemnt results in an ranking preferring valid entries, if required over
// invalid requested name_ids over non-requested narrow deviations over non-narrow
const auto score = [&](const IntersectionViewData &road) {
const auto score = [&](const IntersectionViewData &road)
{
double result_score = 0;
// since angular deviation is limited by 0-180, we add 360 for invalid
if (requires_entry && !road.entry_allowed)
@@ -149,8 +153,11 @@ boost::optional<EdgeID> SelectStraightmostRoadByNameAndOnlyChoice::operator()(
return score(lhs) < score(rhs);
};
const auto count_desired_name =
std::count_if(std::begin(intersection), std::end(intersection), [&](const auto &road) {
const auto count_desired_name = std::count_if(
std::begin(intersection),
std::end(intersection),
[&](const auto &road)
{
return node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
.name_id == desired_name_id;
+59 -50
View File
@@ -65,7 +65,8 @@ void LocationDependentData::loadLocationDependentData(
const auto &features_array = geojson["features"].GetArray();
auto convert_value = [](const auto &property) -> property_t {
auto convert_value = [](const auto &property) -> property_t
{
if (property.IsString())
return std::string(property.GetString());
if (property.IsNumber())
@@ -75,7 +76,8 @@ void LocationDependentData::loadLocationDependentData(
return {};
};
auto collect_properties = [this, &convert_value](const auto &object) -> std::size_t {
auto collect_properties = [this, &convert_value](const auto &object) -> std::size_t
{
properties_t object_properties;
for (const auto &property : object)
{
@@ -86,18 +88,21 @@ void LocationDependentData::loadLocationDependentData(
return index;
};
auto index_polygon = [this, &bounding_boxes](const auto &rings, auto properties_index) {
auto index_polygon = [this, &bounding_boxes](const auto &rings, auto properties_index)
{
// At least an outer ring in polygon https://tools.ietf.org/html/rfc7946#section-3.1.6
BOOST_ASSERT(rings.Size() > 0);
auto to_point = [](const auto &json) -> point_t {
auto to_point = [](const auto &json) -> point_t
{
util::validateCoordinate(json);
const auto &coords = json.GetArray();
return {coords[0].GetDouble(), coords[1].GetDouble()};
};
std::vector<segment_t> segments;
auto append_ring_segments = [&segments, &to_point](const auto &coordinates_array) -> box_t {
auto append_ring_segments = [&segments, &to_point](const auto &coordinates_array) -> box_t
{
using coord_t = boost::geometry::traits::coordinate_type<point_t>::type;
auto x_min = std::numeric_limits<coord_t>::max();
auto y_min = std::numeric_limits<coord_t>::max();
@@ -208,68 +213,72 @@ LocationDependentData::FindByKey(const std::vector<std::size_t> &property_indexe
std::vector<std::size_t> LocationDependentData::GetPropertyIndexes(const point_t &point) const
{
std::vector<std::size_t> result;
auto inserter = [this, &result](const rtree_t::value_type &rtree_entry) {
auto inserter = [this, &result](const rtree_t::value_type &rtree_entry)
{
const auto properties_index = polygons[rtree_entry.second].second;
result.push_back(properties_index);
};
// Search the R-tree and collect a Lua table of tags that correspond to the location
rtree.query(boost::geometry::index::intersects(point) &&
boost::geometry::index::satisfies([this, &point](const rtree_t::value_type &v) {
// Simple point-in-polygon algorithm adapted from
// https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
rtree.query(
boost::geometry::index::intersects(point) &&
boost::geometry::index::satisfies(
[this, &point](const rtree_t::value_type &v)
{
// Simple point-in-polygon algorithm adapted from
// https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
const auto &envelop = v.first;
const auto &bands = polygons[v.second].first;
const auto &envelop = v.first;
const auto &bands = polygons[v.second].first;
const auto y_min = envelop.min_corner().y();
const auto y_max = envelop.max_corner().y();
const auto dy = (y_max - y_min) / bands.size();
const auto y_min = envelop.min_corner().y();
const auto y_max = envelop.max_corner().y();
const auto dy = (y_max - y_min) / bands.size();
std::size_t band = (point.y() - y_min) / dy;
if (band >= bands.size())
{
band = bands.size() - 1;
std::size_t band = (point.y() - y_min) / dy;
if (band >= bands.size())
{
band = bands.size() - 1;
}
bool inside = false;
for (const auto &segment : bands[band])
{
const auto point_x = point.x(), point_y = point.y();
const auto from_x = segment.first.x(), from_y = segment.first.y();
const auto to_x = segment.second.x(), to_y = segment.second.y();
if (to_y == from_y)
{ // handle horizontal segments: check if on boundary or skip
if ((to_y == point_y) &&
(from_x == point_x || (to_x > point_x) != (from_x > point_x)))
return true;
continue;
}
bool inside = false;
for (const auto &segment : bands[band])
if ((to_y > point_y) != (from_y > point_y))
{
const auto point_x = point.x(), point_y = point.y();
const auto from_x = segment.first.x(), from_y = segment.first.y();
const auto to_x = segment.second.x(), to_y = segment.second.y();
const auto ax = to_x - from_x;
const auto ay = to_y - from_y;
const auto tx = point_x - from_x;
const auto ty = point_y - from_y;
if (to_y == from_y)
{ // handle horizontal segments: check if on boundary or skip
if ((to_y == point_y) &&
(from_x == point_x || (to_x > point_x) != (from_x > point_x)))
return true;
continue;
}
const auto cross_product = tx * ay - ax * ty;
if ((to_y > point_y) != (from_y > point_y))
if (cross_product == 0)
return true;
if ((ay > 0) == (cross_product > 0))
{
const auto ax = to_x - from_x;
const auto ay = to_y - from_y;
const auto tx = point_x - from_x;
const auto ty = point_y - from_y;
const auto cross_product = tx * ay - ax * ty;
if (cross_product == 0)
return true;
if ((ay > 0) == (cross_product > 0))
{
inside = !inside;
}
inside = !inside;
}
}
}
return inside;
}),
boost::make_function_output_iterator(std::ref(inserter)));
return inside;
}),
boost::make_function_output_iterator(std::ref(inserter)));
return result;
}
+28 -22
View File
@@ -46,27 +46,31 @@ void NodeBasedGraphFactory::BuildCompressedOutputGraph(const std::vector<NodeBas
util::NodeBasedDynamicGraphFromEdges(number_of_node_based_nodes, edge_list);
// check whether the graph is sane
BOOST_ASSERT([this]() {
for (const auto nbg_node_u : util::irange(0u, compressed_output_graph.GetNumberOfNodes()))
BOOST_ASSERT(
[this]()
{
for (EdgeID nbg_edge_id : compressed_output_graph.GetAdjacentEdgeRange(nbg_node_u))
for (const auto nbg_node_u :
util::irange(0u, compressed_output_graph.GetNumberOfNodes()))
{
// we cannot have invalid edge-ids in the graph
if (nbg_edge_id == SPECIAL_EDGEID)
return false;
for (EdgeID nbg_edge_id : compressed_output_graph.GetAdjacentEdgeRange(nbg_node_u))
{
// we cannot have invalid edge-ids in the graph
if (nbg_edge_id == SPECIAL_EDGEID)
return false;
const auto nbg_node_v = compressed_output_graph.GetTarget(nbg_edge_id);
const auto nbg_node_v = compressed_output_graph.GetTarget(nbg_edge_id);
auto reverse = compressed_output_graph.FindEdge(nbg_node_v, nbg_node_u);
auto reverse = compressed_output_graph.FindEdge(nbg_node_v, nbg_node_u);
// found an edge that is reversed in both directions, should be two distinct edges
if (compressed_output_graph.GetEdgeData(nbg_edge_id).reversed &&
compressed_output_graph.GetEdgeData(reverse).reversed)
return false;
// found an edge that is reversed in both directions, should be two distinct
// edges
if (compressed_output_graph.GetEdgeData(nbg_edge_id).reversed &&
compressed_output_graph.GetEdgeData(reverse).reversed)
return false;
}
}
}
return true;
}());
return true;
}());
}
void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment,
@@ -208,13 +212,15 @@ void NodeBasedGraphFactory::CompressAnnotationData()
}
// remove unreferenced entries, shifting other entries to the front
const auto new_end =
std::remove_if(annotation_data.begin(), annotation_data.end(), [&](auto const &data) {
// both elements are considered equal (to remove the second
// one) if the annotation mapping of the second one is
// invalid
return data.name_id == INVALID_NAMEID;
});
const auto new_end = std::remove_if(annotation_data.begin(),
annotation_data.end(),
[&](auto const &data)
{
// both elements are considered equal (to remove the
// second one) if the annotation mapping of the second
// one is invalid
return data.name_id == INVALID_NAMEID;
});
const auto old_size = annotation_data.size();
// remove all remaining elements
+23 -17
View File
@@ -123,9 +123,10 @@ struct transferBuilder
for (const auto &suffix_node : suffix_nodes)
{
const auto &edges = rg.GetEdges(suffix_node);
const auto edge_it = std::find_if(edges.begin(), edges.end(), [&to](const auto &edge) {
return edge.node_based_to == to && !edge.is_transfer;
});
const auto edge_it = std::find_if(
edges.begin(),
edges.end(),
[&to](const auto &edge) { return edge.node_based_to == to && !edge.is_transfer; });
if (edge_it != edges.end())
{
*(new_suffix_it++) = edge_it->target;
@@ -154,18 +155,22 @@ struct transferBuilder
// the transfer
const auto &restrictions = rg.GetRestrictions(cur_node);
const auto is_restricted =
std::any_of(restrictions.begin(), restrictions.end(), [&](const auto &restriction) {
return restriction->IsTurnRestricted(suffix_edge.node_based_to) &&
restriction->IsUnconditional();
});
std::any_of(restrictions.begin(),
restrictions.end(),
[&](const auto &restriction)
{
return restriction->IsTurnRestricted(suffix_edge.node_based_to) &&
restriction->IsUnconditional();
});
if (is_restricted)
continue;
const auto &edges = rg.GetEdges(cur_node);
// Check that the suffix edge is not a next edge along the current path.
const auto can_transfer = std::none_of(edges.begin(), edges.end(), [&](auto &edge) {
return edge.node_based_to == suffix_edge.node_based_to;
});
const auto can_transfer = std::none_of(
edges.begin(),
edges.end(),
[&](auto &edge) { return edge.node_based_to == suffix_edge.node_based_to; });
if (can_transfer)
{
insertEdge(rg,
@@ -186,9 +191,9 @@ struct transferBuilder
this->next_suffixes(from, to);
std::for_each(suffix_nodes.begin(), suffix_nodes.end(), [&](const auto &suffix_node) {
this->add_suffix_transfer(suffix_node);
});
std::for_each(suffix_nodes.begin(),
suffix_nodes.end(),
[&](const auto &suffix_node) { this->add_suffix_transfer(suffix_node); });
for (const auto &suffix_node : suffix_nodes)
{
@@ -207,7 +212,8 @@ struct transferBuilder
template <typename builder_type>
void buildGraph(RestrictionGraph &rg, const std::vector<TurnRestriction> &restrictions)
{
const auto run_builder = [&](const auto &restriction) {
const auto run_builder = [&](const auto &restriction)
{
builder_type builder(rg);
builder.start(restriction.turn_path.From(), restriction.turn_path.FirstVia());
@@ -248,9 +254,9 @@ RestrictionGraph constructRestrictionGraph(const std::vector<TurnRestriction> &t
// Start renumbering
const auto permutation = util::orderingToPermutation(ordering);
util::inplacePermutation(rg.nodes.begin(), rg.nodes.end(), permutation);
std::for_each(rg.edges.begin(), rg.edges.end(), [&](auto &edge) {
edge.target = permutation[edge.target];
});
std::for_each(rg.edges.begin(),
rg.edges.end(),
[&](auto &edge) { edge.target = permutation[edge.target]; });
rg.num_via_nodes = std::count(is_via_node.begin(), is_via_node.end(), true);
for (auto &entry : rg.via_edge_to_node)
{
+52 -44
View File
@@ -245,7 +245,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"valid",
&osmium::Location::valid);
auto get_location_tag = [](auto &context, const auto &location, const char *key) {
auto get_location_tag = [](auto &context, const auto &location, const char *key)
{
if (context.location_dependent_data.empty())
return sol::object(context.state);
@@ -272,7 +273,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"get_nodes",
[](const osmium::Way &way) { return sol::as_table(&way.nodes()); },
"get_location_tag",
[&context, &get_location_tag](const osmium::Way &way, const char *key) {
[&context, &get_location_tag](const osmium::Way &way, const char *key)
{
// HEURISTIC: use a single node (last) of the way to localize the way
// For more complicated scenarios a proper merging of multiple tags
// at one or many locations must be provided
@@ -292,9 +294,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"version",
&osmium::Node::version,
"get_location_tag",
[&context, &get_location_tag](const osmium::Node &node, const char *key) {
return get_location_tag(context, node.location(), key);
});
[&context, &get_location_tag](const osmium::Node &node, const char *key)
{ return get_location_tag(context, node.location(), key); });
context.state.new_enum("traffic_lights",
"none",
@@ -310,7 +311,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"ResultNode",
"traffic_lights",
sol::property([](const ExtractionNode &node) { return node.traffic_lights; },
[](ExtractionNode &node, const sol::object &obj) {
[](ExtractionNode &node, const sol::object &obj)
{
if (obj.is<bool>())
{
// The old approach of assigning a boolean traffic light
@@ -361,7 +363,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
sol::property(&ExtractionWay::GetName, &ExtractionWay::SetName),
"ref", // backward compatibility
sol::property(&ExtractionWay::GetForwardRef,
[](ExtractionWay &way, const char *ref) {
[](ExtractionWay &way, const char *ref)
{
way.SetForwardRef(ref);
way.SetBackwardRef(ref);
}),
@@ -420,7 +423,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
sol::property([](const ExtractionWay &way) { return way.access_turn_classification; },
[](ExtractionWay &way, int flag) { way.access_turn_classification = flag; }));
auto getTypedRefBySol = [](const sol::object &obj) -> ExtractionRelation::OsmIDTyped {
auto getTypedRefBySol = [](const sol::object &obj) -> ExtractionRelation::OsmIDTyped
{
if (obj.is<osmium::Way>())
{
osmium::Way *way = obj.as<osmium::Way *>();
@@ -456,20 +460,19 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"get_value_by_key",
[](ExtractionRelation &rel, const char *key) -> const char * { return rel.GetAttr(key); },
"get_role",
[&getTypedRefBySol](ExtractionRelation &rel, const sol::object &obj) -> const char * {
return rel.GetRole(getTypedRefBySol(obj));
});
[&getTypedRefBySol](ExtractionRelation &rel, const sol::object &obj) -> const char *
{ return rel.GetRole(getTypedRefBySol(obj)); });
context.state.new_usertype<ExtractionRelationContainer>(
"ExtractionRelationContainer",
"get_relations",
[&getTypedRefBySol](ExtractionRelationContainer &cont, const sol::object &obj)
-> const ExtractionRelationContainer::RelationIDList & {
return cont.GetRelations(getTypedRefBySol(obj));
},
-> const ExtractionRelationContainer::RelationIDList &
{ return cont.GetRelations(getTypedRefBySol(obj)); },
"relation",
[](ExtractionRelationContainer &cont, const ExtractionRelation::OsmIDTyped &rel_id)
-> const ExtractionRelation & { return cont.GetRelationData(rel_id); });
[](ExtractionRelationContainer &cont,
const ExtractionRelation::OsmIDTyped &rel_id) -> const ExtractionRelation &
{ return cont.GetRelationData(rel_id); });
context.state.new_usertype<NodeBasedEdgeClassification>(
"NodeBasedEdgeClassification",
@@ -489,17 +492,14 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"restricted",
sol::property([](NodeBasedEdgeClassification &c) -> bool { return c.restricted; }),
"road_classification",
sol::property([](NodeBasedEdgeClassification &c) -> RoadClassification {
return c.road_classification;
}),
sol::property([](NodeBasedEdgeClassification &c) -> RoadClassification
{ return c.road_classification; }),
"highway_turn_classification",
sol::property([](NodeBasedEdgeClassification &c) -> uint8_t {
return c.highway_turn_classification;
}),
sol::property([](NodeBasedEdgeClassification &c) -> uint8_t
{ return c.highway_turn_classification; }),
"access_turn_classification",
sol::property([](NodeBasedEdgeClassification &c) -> uint8_t {
return c.access_turn_classification;
}));
sol::property([](NodeBasedEdgeClassification &c) -> uint8_t
{ return c.access_turn_classification; }));
context.state.new_usertype<ExtractionSegment>("ExtractionSegment",
"source",
@@ -517,10 +517,12 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
// Keep in mind .location is available only if .pbf is preprocessed to set the location with the
// ref using osmium command "osmium add-locations-to-ways"
context.state.new_usertype<osmium::NodeRef>(
"NodeRef", "id", &osmium::NodeRef::ref, "location", [](const osmium::NodeRef &nref) {
return nref.location();
});
context.state.new_usertype<osmium::NodeRef>("NodeRef",
"id",
&osmium::NodeRef::ref,
"location",
[](const osmium::NodeRef &nref)
{ return nref.location(); });
context.state.new_usertype<InternalExtractorEdge>("EdgeSource",
"source_coordinate",
@@ -576,7 +578,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
util::Log() << "Using profile api version " << context.api_version;
// version-dependent parts of the api
auto initV2Context = [&]() {
auto initV2Context = [&]()
{
// clear global not used in v2
context.state["properties"] = sol::nullopt;
@@ -667,26 +670,31 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
}
};
auto initialize_V3_extraction_turn = [&]() {
auto initialize_V3_extraction_turn = [&]()
{
context.state.new_usertype<ExtractionTurn>(
"ExtractionTurn",
"angle",
&ExtractionTurn::angle,
"turn_type",
sol::property([](const ExtractionTurn &turn) {
if (turn.number_of_roads > 2 || turn.source_mode != turn.target_mode ||
turn.is_u_turn)
return osrm::guidance::TurnType::Turn;
else
return osrm::guidance::TurnType::NoTurn;
}),
sol::property(
[](const ExtractionTurn &turn)
{
if (turn.number_of_roads > 2 || turn.source_mode != turn.target_mode ||
turn.is_u_turn)
return osrm::guidance::TurnType::Turn;
else
return osrm::guidance::TurnType::NoTurn;
}),
"direction_modifier",
sol::property([](const ExtractionTurn &turn) {
if (turn.is_u_turn)
return osrm::guidance::DirectionModifier::UTurn;
else
return osrm::guidance::DirectionModifier::Straight;
}),
sol::property(
[](const ExtractionTurn &turn)
{
if (turn.is_u_turn)
return osrm::guidance::DirectionModifier::UTurn;
else
return osrm::guidance::DirectionModifier::Straight;
}),
"has_traffic_light",
&ExtractionTurn::has_traffic_light,
"weight",
+8 -4
View File
@@ -12,7 +12,8 @@ TurnPathCompressor::TurnPathCompressor(std::vector<TurnRestriction> &restriction
std::vector<UnresolvedManeuverOverride> &maneuver_overrides)
{
// Track all turn paths by their respective start/via/end nodes.
auto index = [&](auto &element) {
auto index = [&](auto &element)
{
starts.insert({element.From(), &element});
ends.insert({element.To(), &element});
if (element.Type() == TurnPathType::VIA_WAY_TURN_PATH)
@@ -44,7 +45,8 @@ void TurnPathCompressor::Compress(const NodeID from, const NodeID via, const Nod
std::back_inserter(start_ptrs),
[](const auto pair) { return pair.second; });
const auto update_start = [&](auto ptr) {
const auto update_start = [&](auto ptr)
{
if (ptr->Type() == TurnPathType::VIA_NODE_TURN_PATH)
{
@@ -97,7 +99,8 @@ void TurnPathCompressor::Compress(const NodeID from, const NodeID via, const Nod
std::back_inserter(end_ptrs),
[](const auto pair) { return pair.second; });
const auto update_end = [&](auto ptr) {
const auto update_end = [&](auto ptr)
{
if (ptr->Type() == TurnPathType::VIA_NODE_TURN_PATH)
{
auto &node_ptr = ptr->AsViaNodePath();
@@ -145,7 +148,8 @@ void TurnPathCompressor::Compress(const NodeID from, const NodeID via, const Nod
// remove compressed node from all via paths
auto all_vias_range = vias.equal_range(via);
const auto update_via = [&](auto restriction_pair) {
const auto update_via = [&](auto restriction_pair)
{
BOOST_ASSERT(restriction_pair.second->Type() == TurnPathType::VIA_WAY_TURN_PATH);
auto &way_ptr = restriction_pair.second->AsViaWayPath();
BOOST_ASSERT(std::find(way_ptr.via.begin(), way_ptr.via.end(), via) != way_ptr.via.end());
+12 -8
View File
@@ -18,7 +18,8 @@ std::vector<T> removeInvalidTurnPaths(std::vector<T> turn_relations,
log << "Removing invalid " << T::Name() << "s...";
TIMER_START(remove_invalid_turn_paths);
const auto is_valid_edge = [&node_based_graph](const auto from, const auto to) {
const auto is_valid_edge = [&node_based_graph](const auto from, const auto to)
{
const auto eid = node_based_graph.FindEdge(from, to);
if (eid == SPECIAL_EDGEID)
{
@@ -35,26 +36,29 @@ std::vector<T> removeInvalidTurnPaths(std::vector<T> turn_relations,
return true;
};
const auto is_valid_node = [is_valid_edge](const auto &via_node_path) {
const auto is_valid_node = [is_valid_edge](const auto &via_node_path)
{
return is_valid_edge(via_node_path.from, via_node_path.via) &&
is_valid_edge(via_node_path.via, via_node_path.to);
};
const auto is_valid_way = [is_valid_edge](const auto &via_way_path) {
const auto is_valid_way = [is_valid_edge](const auto &via_way_path)
{
if (!is_valid_edge(via_way_path.from, via_way_path.via.front()))
return false;
const auto invalid_it = std::adjacent_find(
via_way_path.via.begin(), via_way_path.via.end(), [&](auto via_from, auto via_to) {
return !is_valid_edge(via_from, via_to);
});
const auto invalid_it = std::adjacent_find(via_way_path.via.begin(),
via_way_path.via.end(),
[&](auto via_from, auto via_to)
{ return !is_valid_edge(via_from, via_to); });
if (invalid_it != via_way_path.via.end())
return false;
return is_valid_edge(via_way_path.via.back(), via_way_path.to);
};
const auto is_invalid = [is_valid_way, is_valid_node](const auto &turn_relation) {
const auto is_invalid = [is_valid_way, is_valid_node](const auto &turn_relation)
{
if (turn_relation.turn_path.Type() == TurnPathType::VIA_NODE_TURN_PATH)
{
return !is_valid_node(turn_relation.turn_path.AsViaNodePath());
+4 -3
View File
@@ -38,9 +38,10 @@ bool WayRestrictionMap::IsRestricted(DuplicatedNodeID duplicated_node, const Nod
// Checks if a turn to 'to' is restricted
BOOST_ASSERT(duplicated_node < restriction_graph.num_via_nodes);
const auto &restrictions = restriction_graph.GetRestrictions(duplicated_node);
return std::any_of(restrictions.begin(), restrictions.end(), [&to](const auto &restriction) {
return restriction->IsTurnRestricted(to);
});
return std::any_of(restrictions.begin(),
restrictions.end(),
[&to](const auto &restriction)
{ return restriction->IsTurnRestricted(to); });
}
std::vector<const TurnRestriction *>
+30 -17
View File
@@ -43,10 +43,13 @@ bool DrivewayHandler::canProcess(const NodeID /*nid*/,
return false;
auto low_priority_count =
std::count_if(intersection.begin(), intersection.end(), [this](const auto &road) {
return node_based_graph.GetEdgeData(road.eid)
.flags.road_classification.IsLowPriorityRoadClass();
});
std::count_if(intersection.begin(),
intersection.end(),
[this](const auto &road)
{
return node_based_graph.GetEdgeData(road.eid)
.flags.road_classification.IsLowPriorityRoadClass();
});
// Process intersection if it has two edges with normal priority and one is the entry edge,
// and also has at least one edge with lower priority
@@ -57,11 +60,13 @@ Intersection DrivewayHandler::operator()(const NodeID nid,
const EdgeID source_edge_id,
Intersection intersection) const
{
auto road =
std::find_if(intersection.begin() + 1, intersection.end(), [this](const auto &road) {
return !node_based_graph.GetEdgeData(road.eid)
.flags.road_classification.IsLowPriorityRoadClass();
});
auto road = std::find_if(intersection.begin() + 1,
intersection.end(),
[this](const auto &road)
{
return !node_based_graph.GetEdgeData(road.eid)
.flags.road_classification.IsLowPriorityRoadClass();
});
(void)nid;
OSRM_ASSERT(road != intersection.end(), node_coordinates[nid]);
@@ -76,14 +81,22 @@ Intersection DrivewayHandler::operator()(const NodeID nid,
if (road->instruction.direction_modifier == DirectionModifier::Straight)
{
std::for_each(intersection.begin() + 1, road, [](auto &side_road) {
if (side_road.instruction.direction_modifier == DirectionModifier::Straight)
side_road.instruction.direction_modifier = DirectionModifier::SlightRight;
});
std::for_each(road + 1, intersection.end(), [](auto &side_road) {
if (side_road.instruction.direction_modifier == DirectionModifier::Straight)
side_road.instruction.direction_modifier = DirectionModifier::SlightLeft;
});
std::for_each(
intersection.begin() + 1,
road,
[](auto &side_road)
{
if (side_road.instruction.direction_modifier == DirectionModifier::Straight)
side_road.instruction.direction_modifier = DirectionModifier::SlightRight;
});
std::for_each(
road + 1,
intersection.end(),
[](auto &side_road)
{
if (side_road.instruction.direction_modifier == DirectionModifier::Straight)
side_road.instruction.direction_modifier = DirectionModifier::SlightLeft;
});
}
return intersection;
+16 -15
View File
@@ -96,7 +96,9 @@ void annotateTurns(const util::NodeBasedDynamicGraph &node_based_graph,
// First part of the pipeline generates iterator ranges of IDs in sets of GRAINSIZE
tbb::filter<void, tbb::blocked_range<NodeID>> generator_stage(
tbb::filter_mode::serial_in_order, [&](tbb::flow_control &fc) {
tbb::filter_mode::serial_in_order,
[&](tbb::flow_control &fc)
{
if (current_node < node_count)
{
auto next_node = std::min(current_node + GRAINSIZE, node_count);
@@ -116,7 +118,8 @@ void annotateTurns(const util::NodeBasedDynamicGraph &node_based_graph,
//
tbb::filter<tbb::blocked_range<NodeID>, TurnsPipelineBufferPtr> guidance_stage(
tbb::filter_mode::parallel,
[&](const tbb::blocked_range<NodeID> &intersection_node_range) {
[&](const tbb::blocked_range<NodeID> &intersection_node_range)
{
auto buffer = std::make_shared<TurnsPipelineBuffer>();
buffer->nodes_processed = intersection_node_range.size();
@@ -224,9 +227,8 @@ void annotateTurns(const util::NodeBasedDynamicGraph &node_based_graph,
const auto turn =
std::find_if(intersection.begin(),
intersection.end(),
[edge = outgoing_edge.edge](const auto &road) {
return road.eid == edge;
});
[edge = outgoing_edge.edge](const auto &road)
{ return road.eid == edge; });
OSRM_ASSERT(turn != intersection.end(),
node_coordinates[intersection_node]);
@@ -267,9 +269,8 @@ void annotateTurns(const util::NodeBasedDynamicGraph &node_based_graph,
auto has_unconditional =
std::any_of(restrictions.begin(),
restrictions.end(),
[](const auto &restriction) {
return restriction->IsUnconditional();
});
[](const auto &restriction)
{ return restriction->IsUnconditional(); });
if (has_unconditional)
continue;
@@ -307,7 +308,9 @@ void annotateTurns(const util::NodeBasedDynamicGraph &node_based_graph,
std::vector<guidance::TurnData> delayed_turn_data;
tbb::filter<TurnsPipelineBufferPtr, void> guidance_output_stage(
tbb::filter_mode::serial_in_order, [&](auto buffer) {
tbb::filter_mode::serial_in_order,
[&](auto buffer)
{
guidance_progress.PrintAddition(buffer->nodes_processed);
connectivity_checksum = buffer->checksum.update_checksum(connectivity_checksum);
@@ -315,9 +318,8 @@ void annotateTurns(const util::NodeBasedDynamicGraph &node_based_graph,
// Guidance data
std::for_each(buffer->continuous_turn_data.begin(),
buffer->continuous_turn_data.end(),
[&turn_data_container](const auto &turn_data) {
turn_data_container.push_back(turn_data);
});
[&turn_data_container](const auto &turn_data)
{ turn_data_container.push_back(turn_data); });
// Copy via-way restrictions delayed data
delayed_turn_data.insert(delayed_turn_data.end(),
@@ -336,9 +338,8 @@ void annotateTurns(const util::NodeBasedDynamicGraph &node_based_graph,
// NOTE: EBG edges delayed_data and turns delayed_turn_data have the same index
std::for_each(delayed_turn_data.begin(),
delayed_turn_data.end(),
[&turn_data_container](const auto &turn_data) {
turn_data_container.push_back(turn_data);
});
[&turn_data_container](const auto &turn_data)
{ turn_data_container.push_back(turn_data); });
}
util::Log() << "done.";
+2 -1
View File
@@ -356,7 +356,8 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
ConnectedRoad &right) const
{
// TODO handle low priority road classes in a reasonable way
const auto suppressed_type = [&](const ConnectedRoad &road) {
const auto suppressed_type = [&](const ConnectedRoad &road)
{
const auto in_mode =
node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(via_edge).annotation_data)
+18 -11
View File
@@ -96,10 +96,13 @@ MotorwayHandler::operator()(const NodeID, const EdgeID via_eid, Intersection int
if (isMotorwayClass(via_eid, node_based_graph))
{
intersection = fromMotorway(via_eid, std::move(intersection));
std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) {
if (road.instruction.type == TurnType::OnRamp)
road.instruction.type = TurnType::OffRamp;
});
std::for_each(intersection.begin(),
intersection.end(),
[](ConnectedRoad &road)
{
if (road.instruction.type == TurnType::OnRamp)
road.instruction.type = TurnType::OffRamp;
});
return intersection;
}
else // coming from a ramp
@@ -116,7 +119,8 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
BOOST_ASSERT(isMotorwayClass(via_eid, node_based_graph));
// find the angle that continues on our current highway
const auto getContinueAngle = [this, in_data](const Intersection &intersection) {
const auto getContinueAngle = [this, in_data](const Intersection &intersection)
{
for (const auto &road : intersection)
{
if (!road.entry_allowed)
@@ -136,7 +140,8 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
return intersection[0].angle;
};
const auto getMostLikelyContinue = [this](const Intersection &intersection) {
const auto getMostLikelyContinue = [this](const Intersection &intersection)
{
double angle = intersection[0].angle;
double best = 180;
for (const auto &road : intersection)
@@ -151,7 +156,8 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
return angle;
};
const auto findBestContinue = [&]() {
const auto findBestContinue = [&]()
{
const double continue_angle = getContinueAngle(intersection);
if (continue_angle != intersection[0].angle)
return continue_angle;
@@ -209,10 +215,11 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
const auto valid_exits = std::count_if(intersection.begin(),
intersection.end(),
[](const auto &road) { return road.entry_allowed; });
const auto exiting_motorways =
std::count_if(intersection.begin(), intersection.end(), [this](const auto &road) {
return road.entry_allowed && isMotorwayClass(road.eid, node_based_graph);
});
const auto exiting_motorways = std::count_if(
intersection.begin(),
intersection.end(),
[this](const auto &road)
{ return road.entry_allowed && isMotorwayClass(road.eid, node_based_graph); });
if (exiting_motorways == 0)
{
+23 -16
View File
@@ -119,11 +119,11 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection(
if (!has_limited_size)
return false;
const bool simple_exits =
roundabout_nodes.end() ==
std::find_if(roundabout_nodes.begin(), roundabout_nodes.end(), [this](const NodeID node) {
return (node_based_graph.GetOutDegree(node) > 3);
});
const bool simple_exits = roundabout_nodes.end() ==
std::find_if(roundabout_nodes.begin(),
roundabout_nodes.end(),
[this](const NodeID node)
{ return (node_based_graph.GetOutDegree(node) > 3); });
if (!simple_exits)
return false;
@@ -131,7 +131,8 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection(
// Find all exit bearings. Only if they are well distinct (at least 60 degrees between
// them), we allow a roundabout turn
const auto exit_bearings = [this, &roundabout_nodes]() {
const auto exit_bearings = [this, &roundabout_nodes]()
{
std::vector<double> result;
for (const auto node : roundabout_nodes)
{
@@ -151,7 +152,8 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection(
edge_range.begin(),
edge_range.end(),
std::uint8_t{0},
[this](const auto current_max, const auto current_eid) {
[this](const auto current_max, const auto current_eid)
{
return std::max(current_max,
node_based_graph.GetEdgeData(current_eid)
.flags.road_classification.GetNumberOfLanes());
@@ -187,7 +189,8 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection(
return result;
}();
const bool well_distinct_bearings = [](const std::vector<double> &bearings) {
const bool well_distinct_bearings = [](const std::vector<double> &bearings)
{
for (std::size_t bearing_index = 0; bearing_index < bearings.size(); ++bearing_index)
{
const double difference =
@@ -207,10 +210,10 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
std::unordered_set<unsigned> roundabout_name_ids;
std::unordered_set<unsigned> connected_names;
const auto getNextOnRoundabout = [this, &roundabout_name_ids, &connected_names](
const NodeID node,
const bool roundabout,
const bool circular) {
const auto getNextOnRoundabout =
[this, &roundabout_name_ids, &connected_names](
const NodeID node, const bool roundabout, const bool circular)
{
BOOST_ASSERT(roundabout != circular);
EdgeID continue_edge = SPECIAL_EDGEID;
for (const auto edge_id : node_based_graph.GetAdjacentEdgeRange(node))
@@ -230,7 +233,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
if (!edge_name_empty)
{
const auto announce = [&](unsigned id) {
const auto announce = [&](unsigned id)
{
return util::guidance::requiresNameAnnounced(
id, edge_data.name_id, name_table, street_name_suffix_table);
};
@@ -250,7 +254,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
};
// this value is a hard abort to deal with potential self-loops
const auto countRoundaboutFlags = [&](const NodeID at_node) {
const auto countRoundaboutFlags = [&](const NodeID at_node)
{
// FIXME: this would be nicer as boost::count_if, but our integer range does not support
// these range based handlers
std::size_t count = 0;
@@ -263,7 +268,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
return count;
};
const auto getEdgeLength = [&](const NodeID source_node, EdgeID eid) {
const auto getEdgeLength = [&](const NodeID source_node, EdgeID eid)
{
double length = 0.;
auto last_coord = node_coordinates[source_node];
const auto &edge_bucket = compressed_geometries.GetBucketReference(eid);
@@ -404,7 +410,8 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
else
{
// Check if there is a non-service exit
const auto has_non_ignorable_exit = [&]() {
const auto has_non_ignorable_exit = [&]()
{
for (const auto eid :
node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection))
{
@@ -46,7 +46,8 @@ std::unordered_set<EdgeID> findSegregatedNodes(const extractor::NodeBasedGraphFa
extractor::intersection::CoordinateExtractor coordExtractor(
graph, factory.GetCompressedEdges(), coordinates);
auto const get_edge_length = [&](NodeID from_node, EdgeID edge_id, NodeID to_node) {
auto const get_edge_length = [&](NodeID from_node, EdgeID edge_id, NodeID to_node)
{
auto const geom =
coordExtractor.GetCoordinatesAlongRoad(from_node, edge_id, false, to_node);
double length = 0.0;
@@ -58,7 +59,8 @@ std::unordered_set<EdgeID> findSegregatedNodes(const extractor::NodeBasedGraphFa
};
// Returns an angle between edges from from_edge_id to to_edge_id
auto const get_angle = [&](NodeID from_node, EdgeID from_edge_id, EdgeID to_edge_id) {
auto const get_angle = [&](NodeID from_node, EdgeID from_edge_id, EdgeID to_edge_id)
{
auto intersection_node = graph.GetTarget(from_edge_id);
auto from_edge_id_outgoing = graph.FindEdge(intersection_node, from_node);
auto to_node = graph.GetTarget(to_edge_id);
@@ -70,7 +72,8 @@ std::unordered_set<EdgeID> findSegregatedNodes(const extractor::NodeBasedGraphFa
node_from, coordinates[intersection_node], node_to);
};
auto const get_edge_info = [&](EdgeID edge_id, NodeID node, auto const &edge_data) -> EdgeInfo {
auto const get_edge_info = [&](EdgeID edge_id, NodeID node, auto const &edge_data) -> EdgeInfo
{
/// @todo Make string normalization/lowercase/trim for comparison ...
auto const id = annotation[edge_data.annotation_data].name_id;
@@ -84,22 +87,24 @@ std::unordered_set<EdgeID> findSegregatedNodes(const extractor::NodeBasedGraphFa
edge_data.flags};
};
auto is_bidirectional = [](auto flags) {
return flags.is_split || (!flags.is_split && flags.forward && flags.backward);
};
auto is_bidirectional = [](auto flags)
{ return flags.is_split || (!flags.is_split && flags.forward && flags.backward); };
auto is_internal_straight = [](auto const turn_degree) {
auto is_internal_straight = [](auto const turn_degree)
{
return (turn_degree > INTERNAL_STRAIGHT_LOWER_BOUND &&
turn_degree < INTERNAL_STRAIGHT_UPPER_BOUND);
};
// Lambda to check if the turn set includes a right turn type
const auto has_turn_right = [](std::set<guidance::DirectionModifier::Enum> &turn_types) {
const auto has_turn_right = [](std::set<guidance::DirectionModifier::Enum> &turn_types)
{
return turn_types.find(guidance::DirectionModifier::Right) != turn_types.end() ||
turn_types.find(guidance::DirectionModifier::SharpRight) != turn_types.end();
};
// Lambda to check if the turn set includes a left turn type
const auto has_turn_left = [](std::set<guidance::DirectionModifier::Enum> &turn_types) {
const auto has_turn_left = [](std::set<guidance::DirectionModifier::Enum> &turn_types)
{
return turn_types.find(guidance::DirectionModifier::Left) != turn_types.end() ||
turn_types.find(guidance::DirectionModifier::SharpLeft) != turn_types.end();
};
@@ -108,7 +113,8 @@ std::unordered_set<EdgeID> findSegregatedNodes(const extractor::NodeBasedGraphFa
const std::vector<EdgeInfo> &v1,
const std::vector<EdgeInfo> &v2,
EdgeInfo const &current,
double edge_length) {
double edge_length)
{
// Internal intersection edges must be short and cannot be a roundabout.
// Also they must be a road use (not footway, cycleway, etc.)
// TODO - consider whether alleys, cul-de-sacs, and other road uses
@@ -219,7 +225,8 @@ std::unordered_set<EdgeID> findSegregatedNodes(const extractor::NodeBasedGraphFa
return true;
};
auto const collect_edge_info_fn = [&](auto const &edges1, NodeID node2) {
auto const collect_edge_info_fn = [&](auto const &edges1, NodeID node2)
{
std::vector<EdgeInfo> info;
for (auto e : edges1)
@@ -234,15 +241,15 @@ std::unordered_set<EdgeID> findSegregatedNodes(const extractor::NodeBasedGraphFa
if (info.empty())
return info;
std::sort(info.begin(), info.end(), [](EdgeInfo const &e1, EdgeInfo const &e2) {
return e1.node < e2.node;
});
std::sort(info.begin(),
info.end(),
[](EdgeInfo const &e1, EdgeInfo const &e2) { return e1.node < e2.node; });
info.erase(
std::unique(info.begin(),
info.end(),
[](EdgeInfo const &e1, EdgeInfo const &e2) { return e1.node == e2.node; }),
info.end());
info.erase(std::unique(info.begin(),
info.end(),
[](EdgeInfo const &e1, EdgeInfo const &e2)
{ return e1.node == e2.node; }),
info.end());
return info;
};
@@ -253,7 +260,8 @@ std::unordered_set<EdgeID> findSegregatedNodes(const extractor::NodeBasedGraphFa
NodeID node1,
auto const &edges2,
NodeID node2,
double edge_length) {
double edge_length)
{
return isSegregated(node1,
collect_edge_info_fn(edges1, node2),
collect_edge_info_fn(edges2, node1),
+21 -14
View File
@@ -91,7 +91,8 @@ Intersection SliproadHandler::operator()(const NodeID /*nid*/,
}
// Link-check for (bc) and later on (cd) which both are getting shortcutted by Sliproad
const auto is_potential_link = [this, main_road](const ConnectedRoad &road) {
const auto is_potential_link = [this, main_road](const ConnectedRoad &road)
{
if (!road.entry_allowed)
{
return false;
@@ -188,7 +189,8 @@ Intersection SliproadHandler::operator()(const NodeID /*nid*/,
const auto is_left_sliproad_turn = road_index > *obvious;
// Road at the intersection the main road leads onto which the sliproad arrives onto
const auto crossing_road = [&] {
const auto crossing_road = [&]
{
if (is_left_sliproad_turn)
return main_road_intersection->intersection.getLeftmostRoad();
@@ -266,7 +268,8 @@ Intersection SliproadHandler::operator()(const NodeID /*nid*/,
if (target_intersection.isDeadEnd())
continue;
const auto find_valid = [](const extractor::intersection::IntersectionView &view) {
const auto find_valid = [](const extractor::intersection::IntersectionView &view)
{
// according to our current sliproad idea, there should only be one valid turn
auto itr = std::find_if(
view.begin(), view.end(), [](const auto &road) { return road.entry_allowed; });
@@ -326,16 +329,19 @@ Intersection SliproadHandler::operator()(const NodeID /*nid*/,
is_left_sliproad_turn ? main_road_intersection->intersection.size() - 2 : 2;
auto next_to_crossing_road = main_road_intersection->intersection[next_to_crossing_idx];
auto next_to_crossing_node = node_based_graph.GetTarget(next_to_crossing_road.eid);
auto found_common_node = std::find_if(
begin(target_intersection), end(target_intersection), [&](const auto &road) {
if (next_to_crossing_node == node_based_graph.GetTarget(road.eid))
{
auto direction = getTurnDirection(road.angle);
return direction == DirectionModifier::SharpRight ||
direction == DirectionModifier::SharpLeft;
}
return false;
});
auto found_common_node =
std::find_if(begin(target_intersection),
end(target_intersection),
[&](const auto &road)
{
if (next_to_crossing_node == node_based_graph.GetTarget(road.eid))
{
auto direction = getTurnDirection(road.angle);
return direction == DirectionModifier::SharpRight ||
direction == DirectionModifier::SharpLeft;
}
return false;
});
if (found_common_node == target_intersection.end())
continue;
}
@@ -499,7 +505,8 @@ Intersection SliproadHandler::operator()(const NodeID /*nid*/,
node_based_graph.GetEdgeData(candidate_road.eid).annotation_data);
// Name mismatch: check roads at `c` and `d` for same name
const auto name_mismatch = [&](const NameID road_name_id) {
const auto name_mismatch = [&](const NameID road_name_id)
{
return util::guidance::requiresNameAnnounced(road_name_id, //
candidate_data.name_id, //
name_table, //
+18 -11
View File
@@ -50,11 +50,15 @@ bool SuppressModeHandler::canProcess(const NodeID,
const auto first = begin(intersection);
const auto last = end(intersection);
const auto all_share_mode = std::all_of(first, last, [this, &in_mode](const auto &road) {
return node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
.travel_mode == in_mode;
});
const auto all_share_mode = std::all_of(
first,
last,
[this, &in_mode](const auto &road)
{
return node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
.travel_mode == in_mode;
});
return (suppress_in_mode != end(suppressed)) && all_share_mode;
}
@@ -65,13 +69,16 @@ SuppressModeHandler::operator()(const NodeID, const EdgeID, Intersection interse
const auto first = begin(intersection);
const auto last = end(intersection);
std::for_each(first, last, [&](auto &road) {
const auto modifier = road.instruction.direction_modifier;
// use NoTurn, to not even have it as an IntermediateIntersection
const auto type = TurnType::NoTurn;
std::for_each(first,
last,
[&](auto &road)
{
const auto modifier = road.instruction.direction_modifier;
// use NoTurn, to not even have it as an IntermediateIntersection
const auto type = TurnType::NoTurn;
road.instruction = {type, modifier};
});
road.instruction = {type, modifier};
});
return intersection;
}
+9 -5
View File
@@ -105,7 +105,8 @@ Intersection TurnAnalysis::AssignTurnTypes(
std::transform(intersection_view.begin(),
intersection_view.end(),
std::back_inserter(intersection),
[&](const extractor::intersection::IntersectionViewData &data) {
[&](const extractor::intersection::IntersectionViewData &data)
{
return ConnectedRoad(data,
{TurnType::Invalid, DirectionModifier::UTurn},
INVALID_LANE_DATAID);
@@ -161,10 +162,13 @@ Intersection TurnAnalysis::AssignTurnTypes(
// Turn On Ramps Into Off Ramps, if we come from a motorway-like road
if (node_based_graph.GetEdgeData(entering_via_edge).flags.road_classification.IsMotorwayClass())
{
std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) {
if (road.instruction.type == TurnType::OnRamp)
road.instruction.type = TurnType::OffRamp;
});
std::for_each(intersection.begin(),
intersection.end(),
[](ConnectedRoad &road)
{
if (road.instruction.type == TurnType::OnRamp)
road.instruction.type = TurnType::OffRamp;
});
}
// After we ran all handlers and determined instruction type
+4 -4
View File
@@ -17,14 +17,14 @@ classifyIntersection(Intersection intersection, const osrm::util::Coordinate &lo
std::sort(intersection.begin(),
intersection.end(),
[](const ConnectedRoad &left, const ConnectedRoad &right) {
return left.perceived_bearing < right.perceived_bearing;
});
[](const ConnectedRoad &left, const ConnectedRoad &right)
{ return left.perceived_bearing < right.perceived_bearing; });
util::guidance::EntryClass entry_class;
util::guidance::BearingClass bearing_class;
const bool canBeDiscretized = [&]() {
const bool canBeDiscretized = [&]()
{
if (intersection.size() <= 1)
return true;
+2 -3
View File
@@ -127,9 +127,8 @@ bool findPreviousIntersection(const NodeID node_v,
result_intersection.end() !=
std::find_if(result_intersection.begin(),
result_intersection.end(),
[via_edge](const extractor::intersection::IntersectionViewData &road) {
return road.eid == via_edge;
});
[via_edge](const extractor::intersection::IntersectionViewData &road)
{ return road.eid == via_edge; });
if (!check_via_edge)
{
+45 -25
View File
@@ -223,10 +223,12 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,
bool TurnHandler::hasObvious(const EdgeID &via_edge, const Fork &fork) const
{
auto obvious_road =
std::adjacent_find(fork.begin, fork.end, [&, this](const auto &a, const auto &b) {
return this->isObviousOfTwo(via_edge, a, b) || this->isObviousOfTwo(via_edge, b, a);
});
auto obvious_road = std::adjacent_find(fork.begin,
fork.end,
[&, this](const auto &a, const auto &b) {
return this->isObviousOfTwo(via_edge, a, b) ||
this->isObviousOfTwo(via_edge, b, a);
});
// return whether an obvious road was found
return obvious_road != fork.end;
}
@@ -246,10 +248,11 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
OOOOOOO
*/
const auto all_links =
std::all_of(intersection.begin(), intersection.end(), [this](const auto &road) {
return node_based_graph.GetEdgeData(road.eid).flags.road_classification.IsLinkClass();
});
const auto all_links = std::all_of(
intersection.begin(),
intersection.end(),
[this](const auto &road)
{ return node_based_graph.GetEdgeData(road.eid).flags.road_classification.IsLinkClass(); });
auto fork = findFork(via_edge, intersection);
if (fork && (all_links || obvious_index == 0))
@@ -438,7 +441,8 @@ Intersection TurnHandler::assignLeftTurns(const EdgeID via_edge,
const std::size_t starting_at) const
{
BOOST_ASSERT(starting_at < intersection.size());
const auto switch_left_and_right = [](Intersection &intersection) {
const auto switch_left_and_right = [](Intersection &intersection)
{
BOOST_ASSERT(!intersection.empty());
for (auto &road : intersection)
@@ -462,7 +466,8 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
const std::size_t up_to) const
{
BOOST_ASSERT(up_to <= intersection.size());
const auto count_valid = [&intersection, up_to]() {
const auto count_valid = [&intersection, up_to]()
{
std::size_t count = 0;
for (std::size_t i = 1; i < up_to; ++i)
if (intersection[i].entry_allowed)
@@ -656,24 +661,36 @@ bool TurnHandler::isCompatibleByRoadClass(const Intersection &intersection, cons
// except if rightmost fork candidate is also a link road
const auto is_right_link_class =
node_based_graph.GetEdgeData(fork.getRight().eid).flags.road_classification.IsLinkClass();
if (!std::all_of(fork.begin + 1, fork.end, [&](ConnectedRoad &road) {
return is_right_link_class ==
node_based_graph.GetEdgeData(road.eid).flags.road_classification.IsLinkClass();
}))
if (!std::all_of(fork.begin + 1,
fork.end,
[&](ConnectedRoad &road)
{
return is_right_link_class == node_based_graph.GetEdgeData(road.eid)
.flags.road_classification.IsLinkClass();
}))
{
return false;
}
return std::all_of(fork.begin, fork.end, [&](ConnectedRoad &base) {
const auto base_class = node_based_graph.GetEdgeData(base.eid).flags.road_classification;
// check that there is no turn obvious == check that all turns are non-onvious
return std::all_of(fork.begin, fork.end, [&](ConnectedRoad &compare) {
const auto compare_class =
node_based_graph.GetEdgeData(compare.eid).flags.road_classification;
return compare.eid == base.eid ||
!(obviousByRoadClass(via_class, base_class, compare_class));
return std::all_of(
fork.begin,
fork.end,
[&](ConnectedRoad &base)
{
const auto base_class =
node_based_graph.GetEdgeData(base.eid).flags.road_classification;
// check that there is no turn obvious == check that all turns are non-onvious
return std::all_of(
fork.begin,
fork.end,
[&](ConnectedRoad &compare)
{
const auto compare_class =
node_based_graph.GetEdgeData(compare.eid).flags.road_classification;
return compare.eid == base.eid ||
!(obviousByRoadClass(via_class, base_class, compare_class));
});
});
});
}
// Checks whether a three-way-intersection coming from `via_edge` is a fork
@@ -703,8 +720,11 @@ boost::optional<TurnHandler::Fork> TurnHandler::findFork(const EdgeID via_edge,
// check if all entries in the fork range allow entry
const bool only_valid_entries = intersection.hasAllValidEntries(fork->begin, fork->end);
const auto has_compatible_modes =
std::all_of(fork->begin, fork->end, [&](const auto &road) {
const auto has_compatible_modes = std::all_of(
fork->begin,
fork->end,
[&](const auto &road)
{
return node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
.travel_mode ==
+13 -11
View File
@@ -26,9 +26,9 @@ const constexpr extractor::TurnLaneType::Mask tag_by_modifier[] = {
std::size_t getNumberOfTurns(const Intersection &intersection)
{
return std::count_if(intersection.begin(), intersection.end(), [](const ConnectedRoad &road) {
return road.entry_allowed;
});
return std::count_if(intersection.begin(),
intersection.end(),
[](const ConnectedRoad &road) { return road.entry_allowed; });
}
LaneDataVector augmentMultiple(const std::size_t none_index,
@@ -41,7 +41,8 @@ LaneDataVector augmentMultiple(const std::size_t none_index,
// entries?
// looking at the left side first
const auto range = [&]() {
const auto range = [&]()
{
if (none_index == 0)
{
// find first connection_count - lane_data.size() valid turns
@@ -106,17 +107,18 @@ LaneDataVector augmentMultiple(const std::size_t none_index,
const auto intersection_range_first = intersection.begin() + range.first;
const auto intersection_range_end = intersection.begin() + range.second;
const auto allowed_in_range =
std::count_if(intersection_range_first, intersection_range_end, [](const auto &road) {
return road.entry_allowed;
});
std::count_if(intersection_range_first,
intersection_range_end,
[](const auto &road) { return road.entry_allowed; });
if (allowed_in_range > 1 && lane_data[none_index].to - lane_data[none_index].from >= 1)
{
// check if there is a straight turn
auto straight_itr =
std::find_if(intersection_range_first, intersection_range_end, [](const auto &road) {
return road.instruction.direction_modifier == DirectionModifier::Straight;
});
auto straight_itr = std::find_if(
intersection_range_first,
intersection_range_end,
[](const auto &road)
{ return road.instruction.direction_modifier == DirectionModifier::Straight; });
// we have a straight turn?
if (straight_itr != intersection_range_end)
+25 -22
View File
@@ -67,26 +67,26 @@ LaneDataVector laneDataFromDescription(const TurnLaneDescription &turn_lane_desc
const auto num_lanes = boost::numeric_cast<LaneID>(turn_lane_description.size());
const auto setLaneData =
[&](LaneMap &map, TurnLaneType::Mask full_mask, const LaneID current_lane) {
const auto isSet = [&](const TurnLaneType::Mask test_mask) -> bool {
return (test_mask & full_mask) == test_mask;
};
[&](LaneMap &map, TurnLaneType::Mask full_mask, const LaneID current_lane)
{
const auto isSet = [&](const TurnLaneType::Mask test_mask) -> bool
{ return (test_mask & full_mask) == test_mask; };
for (const auto shift : util::irange<std::size_t>(0, TurnLaneType::NUM_TYPES))
for (const auto shift : util::irange<std::size_t>(0, TurnLaneType::NUM_TYPES))
{
TurnLaneType::Mask mask = 1 << shift;
if (isSet(mask))
{
TurnLaneType::Mask mask = 1 << shift;
if (isSet(mask))
auto map_iterator = map.find(mask);
if (map_iterator == map.end())
map[mask] = std::make_pair(current_lane, current_lane);
else
{
auto map_iterator = map.find(mask);
if (map_iterator == map.end())
map[mask] = std::make_pair(current_lane, current_lane);
else
{
map_iterator->second.first = current_lane;
}
map_iterator->second.first = current_lane;
}
}
};
}
};
LaneMap lane_map;
LaneID lane_nr = num_lanes - 1;
@@ -108,7 +108,8 @@ LaneDataVector laneDataFromDescription(const TurnLaneDescription &turn_lane_desc
std::sort(lane_data.begin(), lane_data.end());
// check whether a given turn lane string resulted in valid lane data
const auto hasValidOverlaps = [](const LaneDataVector &lane_data) {
const auto hasValidOverlaps = [](const LaneDataVector &lane_data)
{
// Allow an overlap of at most one. Larger overlaps would result in crossing another turn,
// which is invalid
for (std::size_t index = 1; index < lane_data.size(); ++index)
@@ -134,15 +135,17 @@ LaneDataVector laneDataFromDescription(const TurnLaneDescription &turn_lane_desc
LaneDataVector::iterator findTag(const TurnLaneType::Mask tag, LaneDataVector &data)
{
return std::find_if(data.begin(), data.end(), [&](const TurnLaneData &lane_data) {
return (tag & lane_data.tag) != TurnLaneType::empty;
});
return std::find_if(data.begin(),
data.end(),
[&](const TurnLaneData &lane_data)
{ return (tag & lane_data.tag) != TurnLaneType::empty; });
}
LaneDataVector::const_iterator findTag(const TurnLaneType::Mask tag, const LaneDataVector &data)
{
return std::find_if(data.cbegin(), data.cend(), [&](const TurnLaneData &lane_data) {
return (tag & lane_data.tag) != TurnLaneType::empty;
});
return std::find_if(data.cbegin(),
data.cend(),
[&](const TurnLaneData &lane_data)
{ return (tag & lane_data.tag) != TurnLaneType::empty; });
}
bool hasTag(const TurnLaneType::Mask tag, const LaneDataVector &data)
+25 -20
View File
@@ -24,9 +24,9 @@ namespace
{
std::size_t getNumberOfTurns(const Intersection &intersection)
{
return std::count_if(intersection.begin(), intersection.end(), [](const ConnectedRoad &road) {
return road.entry_allowed;
});
return std::count_if(intersection.begin(),
intersection.end(),
[](const ConnectedRoad &road) { return road.entry_allowed; });
}
} // namespace
@@ -158,10 +158,10 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at,
return TurnLaneScenario::NONE;
// really don't touch roundabouts (#2626)
if (intersection.end() !=
std::find_if(intersection.begin(), intersection.end(), [](const auto &road) {
return hasRoundaboutType(road.instruction);
}))
if (intersection.end() != std::find_if(intersection.begin(),
intersection.end(),
[](const auto &road)
{ return hasRoundaboutType(road.instruction); }))
return TurnLaneScenario::NONE;
// if only a uturn exists, there is nothing we can do
@@ -233,7 +233,8 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at,
if (via_edge == road.eid)
return TurnLaneScenario::SLIPROAD;
const auto &closest_road = [&]() {
const auto &closest_road = [&]()
{
if (road_index + 1 == previous_intersection.size())
{
BOOST_ASSERT(road_index > 1);
@@ -419,7 +420,8 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
return std::count_if(
lane_data.begin(),
lane_data.end(),
[](const TurnLaneData &data) {
[](const TurnLaneData &data)
{
return ((data.tag & TurnLaneType::merge_to_left) != TurnLaneType::empty) ||
((data.tag & TurnLaneType::merge_to_right) != TurnLaneType::empty);
}) +
@@ -429,7 +431,8 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
// in case an intersection offers far more lane data items than actual turns, some of them
// have to be for another intersection. A single additional item can be for an invalid bus lane.
const auto num_turns = [&]() {
const auto num_turns = [&]()
{
auto count = getNumberOfTurns(intersection);
if (count < lane_data.size() && !intersection[0].entry_allowed &&
lane_data.back().tag == TurnLaneType::uturn)
@@ -453,10 +456,10 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
// more turns than lane data
if (num_turns > lane_data.size() &&
lane_data.end() ==
std::find_if(lane_data.begin(), lane_data.end(), [](const TurnLaneData &data) {
return data.tag == TurnLaneType::none;
}))
lane_data.end() == std::find_if(lane_data.begin(),
lane_data.end(),
[](const TurnLaneData &data)
{ return data.tag == TurnLaneType::none; }))
{
return false;
}
@@ -485,7 +488,8 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
// u-turn tags are at the outside of the lane-tags and require special handling, since
// locating their best match requires knowledge on the neighboring tag. (see documentation
// on findBestMatch/findBestMatchForReverse
const auto best_match = [&]() {
const auto best_match = [&]()
{
// normal tag or u-turn as only choice (no other tag present)
if (data.tag != TurnLaneType::uturn || lane_data.size() == 1)
return findBestMatch(data.tag, intersection);
@@ -644,7 +648,8 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
matched_at_second[none_index] = true;
}
const auto augmentEntry = [&](TurnLaneData &data) {
const auto augmentEntry = [&](TurnLaneData &data)
{
for (std::size_t lane = 0; lane < turn_lane_data.size(); ++lane)
if (matched_at_second[lane])
{
@@ -713,15 +718,15 @@ Intersection TurnLaneHandler::handleSliproadTurn(Intersection intersection,
std::distance(previous_intersection.begin(),
std::find_if(previous_intersection.begin(),
previous_intersection.end(),
[](const ConnectedRoad &road) {
return road.instruction.type == TurnType::Sliproad;
}));
[](const ConnectedRoad &road)
{ return road.instruction.type == TurnType::Sliproad; }));
BOOST_ASSERT(sliproad_index <= previous_intersection.size());
const auto &sliproad = previous_intersection[sliproad_index];
// code duplicatino with deduceScenario: TODO refactor
const auto &main_road = [&]() {
const auto &main_road = [&]()
{
if (sliproad_index + 1 == previous_intersection.size())
{
BOOST_ASSERT(sliproad_index > 1);
+8 -6
View File
@@ -49,9 +49,8 @@ DirectionModifier::Enum getMatchingModifier(const TurnLaneType::Mask tag)
// check whether a match of a given tag and a turn instruction can be seen as valid
bool isValidMatch(const TurnLaneType::Mask tag, const TurnInstruction instruction)
{
const auto isMirroredModifier = [](const TurnInstruction instruction) {
return instruction.type == TurnType::Merge;
};
const auto isMirroredModifier = [](const TurnInstruction instruction)
{ return instruction.type == TurnType::Merge; };
if (tag == TurnLaneType::uturn)
{
@@ -114,7 +113,8 @@ typename Intersection::const_iterator findBestMatch(const TurnLaneType::Mask tag
{
return std::min_element(intersection.begin(),
intersection.end(),
[tag](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
[tag](const ConnectedRoad &lhs, const ConnectedRoad &rhs)
{
// prefer valid matches
if (isValidMatch(tag, lhs.instruction) !=
isValidMatch(tag, rhs.instruction))
@@ -144,7 +144,8 @@ typename Intersection::const_iterator findBestMatchForReverse(const TurnLaneType
return std::min_element(
intersection.begin() + std::distance(intersection.begin(), neighbor_itr),
intersection.end(),
[](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
[](const ConnectedRoad &lhs, const ConnectedRoad &rhs)
{
const TurnLaneType::Mask tag = TurnLaneType::uturn;
// prefer valid matches
if (isValidMatch(tag, lhs.instruction) != isValidMatch(tag, rhs.instruction))
@@ -197,7 +198,8 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
{
std::size_t road_index = 1, lane = 0;
const auto matchRoad = [&](ConnectedRoad &road, const TurnLaneData &data) {
const auto matchRoad = [&](ConnectedRoad &road, const TurnLaneData &data)
{
util::guidance::LaneTupleIdPair key{{LaneID(data.to - data.from + 1), data.from},
lane_string_id};
+4 -6
View File
@@ -64,9 +64,8 @@ void partitionLevel(const std::vector<BisectionID> &node_to_bisection_id,
std::accumulate(permutation.begin() + cell.begin,
permutation.begin() + cell.end,
BisectionID{0},
[&node_to_bisection_id](const BisectionID lhs, const NodeID rhs) {
return lhs | node_to_bisection_id[rhs];
});
[&node_to_bisection_id](const BisectionID lhs, const NodeID rhs)
{ return lhs | node_to_bisection_id[rhs]; });
// masks all bit strictly higher then cell.bit
BOOST_ASSERT(sizeof(unsigned long long) * CHAR_BIT > sizeof(BisectionID) * CHAR_BIT);
const BisectionID mask = (1ULL << (cell.bit + 1)) - 1;
@@ -88,9 +87,8 @@ void partitionLevel(const std::vector<BisectionID> &node_to_bisection_id,
std::uint32_t middle =
std::partition(permutation.begin() + cell.begin,
permutation.begin() + cell.end,
[is_left_mask, &node_to_bisection_id](const auto node_id) {
return node_to_bisection_id[node_id] & is_left_mask;
}) -
[is_left_mask, &node_to_bisection_id](const auto node_id)
{ return node_to_bisection_id[node_id] & is_left_mask; }) -
permutation.begin();
if (bit > 0)
+18 -15
View File
@@ -19,10 +19,10 @@ const auto constexpr INVALID_LEVEL = std::numeric_limits<DinicMaxFlow::Level>::m
auto makeHasNeighborNotInCheck(const DinicMaxFlow::SourceSinkNodes &set,
const BisectionGraphView &view)
{
return [&](const NodeID nid) {
const auto is_not_contained = [&set](const BisectionEdge &edge) {
return set.count(edge.target) == 0;
};
return [&](const NodeID nid)
{
const auto is_not_contained = [&set](const BisectionEdge &edge)
{ return set.count(edge.target) == 0; };
return view.EndEdges(nid) !=
std::find_if(view.BeginEdges(nid), view.EndEdges(nid), is_not_contained);
};
@@ -132,12 +132,12 @@ DinicMaxFlow::ComputeLevelGraph(const BisectionGraphView &view,
levels[edge.target] = 0;
}
// check if there is flow present on an edge
const auto has_flow = [&](const NodeID from, const NodeID to) {
return flow[from].find(to) != flow[from].end();
};
const auto has_flow = [&](const NodeID from, const NodeID to)
{ return flow[from].find(to) != flow[from].end(); };
// perform a relaxation step in the BFS algorithm
const auto relax_node = [&](const NodeID node_id) {
const auto relax_node = [&](const NodeID node_id)
{
// don't relax sink nodes
if (sink_nodes.count(node_id))
return;
@@ -180,9 +180,11 @@ std::size_t DinicMaxFlow::BlockingFlow(FlowEdges &flow,
std::size_t flow_increase = 0;
// augment the flow along a path in the level graph
const auto augment_flow = [&flow](const std::vector<NodeID> &path) {
const auto augment_flow = [&flow](const std::vector<NodeID> &path)
{
// add/remove flow edges from the current residual graph
const auto augment_one = [&flow](const NodeID from, const NodeID to) {
const auto augment_one = [&flow](const NodeID from, const NodeID to)
{
// check if there is flow in the opposite direction
auto existing_edge = flow[to].find(from);
if (existing_edge != flow[to].end())
@@ -200,7 +202,8 @@ std::size_t DinicMaxFlow::BlockingFlow(FlowEdges &flow,
[[maybe_unused]] auto _ = std::adjacent_find(path.begin(), path.end(), augment_one);
};
const auto augment_all_paths = [&](const NodeID sink_node_id) {
const auto augment_all_paths = [&](const NodeID sink_node_id)
{
// only augment sinks
if (levels[sink_node_id] == INVALID_LEVEL)
return;
@@ -295,10 +298,10 @@ bool DinicMaxFlow::Validate(const BisectionGraphView &view,
const SourceSinkNodes &sink_nodes) const
{
// sink and source cannot share a common node
const auto separated =
std::find_if(source_nodes.begin(), source_nodes.end(), [&sink_nodes](const auto node) {
return sink_nodes.count(node);
}) == source_nodes.end();
const auto separated = std::find_if(source_nodes.begin(),
source_nodes.end(),
[&sink_nodes](const auto node)
{ return sink_nodes.count(node); }) == source_nodes.end();
const auto invalid_id = [&view](const NodeID nid) { return nid >= view.NumberOfNodes(); };
const auto in_range_source =
+41 -31
View File
@@ -53,21 +53,25 @@ makeSpatialOrder(const BisectionGraphView &view, const double ratio, const doubl
// adress of the very first node
const auto node_zero = &(*view.Begin());
std::transform(view.Begin(), view.End(), std::back_inserter(embedding), [&](const auto &node) {
const auto node_id = static_cast<NodeID>(&node - node_zero);
return NodeWithCoordinate{node_id, node.coordinate};
});
std::transform(view.Begin(),
view.End(),
std::back_inserter(embedding),
[&](const auto &node)
{
const auto node_id = static_cast<NodeID>(&node - node_zero);
return NodeWithCoordinate{node_id, node.coordinate};
});
const auto project = [slope](const auto &each) {
const auto project = [slope](const auto &each)
{
auto lon = static_cast<std::int32_t>(each.coordinate.lon);
auto lat = static_cast<std::int32_t>(each.coordinate.lat);
return slope * lon + (1. - std::fabs(slope)) * lat;
};
const auto spatially = [&](const auto &lhs, const auto &rhs) {
return project(lhs) < project(rhs);
};
const auto spatially = [&](const auto &lhs, const auto &rhs)
{ return project(lhs) < project(rhs); };
const std::size_t n = ratio * embedding.size();
@@ -96,7 +100,8 @@ DinicMaxFlow::MinCut bestMinCut(const BisectionGraphView &view,
DinicMaxFlow::MinCut best;
best.num_edges = -1;
const auto get_balance = [&view, balance](const auto num_nodes_source) {
const auto get_balance = [&view, balance](const auto num_nodes_source)
{
const auto perfect_balance = view.NumberOfNodes() / 2;
const auto allowed_balance = balance * perfect_balance;
const auto bigger_side =
@@ -114,36 +119,41 @@ DinicMaxFlow::MinCut bestMinCut(const BisectionGraphView &view,
tbb::blocked_range<std::size_t> range{0, n, 1};
const auto balance_delta = [&view](const auto num_nodes_source) {
const auto balance_delta = [&view](const auto num_nodes_source)
{
const std::int64_t difference =
static_cast<std::int64_t>(view.NumberOfNodes()) / 2 - num_nodes_source;
return std::abs(difference);
};
tbb::parallel_for(range, [&](const auto &chunk) {
for (auto round = chunk.begin(), end = chunk.end(); round != end; ++round)
{
const auto slope = -1. + round * (2. / n);
tbb::parallel_for(range,
[&](const auto &chunk)
{
for (auto round = chunk.begin(), end = chunk.end(); round != end; ++round)
{
const auto slope = -1. + round * (2. / n);
auto order = makeSpatialOrder(view, ratio, slope);
auto cut = DinicMaxFlow()(view, order.sources, order.sinks);
auto cut_balance = get_balance(cut.num_nodes_source);
auto order = makeSpatialOrder(view, ratio, slope);
auto cut = DinicMaxFlow()(view, order.sources, order.sinks);
auto cut_balance = get_balance(cut.num_nodes_source);
{
std::lock_guard<std::mutex> guard{lock};
{
std::lock_guard<std::mutex> guard{lock};
// Swap to keep the destruction of the old object outside of critical section.
if (cut.num_edges * cut_balance < best.num_edges * best_balance ||
(cut.num_edges == best.num_edges &&
balance_delta(cut.num_nodes_source) < balance_delta(best.num_nodes_source)))
{
best_balance = cut_balance;
std::swap(best, cut);
}
}
// cut gets destroyed here
}
});
// Swap to keep the destruction of the old object outside of
// critical section.
if (cut.num_edges * cut_balance < best.num_edges * best_balance ||
(cut.num_edges == best.num_edges &&
balance_delta(cut.num_nodes_source) <
balance_delta(best.num_nodes_source)))
{
best_balance = cut_balance;
std::swap(best, cut);
}
}
// cut gets destroyed here
}
});
return best;
}
+31 -23
View File
@@ -58,40 +58,48 @@ RecursiveBisection::RecursiveBisection(BisectionGraph &bisection_graph_,
std::vector<TreeNode> forest;
forest.reserve(last - first);
std::transform(first, last, std::back_inserter(forest), [this](auto graph) {
return TreeNode{std::move(graph), internal_state.SCCDepth()};
});
std::transform(first,
last,
std::back_inserter(forest),
[this](auto graph) {
return TreeNode{std::move(graph), internal_state.SCCDepth()};
});
using Feeder = tbb::feeder<TreeNode>;
TIMER_START(bisection);
// Bisect graph into two parts. Get partition point and recurse left and right in parallel.
tbb::parallel_for_each(begin(forest), end(forest), [&](const TreeNode &node, Feeder &feeder) {
const auto cut =
computeInertialFlowCut(node.graph, num_optimizing_cuts, balance, boundary_factor);
const auto center = internal_state.ApplyBisection(
node.graph.Begin(), node.graph.End(), node.depth, cut.flags);
tbb::parallel_for_each(
begin(forest),
end(forest),
[&](const TreeNode &node, Feeder &feeder)
{
const auto cut =
computeInertialFlowCut(node.graph, num_optimizing_cuts, balance, boundary_factor);
const auto center = internal_state.ApplyBisection(
node.graph.Begin(), node.graph.End(), node.depth, cut.flags);
const auto terminal = [&](const auto &node) {
const auto maximum_depth = sizeof(BisectionID) * CHAR_BIT;
const auto too_small = node.graph.NumberOfNodes() < maximum_cell_size;
const auto too_deep = node.depth >= maximum_depth;
return too_small || too_deep;
};
const auto terminal = [&](const auto &node)
{
const auto maximum_depth = sizeof(BisectionID) * CHAR_BIT;
const auto too_small = node.graph.NumberOfNodes() < maximum_cell_size;
const auto too_deep = node.depth >= maximum_depth;
return too_small || too_deep;
};
BisectionGraphView left_graph{bisection_graph, node.graph.Begin(), center};
TreeNode left_node{std::move(left_graph), node.depth + 1};
BisectionGraphView left_graph{bisection_graph, node.graph.Begin(), center};
TreeNode left_node{std::move(left_graph), node.depth + 1};
if (!terminal(left_node))
feeder.add(left_node);
if (!terminal(left_node))
feeder.add(left_node);
BisectionGraphView right_graph{bisection_graph, center, node.graph.End()};
TreeNode right_node{std::move(right_graph), node.depth + 1};
BisectionGraphView right_graph{bisection_graph, center, node.graph.End()};
TreeNode right_node{std::move(right_graph), node.depth + 1};
if (!terminal(right_node))
feeder.add(right_node);
});
if (!terminal(right_node))
feeder.add(right_node);
});
TIMER_STOP(bisection);
+43 -31
View File
@@ -45,9 +45,8 @@ RecursiveBisectionState::ApplyBisection(const NodeIterator const_begin,
}
// Keep items with `0` as partition id to the left, move other to the right
auto by_flag_bit = [this, flag](const auto &node) {
return BisectionID{0} == (bisection_ids[node.original_id] & flag);
};
auto by_flag_bit = [this, flag](const auto &node)
{ return BisectionID{0} == (bisection_ids[node.original_id] & flag); };
auto begin = bisection_graph.Begin() + std::distance(bisection_graph.CBegin(), const_begin);
const auto end = begin + std::distance(const_begin, const_end);
@@ -59,26 +58,34 @@ RecursiveBisectionState::ApplyBisection(const NodeIterator const_begin,
std::transform(const_begin,
const_end,
mapping.begin(),
[by_flag_bit, &lesser_id, &upper_id](const auto &node) {
return by_flag_bit(node) ? lesser_id++ : upper_id++;
});
[by_flag_bit, &lesser_id, &upper_id](const auto &node)
{ return by_flag_bit(node) ? lesser_id++ : upper_id++; });
// erase all edges that point into different partitions
std::for_each(begin, end, [&](auto &node) {
const auto node_flag = by_flag_bit(node);
bisection_graph.RemoveEdges(node, [&](const BisectionGraph::EdgeT &edge) {
const auto target_flag = by_flag_bit(*(const_begin + edge.target));
return (node_flag != target_flag);
});
});
std::for_each(begin,
end,
[&](auto &node)
{
const auto node_flag = by_flag_bit(node);
bisection_graph.RemoveEdges(node,
[&](const BisectionGraph::EdgeT &edge)
{
const auto target_flag =
by_flag_bit(*(const_begin + edge.target));
return (node_flag != target_flag);
});
});
auto center = std::stable_partition(begin, end, by_flag_bit);
// remap all remaining edges
std::for_each(const_begin, const_end, [&](const auto &node) {
for (auto &edge : bisection_graph.Edges(node))
edge.target = mapping[edge.target];
});
std::for_each(const_begin,
const_end,
[&](const auto &node)
{
for (auto &edge : bisection_graph.Edges(node))
edge.target = mapping[edge.target];
});
return const_begin + std::distance(begin, center);
}
@@ -93,13 +100,13 @@ RecursiveBisectionState::PrePartitionWithSCC(const std::size_t small_component_s
scc_algo.Run();
// Map Edges to Sccs
const auto in_small = [&scc_algo, small_component_size](const NodeID node_id) {
return scc_algo.GetComponentSize(scc_algo.GetComponentID(node_id)) <= small_component_size;
};
const auto in_small = [&scc_algo, small_component_size](const NodeID node_id)
{ return scc_algo.GetComponentSize(scc_algo.GetComponentID(node_id)) <= small_component_size; };
const constexpr std::size_t small_component_id = -1;
std::unordered_map<std::size_t, std::size_t> component_map;
const auto transform_id = [&](const NodeID node_id) -> std::size_t {
const auto transform_id = [&](const NodeID node_id) -> std::size_t
{
if (in_small(node_id))
return small_component_id;
else
@@ -111,16 +118,19 @@ RecursiveBisectionState::PrePartitionWithSCC(const std::size_t small_component_s
mapping[node.original_id] = component_map[transform_id(node.original_id)]++;
// needs to remove edges, if we should ever switch to directed graphs here
std::stable_sort(
bisection_graph.Begin(), bisection_graph.End(), [&](const auto &lhs, const auto &rhs) {
return transform_id(lhs.original_id) < transform_id(rhs.original_id);
});
std::stable_sort(bisection_graph.Begin(),
bisection_graph.End(),
[&](const auto &lhs, const auto &rhs)
{ return transform_id(lhs.original_id) < transform_id(rhs.original_id); });
// remap all remaining edges
std::for_each(bisection_graph.Begin(), bisection_graph.End(), [&](const auto &node) {
for (auto &edge : bisection_graph.Edges(node))
edge.target = mapping[edge.target];
});
std::for_each(bisection_graph.Begin(),
bisection_graph.End(),
[&](const auto &node)
{
for (auto &edge : bisection_graph.Edges(node))
edge.target = mapping[edge.target];
});
std::vector<BisectionGraphView> views;
auto last = bisection_graph.CBegin();
@@ -139,7 +149,8 @@ RecursiveBisectionState::PrePartitionWithSCC(const std::size_t small_component_s
}
views.push_back(BisectionGraphView(bisection_graph, last, bisection_graph.CEnd()));
bool has_small_component = [&]() {
bool has_small_component = [&]()
{
for (std::size_t i = 0; i < scc_algo.GetNumberOfComponents(); ++i)
if (scc_algo.GetComponentSize(i) <= small_component_size)
return true;
@@ -154,7 +165,8 @@ RecursiveBisectionState::PrePartitionWithSCC(const std::size_t small_component_s
// ceil(log_2(components))
scc_levels = ceil(log(views.size()) / log(2.0));
const auto conscutive_component_id = [&](const NodeID nid) {
const auto conscutive_component_id = [&](const NodeID nid)
{
const auto component_id = transform_id(nid);
const auto itr = ordered_component_ids.find(component_id);
BOOST_ASSERT(itr != ordered_component_ids.end());
+8 -8
View File
@@ -46,10 +46,10 @@ std::vector<std::uint32_t> makePermutation(const DynamicEdgeBasedGraph &graph,
// Nodes in the same cell will be sorted by cell ID on the level below
for (const auto &partition : partitions)
{
std::stable_sort(
ordering.begin(), ordering.end(), [&partition](const auto lhs, const auto rhs) {
return partition[lhs] < partition[rhs];
});
std::stable_sort(ordering.begin(),
ordering.end(),
[&partition](const auto lhs, const auto rhs)
{ return partition[lhs] < partition[rhs]; });
}
// Now sort the nodes by the level at which they are a border node, descening.
@@ -57,10 +57,10 @@ std::vector<std::uint32_t> makePermutation(const DynamicEdgeBasedGraph &graph,
// whereas nodes that are nerver border nodes are sorted to the end of the array.
// Note: Since we use a stable sort that preserves the cell sorting within each level
auto border_level = getHighestBorderLevel(graph, partitions);
std::stable_sort(
ordering.begin(), ordering.end(), [&border_level](const auto lhs, const auto rhs) {
return border_level[lhs] > border_level[rhs];
});
std::stable_sort(ordering.begin(),
ordering.end(),
[&border_level](const auto lhs, const auto rhs)
{ return border_level[lhs] > border_level[rhs]; });
return util::orderingToPermutation(ordering);
}
+4 -2
View File
@@ -53,7 +53,8 @@ void validate(boost::any &v, const std::vector<std::string> &values, MaxCellSize
std::transform(std::sregex_token_iterator(s.begin(), s.end(), re, -1),
std::sregex_token_iterator(),
std::back_inserter(output),
[](const auto &x) {
[](const auto &x)
{
try
{
return boost::lexical_cast<std::size_t>(x);
@@ -215,7 +216,8 @@ try
return EXIT_FAILURE;
}
auto check_file = [](const boost::filesystem::path &path) {
auto check_file = [](const boost::filesystem::path &path)
{
if (!boost::filesystem::is_regular_file(path))
{
util::Log(logERROR) << "Input file " << path << " not found!";
+6 -4
View File
@@ -343,10 +343,12 @@ try
}
else
{
std::packaged_task<int()> server_task([&] {
routing_server->Run();
return 0;
});
std::packaged_task<int()> server_task(
[&]
{
routing_server->Run();
return 0;
});
auto future = server_task.get_future();
std::thread server_thread(std::move(server_task));
+3 -3
View File
@@ -39,9 +39,9 @@ SegmentLookupTable readSegmentValues(const std::vector<std::string> &paths)
// Check consistency of keys in the result lookup table
auto result = parser(paths);
const auto found_inconsistency =
std::find_if(std::begin(result.lookup), std::end(result.lookup), [](const auto &entry) {
return entry.first.from == entry.first.to;
});
std::find_if(std::begin(result.lookup),
std::end(result.lookup),
[](const auto &entry) { return entry.first.from == entry.first.to; });
if (found_inconsistency != std::end(result.lookup))
{
util::Log(logWARNING) << "Empty segment in CSV with node " +
+125 -108
View File
@@ -155,10 +155,11 @@ updateSegmentData(const UpdaterConfig &config,
// closure to convert SpeedSource value to weight and count fallbacks to durations
std::atomic<std::uint32_t> fallbacks_to_duration{0};
auto convertToWeight = [&profile_properties,
&fallbacks_to_duration](const SegmentWeight &existing_weight,
const SpeedSource &value,
double distance_in_meters) {
auto convertToWeight =
[&profile_properties, &fallbacks_to_duration](const SegmentWeight &existing_weight,
const SpeedSource &value,
double distance_in_meters)
{
double rate = std::numeric_limits<double>::quiet_NaN();
// if value.rate is not set, we fall back to duration
@@ -211,96 +212,104 @@ updateSegmentData(const UpdaterConfig &config,
using DirectionalGeometryID = extractor::SegmentDataContainer::DirectionalGeometryID;
auto range = tbb::blocked_range<DirectionalGeometryID>(0, segment_data.GetNumberOfGeometries());
tbb::parallel_for(range, [&](const auto &range) {
auto &counters = segment_speeds_counters.local();
std::vector<double> segment_lengths;
for (auto geometry_id = range.begin(); geometry_id < range.end(); geometry_id++)
tbb::parallel_for(
range,
[&](const auto &range)
{
auto nodes_range = segment_data.GetForwardGeometry(geometry_id);
segment_lengths.clear();
segment_lengths.reserve(nodes_range.size() + 1);
util::for_each_pair(nodes_range, [&](const auto &u, const auto &v) {
segment_lengths.push_back(util::coordinate_calculation::greatCircleDistance(
coordinates[u], coordinates[v]));
});
auto fwd_weights_range = segment_data.GetForwardWeights(geometry_id);
auto fwd_durations_range = segment_data.GetForwardDurations(geometry_id);
auto fwd_datasources_range = segment_data.GetForwardDatasources(geometry_id);
bool fwd_was_updated = false;
for (const auto segment_offset : util::irange<std::size_t>(0, fwd_weights_range.size()))
auto &counters = segment_speeds_counters.local();
std::vector<double> segment_lengths;
for (auto geometry_id = range.begin(); geometry_id < range.end(); geometry_id++)
{
auto u = osm_node_ids[nodes_range[segment_offset]];
auto v = osm_node_ids[nodes_range[segment_offset + 1]];
auto nodes_range = segment_data.GetForwardGeometry(geometry_id);
// Self-loops are artifical segments (e.g. traffic light nodes), do not
// waste time updating them with traffic data
if (u == v)
continue;
segment_lengths.clear();
segment_lengths.reserve(nodes_range.size() + 1);
util::for_each_pair(nodes_range,
[&](const auto &u, const auto &v)
{
segment_lengths.push_back(
util::coordinate_calculation::greatCircleDistance(
coordinates[u], coordinates[v]));
});
if (auto value = segment_speed_lookup({u, v}))
auto fwd_weights_range = segment_data.GetForwardWeights(geometry_id);
auto fwd_durations_range = segment_data.GetForwardDurations(geometry_id);
auto fwd_datasources_range = segment_data.GetForwardDatasources(geometry_id);
bool fwd_was_updated = false;
for (const auto segment_offset :
util::irange<std::size_t>(0, fwd_weights_range.size()))
{
auto segment_length = segment_lengths[segment_offset];
auto new_duration = convertToDuration(value->speed, segment_length);
auto new_weight =
convertToWeight(fwd_weights_range[segment_offset], *value, segment_length);
fwd_was_updated = true;
auto u = osm_node_ids[nodes_range[segment_offset]];
auto v = osm_node_ids[nodes_range[segment_offset + 1]];
fwd_weights_range[segment_offset] = new_weight;
fwd_durations_range[segment_offset] = new_duration;
fwd_datasources_range[segment_offset] = value->source;
counters[value->source] += 1;
// Self-loops are artifical segments (e.g. traffic light nodes), do not
// waste time updating them with traffic data
if (u == v)
continue;
if (auto value = segment_speed_lookup({u, v}))
{
auto segment_length = segment_lengths[segment_offset];
auto new_duration = convertToDuration(value->speed, segment_length);
auto new_weight = convertToWeight(
fwd_weights_range[segment_offset], *value, segment_length);
fwd_was_updated = true;
fwd_weights_range[segment_offset] = new_weight;
fwd_durations_range[segment_offset] = new_duration;
fwd_datasources_range[segment_offset] = value->source;
counters[value->source] += 1;
}
else
{
counters[LUA_SOURCE] += 1;
}
}
else
if (fwd_was_updated)
updated_segments.push_back(GeometryID{geometry_id, true});
// In this case we want it oriented from in forward directions
auto rev_weights_range =
boost::adaptors::reverse(segment_data.GetReverseWeights(geometry_id));
auto rev_durations_range =
boost::adaptors::reverse(segment_data.GetReverseDurations(geometry_id));
auto rev_datasources_range =
boost::adaptors::reverse(segment_data.GetReverseDatasources(geometry_id));
bool rev_was_updated = false;
for (const auto segment_offset :
util::irange<std::size_t>(0, rev_weights_range.size()))
{
counters[LUA_SOURCE] += 1;
auto u = osm_node_ids[nodes_range[segment_offset]];
auto v = osm_node_ids[nodes_range[segment_offset + 1]];
// Self-loops are artifical segments (e.g. traffic light nodes), do not
// waste time updating them with traffic data
if (u == v)
continue;
if (auto value = segment_speed_lookup({v, u}))
{
auto segment_length = segment_lengths[segment_offset];
auto new_duration = convertToDuration(value->speed, segment_length);
auto new_weight = convertToWeight(
rev_weights_range[segment_offset], *value, segment_length);
rev_was_updated = true;
rev_weights_range[segment_offset] = new_weight;
rev_durations_range[segment_offset] = new_duration;
rev_datasources_range[segment_offset] = value->source;
counters[value->source] += 1;
}
else
{
counters[LUA_SOURCE] += 1;
}
}
if (rev_was_updated)
updated_segments.push_back(GeometryID{geometry_id, false});
}
if (fwd_was_updated)
updated_segments.push_back(GeometryID{geometry_id, true});
// In this case we want it oriented from in forward directions
auto rev_weights_range =
boost::adaptors::reverse(segment_data.GetReverseWeights(geometry_id));
auto rev_durations_range =
boost::adaptors::reverse(segment_data.GetReverseDurations(geometry_id));
auto rev_datasources_range =
boost::adaptors::reverse(segment_data.GetReverseDatasources(geometry_id));
bool rev_was_updated = false;
for (const auto segment_offset : util::irange<std::size_t>(0, rev_weights_range.size()))
{
auto u = osm_node_ids[nodes_range[segment_offset]];
auto v = osm_node_ids[nodes_range[segment_offset + 1]];
// Self-loops are artifical segments (e.g. traffic light nodes), do not
// waste time updating them with traffic data
if (u == v)
continue;
if (auto value = segment_speed_lookup({v, u}))
{
auto segment_length = segment_lengths[segment_offset];
auto new_duration = convertToDuration(value->speed, segment_length);
auto new_weight =
convertToWeight(rev_weights_range[segment_offset], *value, segment_length);
rev_was_updated = true;
rev_weights_range[segment_offset] = new_weight;
rev_durations_range[segment_offset] = new_duration;
rev_datasources_range[segment_offset] = value->source;
counters[value->source] += 1;
}
else
{
counters[LUA_SOURCE] += 1;
}
}
if (rev_was_updated)
updated_segments.push_back(GeometryID{geometry_id, false});
}
}); // parallel_for
}); // parallel_for
counters_type merged_counters(num_counters, 0);
for (const auto &counters : segment_speeds_counters)
@@ -587,20 +596,22 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
if (update_edge_weights || update_turn_penalties || update_conditional_turns)
{
tbb::parallel_invoke(
[&] {
extractor::files::readSegmentData(config.GetPath(".osrm.geometry"), segment_data);
},
[&]
{ extractor::files::readSegmentData(config.GetPath(".osrm.geometry"), segment_data); },
[&] { extractor::files::readNodeData(config.GetPath(".osrm.ebg_nodes"), node_data); },
[&] {
[&]
{
extractor::files::readTurnWeightPenalty(
config.GetPath(".osrm.turn_weight_penalties"), turn_weight_penalties);
},
[&] {
[&]
{
extractor::files::readTurnDurationPenalty(
config.GetPath(".osrm.turn_duration_penalties"), turn_duration_penalties);
},
[&] {
[&]
{
extractor::files::readProfileProperties(config.GetPath(".osrm.properties"),
profile_properties);
});
@@ -647,7 +658,8 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
std::transform(updated_turn_penalties.begin(),
updated_turn_penalties.end(),
updated_segments.begin() + offset,
[&node_data, &edge_based_edge_list](const std::uint64_t turn_id) {
[&node_data, &edge_based_edge_list](const std::uint64_t turn_id)
{
const auto node_id = edge_based_edge_list[turn_id].source;
return node_data.GetGeometryID(node_id);
});
@@ -672,7 +684,8 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
std::transform(updated_turn_penalties.begin(),
updated_turn_penalties.end(),
updated_segments.begin() + offset,
[&node_data, &edge_based_edge_list](const std::uint64_t turn_id) {
[&node_data, &edge_based_edge_list](const std::uint64_t turn_id)
{
const auto node_id = edge_based_edge_list[turn_id].source;
return node_data.GetGeometryID(node_id);
});
@@ -680,13 +693,13 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
tbb::parallel_sort(updated_segments.begin(),
updated_segments.end(),
[](const GeometryID lhs, const GeometryID rhs) {
return std::tie(lhs.id, lhs.forward) < std::tie(rhs.id, rhs.forward);
});
[](const GeometryID lhs, const GeometryID rhs)
{ return std::tie(lhs.id, lhs.forward) < std::tie(rhs.id, rhs.forward); });
using WeightAndDuration = std::tuple<EdgeWeight, EdgeDuration>;
const auto compute_new_weight_and_duration =
[&](const GeometryID geometry_id) -> WeightAndDuration {
[&](const GeometryID geometry_id) -> WeightAndDuration
{
EdgeWeight new_weight = {0};
EdgeDuration new_duration = {0};
if (geometry_id.forward)
@@ -728,7 +741,8 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
std::vector<WeightAndDuration> accumulated_segment_data(updated_segments.size());
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, updated_segments.size()),
[&](const auto &range) {
[&](const auto &range)
{
for (auto index = range.begin(); index < range.end(); ++index)
{
accumulated_segment_data[index] =
@@ -736,16 +750,16 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
}
});
const auto update_edge = [&](extractor::EdgeBasedEdge &edge) {
const auto update_edge = [&](extractor::EdgeBasedEdge &edge)
{
const auto node_id = edge.source;
const auto geometry_id = node_data.GetGeometryID(node_id);
auto updated_iter = std::lower_bound(updated_segments.begin(),
updated_segments.end(),
geometry_id,
[](const GeometryID lhs, const GeometryID rhs) {
return std::tie(lhs.id, lhs.forward) <
std::tie(rhs.id, rhs.forward);
});
auto updated_iter = std::lower_bound(
updated_segments.begin(),
updated_segments.end(),
geometry_id,
[](const GeometryID lhs, const GeometryID rhs)
{ return std::tie(lhs.id, lhs.forward) < std::tie(rhs.id, rhs.forward); });
if (updated_iter != updated_segments.end() && updated_iter->id == geometry_id.id &&
updated_iter->forward == geometry_id.forward)
{
@@ -806,7 +820,8 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
if (updated_segments.size() > 0)
{
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, edge_based_edge_list.size()),
[&](const auto &range) {
[&](const auto &range)
{
for (auto index = range.begin(); index < range.end(); ++index)
{
update_edge(edge_based_edge_list[index]);
@@ -817,11 +832,13 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
if (update_turn_penalties || update_conditional_turns)
{
tbb::parallel_invoke(
[&] {
[&]
{
extractor::files::writeTurnWeightPenalty(
config.GetPath(".osrm.turn_weight_penalties"), turn_weight_penalties);
},
[&] {
[&]
{
extractor::files::writeTurnDurationPenalty(
config.GetPath(".osrm.turn_duration_penalties"), turn_duration_penalties);
});
+7 -7
View File
@@ -317,7 +317,8 @@ double findClosestDistance(const std::vector<Coordinate> &lhs, const std::vector
{
double current_min = std::numeric_limits<double>::max();
const auto compute_minimum_distance_in_rhs = [&current_min, &rhs](const Coordinate coordinate) {
const auto compute_minimum_distance_in_rhs = [&current_min, &rhs](const Coordinate coordinate)
{
current_min =
std::min(current_min, findClosestDistance(coordinate, rhs.begin(), rhs.end()));
return false;
@@ -331,9 +332,8 @@ double findClosestDistance(const std::vector<Coordinate> &lhs, const std::vector
std::vector<double> getDeviations(const std::vector<Coordinate> &from,
const std::vector<Coordinate> &to)
{
auto find_deviation = [&to](const Coordinate coordinate) {
return findClosestDistance(coordinate, to.begin(), to.end());
};
auto find_deviation = [&to](const Coordinate coordinate)
{ return findClosestDistance(coordinate, to.begin(), to.end()); };
std::vector<double> deviations_from;
deviations_from.reserve(from.size());
@@ -385,9 +385,9 @@ double computeArea(const std::vector<Coordinate> &polygon)
// ⚠ ref_latitude is the standard parallel for the equirectangular projection
// that is not an area-preserving projection
const auto ref_point =
std::min_element(polygon.begin(), polygon.end(), [](const auto &lhs, const auto &rhs) {
return lhs.lat < rhs.lat;
});
std::min_element(polygon.begin(),
polygon.end(),
[](const auto &lhs, const auto &rhs) { return lhs.lat < rhs.lat; });
const auto ref_latitude = ref_point->lat;
// Compute area of under a curve and a line that is parallel the equator with ref_latitude
+2 -1
View File
@@ -73,7 +73,8 @@ void Log::Init()
{
const bool is_terminal = IsStdoutATTY();
auto format = [is_terminal](const char *level, const char *color) {
auto format = [is_terminal](const char *level, const char *color)
{
const auto timestamp = std::chrono::system_clock::now();
return fmt::format("{}[{:%FT%H:%M:}{:%S}] [{}] ",
is_terminal ? color : "",
+3 -7
View File
@@ -327,13 +327,9 @@ struct opening_hours_grammar : qi::grammar<Iterator, Skipper, std::vector<Openin
// clang-format on
BOOST_SPIRIT_DEBUG_NODES((time_domain)(rule_sequence)(any_rule_separator)(
selector_sequence)(wide_range_selectors)(small_range_selectors)(time_selector)(
timespan)(time)(extended_time)(variable_time)(weekday_selector)(weekday_sequence)(
weekday_range)(holiday_sequence)(nth_entry)(nth)(day_offset)(week_selector)(week)(
monthday_selector)(monthday_range)(date_offset)(date_from)(date_to)(variable_date)(
year_selector)(year_range)(plus_or_minus)(hour_minutes)(extended_hour_minutes)(comment)(
hour)(extended_hour)(minute)(daynum)(weeknum)(year));
BOOST_SPIRIT_DEBUG_NODES(
(
time_domain)(rule_sequence)(any_rule_separator)(selector_sequence)(wide_range_selectors)(small_range_selectors)(time_selector)(timespan)(time)(extended_time)(variable_time)(weekday_selector)(weekday_sequence)(weekday_range)(holiday_sequence)(nth_entry)(nth)(day_offset)(week_selector)(week)(monthday_selector)(monthday_range)(date_offset)(date_from)(date_to)(variable_date)(year_selector)(year_range)(plus_or_minus)(hour_minutes)(extended_hour_minutes)(comment)(hour)(extended_hour)(minute)(daynum)(weeknum)(year));
}
qi::rule<Iterator, Skipper, std::vector<OpeningHours>()> time_domain;
+2 -1
View File
@@ -79,7 +79,8 @@ void Timezoner::LoadLocalTimesRTree(rapidjson::Document &geojson, std::time_t ut
// Lambda function that returns local time in the tzname time zone
// Thread safety: MT-Unsafe const:env
std::unordered_map<std::string, struct tm> local_time_memo;
auto get_local_time_in_tz = [utc_time, &local_time_memo](const char *tzname) {
auto get_local_time_in_tz = [utc_time, &local_time_memo](const char *tzname)
{
auto it = local_time_memo.find(tzname);
if (it == local_time_memo.end())
{