refactor route step / intermediate intersections

rename intersection (engine version) to IntermediateIntersection
follow coding convention for existing functions, move invalidate into routeStep
moved elongate into route step
move forward-step-signage into route step
replace post-processings `forwardInto` with `RouteStep` functionality. Don't change maneuver in step
separete declaration and implementation
This commit is contained in:
Moritz Kobitzsch 2016-12-20 14:57:08 +01:00
parent 3cbac0f012
commit bc081b7132
11 changed files with 230 additions and 234 deletions

View File

@ -302,16 +302,16 @@ class GraphContractor
util::UnbufferedLog log;
log << "initializing elimination PQ ...";
tbb::parallel_for(
tbb::blocked_range<NodeID>(0, number_of_nodes, PQGrainSize),
[this, &node_priorities, &node_depth, &thread_data_list](
const tbb::blocked_range<NodeID> &range) {
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto x = range.begin(), end = range.end(); x != end; ++x)
{
node_priorities[x] = this->EvaluateNodePriority(data, node_depth[x], x);
}
});
tbb::parallel_for(tbb::blocked_range<NodeID>(0, number_of_nodes, PQGrainSize),
[this, &node_priorities, &node_depth, &thread_data_list](
const tbb::blocked_range<NodeID> &range) {
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto x = range.begin(), end = range.end(); x != end; ++x)
{
node_priorities[x] =
this->EvaluateNodePriority(data, node_depth[x], x);
}
});
log << "ok";
}
BOOST_ASSERT(node_priorities.size() == number_of_nodes);
@ -552,8 +552,7 @@ class GraphContractor
[this, &node_priorities, &remaining_nodes, &node_depth, &thread_data_list](
const tbb::blocked_range<NodeID> &range) {
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto position = range.begin(), end = range.end();
position != end;
for (auto position = range.begin(), end = range.end(); position != end;
++position)
{
NodeID x = remaining_nodes[position].id;

View File

@ -70,13 +70,13 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
WaypointType::Depart,
0};
Intersection intersection{source_node.location,
std::vector<short>({bearings.second}),
std::vector<bool>({true}),
Intersection::NO_INDEX,
0,
util::guidance::LaneTuple(),
{}};
IntermediateIntersection intersection{source_node.location,
std::vector<short>({bearings.second}),
std::vector<bool>({true}),
IntermediateIntersection::NO_INDEX,
0,
util::guidance::LaneTuple(),
{}};
if (leg_data.size() > 0)
{
@ -218,7 +218,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
std::vector<short>({static_cast<short>(util::reverseBearing(bearings.first))}),
std::vector<bool>({true}),
0,
Intersection::NO_INDEX,
IntermediateIntersection::NO_INDEX,
util::guidance::LaneTuple(),
{}};

View File

@ -30,10 +30,6 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps);
// maneuvers that can, in some form, be seen as one. Lookahead of one step.
bool collapsable(const RouteStep &step, const RouteStep &next);
// Elongate a step by another. the data is added either at the front, or the back
OSRM_ATTR_WARN_UNUSED
RouteStep elongate(RouteStep step, const RouteStep &by_step);
// trim initial/final segment of very short length.
// This function uses in/out parameter passing to modify both steps and geometry in place.
// We use this method since both steps and geometry are closely coupled logically but

View File

@ -30,7 +30,7 @@ namespace guidance
// Arrive: a --> b --> t. The segment (b,t) is already covered by the previous segment.
// A representation of intermediate intersections
struct Intersection
struct IntermediateIntersection
{
static const constexpr std::size_t NO_INDEX = std::numeric_limits<std::size_t>::max();
util::Coordinate location;
@ -44,13 +44,13 @@ struct Intersection
extractor::guidance::TurnLaneDescription lane_description;
};
inline Intersection getInvalidIntersection()
inline IntermediateIntersection getInvalidIntersection()
{
return {util::Coordinate{util::FloatLongitude{0.0}, util::FloatLatitude{0.0}},
{},
{},
Intersection::NO_INDEX,
Intersection::NO_INDEX,
IntermediateIntersection::NO_INDEX,
IntermediateIntersection::NO_INDEX,
util::guidance::LaneTuple(),
{}};
}
@ -71,55 +71,135 @@ struct RouteStep
// indices into the locations array stored the LegGeometry
std::size_t geometry_begin;
std::size_t geometry_end;
std::vector<Intersection> intersections;
std::vector<IntermediateIntersection> intersections;
LaneID numLanesToTheRight() const
{
return intersections.front().lanes.first_lane_from_the_right;
}
// remove all information from the route step, marking it as invalid (used to indicate empty
// steps to be removed).
void Invalidate();
LaneID numLanesToTheLeft() const
{
LaneID const total = intersections.front().lane_description.size();
return total - (intersections.front().lanes.lanes_in_turn +
intersections.front().lanes.first_lane_from_the_right);
}
// Elongate by another step in front
RouteStep &AddInFront(const RouteStep &preceeding_step);
auto lanesToTheLeft() const
{
const auto &description = intersections.front().lane_description;
LaneID num_lanes_left = numLanesToTheLeft();
return boost::make_iterator_range(description.begin(),
description.begin() + num_lanes_left);
}
// Elongate by another step in back
RouteStep &ElongateBy(const RouteStep &following_step);
auto lanesToTheRight() const
{
const auto &description = intersections.front().lane_description;
LaneID num_lanes_right = numLanesToTheRight();
return boost::make_iterator_range(description.end() - num_lanes_right, description.end());
}
/* Elongate without prior knowledge of in front, or in back, convenience function if you
* don't know if step is augmented in front or at the back */
RouteStep &MergeWith(const RouteStep &by_step);
// copy all strings from origin into the step, apart from rotary names
RouteStep &AdaptStepSignage(const RouteStep &origin);
LaneID NumLanesToTheRight() const;
LaneID NumLanesToTheLeft() const;
auto LanesToTheLeft() const;
auto LanesToTheRight() const;
};
inline RouteStep getInvalidRouteStep()
inline void RouteStep::Invalidate()
{
return {0,
"",
"",
"",
"",
"",
"",
0,
0,
TRAVEL_MODE_INACCESSIBLE,
getInvalidStepManeuver(),
0,
0,
{getInvalidIntersection()}};
}
}
}
name_id = EMPTY_NAMEID;
name.clear();
ref.clear();
pronunciation.clear();
destinations.clear();
rotary_name.clear();
rotary_pronunciation.clear();
duration = 0;
distance = 0;
mode = TRAVEL_MODE_INACCESSIBLE;
maneuver = getInvalidStepManeuver();
geometry_begin = 0;
geometry_end = 0;
intersections.clear();
intersections.push_back(getInvalidIntersection());
}
// Elongate by another step in front
inline RouteStep &RouteStep::AddInFront(const RouteStep &preceeding_step)
{
BOOST_ASSERT(preceeding_step.geometry_end == geometry_begin + 1);
BOOST_ASSERT(mode == preceeding_step.mode);
duration += preceeding_step.duration;
distance += preceeding_step.distance;
geometry_begin = preceeding_step.geometry_begin;
intersections.insert(intersections.begin(),
preceeding_step.intersections.begin(),
preceeding_step.intersections.end());
return *this;
}
// Elongate by another step in back
inline RouteStep &RouteStep::ElongateBy(const RouteStep &following_step)
{
BOOST_ASSERT(geometry_end == following_step.geometry_begin + 1);
BOOST_ASSERT(mode == following_step.mode);
duration += following_step.duration;
distance += following_step.distance;
geometry_end = following_step.geometry_end;
intersections.insert(intersections.end(),
following_step.intersections.begin(),
following_step.intersections.end());
return *this;
}
// Elongate without prior knowledge of in front, or in back.
inline RouteStep &RouteStep::MergeWith(const RouteStep &by_step)
{
// if our own geometry ends, where the next begins, we elongate by
if (geometry_end == by_step.geometry_begin + 1)
return AddInFront(by_step);
else
return ElongateBy(by_step);
}
// copy all strings from origin into the step, apart from rotary names
inline RouteStep &RouteStep::AdaptStepSignage(const RouteStep &origin)
{
name_id = origin.name_id;
name = origin.name;
pronunciation = origin.pronunciation;
destinations = origin.destinations;
ref = origin.ref;
return *this;
}
inline LaneID RouteStep::NumLanesToTheRight() const
{
return intersections.front().lanes.first_lane_from_the_right;
}
inline LaneID RouteStep::NumLanesToTheLeft() const
{
LaneID const total = intersections.front().lane_description.size();
return total - (intersections.front().lanes.lanes_in_turn +
intersections.front().lanes.first_lane_from_the_right);
}
inline auto RouteStep::LanesToTheLeft() const
{
const auto &description = intersections.front().lane_description;
LaneID num_lanes_left = NumLanesToTheLeft();
return boost::make_iterator_range(description.begin(), description.begin() + num_lanes_left);
}
inline auto RouteStep::LanesToTheRight() const
{
const auto &description = intersections.front().lane_description;
LaneID num_lanes_right = NumLanesToTheRight();
return boost::make_iterator_range(description.end() - num_lanes_right, description.end());
}
} // namespace guidance
} // namespace engine
} // namespace osrm
#endif

View File

@ -60,7 +60,7 @@ inline bool isValidModifier(const guidance::StepManeuver maneuver)
maneuver.instruction.direction_modifier != DirectionModifier::UTurn);
}
inline bool hasValidLanes(const guidance::Intersection &intersection)
inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection)
{
return intersection.lanes.lanes_in_turn > 0;
}
@ -72,7 +72,7 @@ std::string instructionTypeToString(const TurnType::Enum type)
return turn_type_names[static_cast<std::size_t>(type)];
}
util::json::Array lanesFromIntersection(const guidance::Intersection &intersection)
util::json::Array lanesFromIntersection(const guidance::IntermediateIntersection &intersection)
{
BOOST_ASSERT(intersection.lanes.lanes_in_turn >= 1);
util::json::Array result;
@ -200,7 +200,7 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
return step_maneuver;
}
util::json::Object makeIntersection(const guidance::Intersection &intersection)
util::json::Object makeIntersection(const guidance::IntermediateIntersection &intersection)
{
util::json::Object result;
util::json::Array bearings;
@ -226,9 +226,9 @@ util::json::Object makeIntersection(const guidance::Intersection &intersection)
result.values["location"] = detail::coordinateToLonLat(intersection.location);
result.values["bearings"] = bearings;
result.values["entry"] = entry;
if (intersection.in != guidance::Intersection::NO_INDEX)
if (intersection.in != guidance::IntermediateIntersection::NO_INDEX)
result.values["in"] = intersection.in;
if (intersection.out != guidance::Intersection::NO_INDEX)
if (intersection.out != guidance::IntermediateIntersection::NO_INDEX)
result.values["out"] = intersection.out;
if (detail::hasValidLanes(intersection))

View File

@ -78,8 +78,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
// 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();
const LaneID current_num_lanes_right_of_turn = current.NumLanesToTheRight();
const LaneID current_num_lanes_left_of_turn = current.NumLanesToTheLeft();
const LaneID num_shared_lanes = std::min(current_lanes.lanes_in_turn, //
previous_lanes.lanes_in_turn); //
@ -166,7 +166,7 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
// step as invalid, scheduled for later removal.
if (collapsable(previous, current))
{
previous = elongate(previous, current);
previous.ElongateBy(current);
current.maneuver.instruction = TurnInstruction::NO_TURN();
}
});

View File

@ -50,18 +50,6 @@ inline bool hasManeuver(const RouteStep &first, const RouteStep &second)
second.maneuver.instruction.type != TurnType::NoTurn);
}
// forward all signage/name data from one step to another.
// When we collapse a step, we might have to transfer the name, pronunciation and similar tags.
inline void forwardStepSignage(RouteStep &destination, const RouteStep &origin)
{
destination.name_id = origin.name_id;
destination.name = origin.name;
destination.pronunciation = origin.pronunciation;
destination.destinations = origin.destinations;
destination.destinations = origin.destinations;
destination.ref = origin.ref;
}
inline bool choiceless(const RouteStep &step, const RouteStep &previous)
{
// if the next turn is choiceless, we consider longer turn roads collapsable than usually
@ -90,9 +78,6 @@ bool isCollapsableInstruction(const TurnInstruction instruction)
bool compatible(const RouteStep &lhs, const RouteStep &rhs) { return lhs.mode == rhs.mode; }
// invalidate a step and set its content to nothing
void invalidateStep(RouteStep &step) { step = getInvalidRouteStep(); }
// Checks if name change happens the user wants to know about.
// Treats e.g. "Name (Ref)" -> "Name" changes still as same name.
bool isNoticeableNameChange(const RouteStep &lhs, const RouteStep &rhs)
@ -115,32 +100,6 @@ double nameSegmentLength(std::size_t at, const std::vector<RouteStep> &steps)
return result;
}
OSRM_ATTR_WARN_UNUSED
RouteStep forwardInto(RouteStep destination, const RouteStep &source)
{
// Merge a turn into a silent turn
// Overwrites turn instruction and increases exit NR
destination.duration += source.duration;
destination.distance += source.distance;
destination.maneuver.exit = source.maneuver.exit;
if (destination.geometry_begin < source.geometry_begin)
{
destination.intersections.insert(destination.intersections.end(),
source.intersections.begin(),
source.intersections.end());
}
else
{
destination.intersections.insert(destination.intersections.begin(),
source.intersections.begin(),
source.intersections.end());
}
destination.geometry_begin = std::min(destination.geometry_begin, source.geometry_begin);
destination.geometry_end = std::max(destination.geometry_end, source.geometry_end);
return destination;
}
void fixFinalRoundabout(std::vector<RouteStep> &steps)
{
for (std::size_t propagation_index = steps.size() - 1; propagation_index > 0;
@ -173,9 +132,9 @@ void fixFinalRoundabout(std::vector<RouteStep> &steps)
// TODO this operates on the data that is in the instructions.
// We are missing out on the final segment after the last stay-on-roundabout
// instruction though. it is not contained somewhere until now
steps[propagation_index - 1] =
forwardInto(std::move(steps[propagation_index - 1]), propagation_step);
invalidateStep(propagation_step);
steps[propagation_index - 1].ElongateBy(propagation_step);
steps[propagation_index - 1].maneuver.exit = propagation_step.maneuver.exit;
propagation_step.Invalidate();
}
}
}
@ -240,7 +199,7 @@ void closeOffRoundabout(const bool on_roundabout,
steps[1].maneuver.instruction.type == TurnType::UseLane);
steps[0].geometry_end = 1;
steps[1].geometry_begin = 0;
steps[1] = forwardInto(steps[1], steps[0]);
steps[1].AddInFront(steps[0]);
steps[1].intersections.erase(steps[1].intersections.begin()); // otherwise we copy the
// source
if (leavesRoundabout(steps[1].maneuver.instruction))
@ -282,7 +241,8 @@ void closeOffRoundabout(const bool on_roundabout,
--propagation_index)
{
auto &propagation_step = steps[propagation_index];
propagation_step = forwardInto(propagation_step, steps[propagation_index + 1]);
propagation_step.ElongateBy(steps[propagation_index + 1]);
propagation_step.maneuver.exit = steps[propagation_index + 1].maneuver.exit;
if (entersRoundabout(propagation_step.maneuver.instruction))
{
const auto entry_intersection = propagation_step.intersections.front();
@ -309,13 +269,13 @@ void closeOffRoundabout(const bool on_roundabout,
getTurnDirection(angle);
}
forwardStepSignage(propagation_step, destination_copy);
invalidateStep(steps[propagation_index + 1]);
propagation_step.AdaptStepSignage(destination_copy);
steps[propagation_index + 1].Invalidate();
break;
}
else
{
invalidateStep(steps[propagation_index + 1]);
steps[propagation_index + 1].Invalidate();
}
}
// remove exit
@ -445,19 +405,18 @@ void collapseUTurn(std::vector<RouteStep> &steps,
if (direct_u_turn || u_turn_with_name_change)
{
steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]);
invalidateStep(steps[step_index]);
steps[one_back_index].ElongateBy(steps[step_index]);
steps[step_index].Invalidate();
if (u_turn_with_name_change)
{
BOOST_ASSERT_MSG(compatible(steps[one_back_index], steps[next_step_index]),
"Compatibility should be transitive");
steps[one_back_index] =
elongate(std::move(steps[one_back_index]), steps[next_step_index]);
invalidateStep(steps[next_step_index]); // will be skipped due to the
// continue statement at the
// beginning of this function
steps[one_back_index].ElongateBy(steps[next_step_index]);
steps[next_step_index].Invalidate(); // will be skipped due to the
// continue statement at the
// beginning of this function
}
forwardStepSignage(steps[one_back_index], steps[two_back_index]);
steps[one_back_index].AdaptStepSignage(steps[two_back_index]);
steps[one_back_index].maneuver.instruction.type = TurnType::Continue;
steps[one_back_index].maneuver.instruction.direction_modifier = DirectionModifier::UTurn;
}
@ -685,15 +644,15 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
}
}
steps[two_back_index] = elongate(std::move(steps[two_back_index]), one_back_step);
steps[two_back_index].ElongateBy(one_back_step);
// If the previous instruction asked to continue, the name change will have to
// be changed into a turn
invalidateStep(steps[one_back_index]);
steps[one_back_index].Invalidate();
}
// very short segment after turn, turn location remains at one_back_step
else if (isDelayedTurn(one_back_step, current_step)) // checks for compatibility
{
steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]);
steps[one_back_index].ElongateBy(steps[step_index]);
// TODO check for lanes (https://github.com/Project-OSRM/osrm-backend/issues/2553)
if (TurnType::Continue == one_back_step.maneuver.instruction.type &&
isNoticeableNameChange(steps[two_back_index], current_step))
@ -723,7 +682,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
steps[one_back_index].maneuver.instruction.direction_modifier =
DirectionModifier::UTurn;
}
forwardStepSignage(steps[one_back_index], current_step);
steps[one_back_index].AdaptStepSignage(current_step);
}
else if (TurnType::NewName == one_back_step.maneuver.instruction.type ||
(TurnType::NewName == current_step.maneuver.instruction.type &&
@ -749,30 +708,29 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
steps[one_back_index].name = current_step.name;
steps[one_back_index].name_id = current_step.name_id;
invalidateStep(steps[step_index]);
steps[step_index].Invalidate();
}
else if (TurnType::Suppressed == current_step.maneuver.instruction.type &&
!isNoticeableNameChange(one_back_step, current_step) &&
compatible(one_back_step, current_step))
{
steps[one_back_index] = elongate(std::move(steps[one_back_index]), current_step);
steps[one_back_index].ElongateBy(current_step);
const auto angle = findTotalTurnAngle(one_back_step, current_step);
steps[one_back_index].maneuver.instruction.direction_modifier = getTurnDirection(angle);
invalidateStep(steps[step_index]);
steps[step_index].Invalidate();
}
else if (TurnType::Turn == one_back_step.maneuver.instruction.type &&
TurnType::OnRamp == current_step.maneuver.instruction.type &&
compatible(one_back_step, current_step))
{
// turning onto a ramp makes the first turn into a ramp
steps[one_back_index] = elongate(std::move(steps[one_back_index]), current_step);
steps[one_back_index].ElongateBy(current_step);
steps[one_back_index].maneuver.instruction.type = TurnType::OnRamp;
const auto angle = findTotalTurnAngle(one_back_step, current_step);
steps[one_back_index].maneuver.instruction.direction_modifier = getTurnDirection(angle);
forwardStepSignage(steps[one_back_index], current_step);
invalidateStep(steps[step_index]);
steps[one_back_index].AdaptStepSignage(current_step);
steps[step_index].Invalidate();
}
}
@ -864,43 +822,6 @@ bool collapsable(const RouteStep &step, const RouteStep &next)
return false;
}
// elongate a step by another. the data is added either at the front, or the back
OSRM_ATTR_WARN_UNUSED
RouteStep elongate(RouteStep step, const RouteStep &by_step)
{
BOOST_ASSERT(step.mode == by_step.mode);
step.duration += by_step.duration;
step.distance += by_step.distance;
BOOST_ASSERT(step.mode == by_step.mode);
// by_step comes after step -> we append at the end
if (step.geometry_end == by_step.geometry_begin + 1)
{
step.geometry_end = by_step.geometry_end;
// if we elongate in the back, we only need to copy the intersections to the beginning.
// the bearings remain the same, as the location of the turn doesn't change
step.intersections.insert(
step.intersections.end(), by_step.intersections.begin(), by_step.intersections.end());
}
// by_step comes before step -> we append at the front
else
{
BOOST_ASSERT(step.maneuver.waypoint_type == WaypointType::None &&
by_step.maneuver.waypoint_type == WaypointType::None);
BOOST_ASSERT(by_step.geometry_end == step.geometry_begin + 1);
step.geometry_begin = by_step.geometry_begin;
// elongating in the front changes the location of the maneuver
step.maneuver = by_step.maneuver;
step.intersections.insert(
step.intersections.begin(), by_step.intersections.begin(), by_step.intersections.end());
}
return step;
}
// Post processing can invalidate some instructions. For example StayOnRoundabout
// is turned into exit counts. These instructions are removed by the following function
@ -1081,9 +1002,8 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
{
// Traffic light on the sliproad, the road itself will be handled in the next
// iteration, when one-back-index again points to the sliproad.
steps[one_back_index] =
elongate(std::move(steps[one_back_index]), steps[step_index]);
invalidateStep(steps[step_index]);
steps[one_back_index].ElongateBy(steps[step_index]);
steps[step_index].Invalidate();
}
else
{
@ -1110,10 +1030,9 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
else
steps[one_back_index].maneuver.instruction.type = TurnType::Turn;
steps[one_back_index] =
elongate(std::move(steps[one_back_index]), steps[step_index]);
steps[one_back_index].ElongateBy(steps[step_index]);
forwardStepSignage(steps[one_back_index], steps[step_index]);
steps[one_back_index].AdaptStepSignage(steps[step_index]);
// the turn lanes for this turn are on the sliproad itself, so we have to
// remember them
steps[one_back_index].intersections.front().lanes =
@ -1124,7 +1043,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
const auto angle = findTotalTurnAngle(one_back_step, current_step);
steps[one_back_index].maneuver.instruction.direction_modifier =
getTurnDirection(angle);
invalidateStep(steps[step_index]);
steps[step_index].Invalidate();
}
else
{
@ -1146,9 +1065,8 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
for (std::size_t index = last_available_name_index + 1; index <= step_index; ++index)
{
steps[last_available_name_index] =
elongate(std::move(steps[last_available_name_index]), steps[index]);
invalidateStep(steps[index]);
steps[last_available_name_index].ElongateBy(steps[index]);
steps[index].Invalidate();
}
}
// If we look at two consecutive name changes, we can check for a name oscillation.
@ -1166,11 +1084,11 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
{
if (compatible(one_back_step, steps[two_back_index]))
{
steps[two_back_index] =
elongate(elongate(std::move(steps[two_back_index]), steps[one_back_index]),
steps[step_index]);
invalidateStep(steps[one_back_index]);
invalidateStep(steps[step_index]);
steps[two_back_index]
.ElongateBy(steps[one_back_index])
.ElongateBy(steps[step_index]);
steps[one_back_index].Invalidate();
steps[step_index].Invalidate();
}
// TODO discuss: we could think about changing the new-name to a pure notification
// about mode changes
@ -1180,15 +1098,13 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
{
if (compatible(steps[two_back_index], steps[one_back_index]))
{
steps[two_back_index] =
elongate(std::move(steps[two_back_index]), steps[one_back_index]);
invalidateStep(steps[one_back_index]);
steps[two_back_index].ElongateBy(steps[one_back_index]);
steps[one_back_index].Invalidate();
if (nameSegmentLength(step_index, steps) < name_segment_cutoff_length &&
compatible(steps[two_back_index], steps[step_index]))
{
steps[two_back_index] =
elongate(std::move(steps[two_back_index]), steps[step_index]);
invalidateStep(steps[step_index]);
steps[two_back_index].ElongateBy(steps[step_index]);
steps[step_index].Invalidate();
}
}
}
@ -1203,11 +1119,11 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
// change,
// we don't wan't to collapse the initial intersection.
// a - b ---BRIDGE -- c
steps[one_back_index] =
elongate(std::move(steps[one_back_index]),
elongate(std::move(steps[step_index]), steps[next_step_index]));
invalidateStep(steps[step_index]);
invalidateStep(steps[next_step_index]);
steps[one_back_index]
.ElongateBy(steps[step_index])
.ElongateBy(steps[next_step_index]);
steps[step_index].Invalidate();
steps[next_step_index].Invalidate();
}
}
else if (choiceless(current_step, one_back_step) ||
@ -1350,7 +1266,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
designated_depart.intersections.front().lane_description.clear();
first_intersection.bearings = {first_intersection.bearings[first_intersection.out]};
first_intersection.entry = {true};
first_intersection.in = Intersection::NO_INDEX;
first_intersection.in = IntermediateIntersection::NO_INDEX;
first_intersection.out = 0;
// finally remove the initial (now duplicated move)
@ -1423,7 +1339,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
auto &last_intersection = next_to_last_step.intersections.back();
last_intersection.bearings = {last_intersection.bearings[last_intersection.in]};
last_intersection.entry = {true};
last_intersection.out = Intersection::NO_INDEX;
last_intersection.out = IntermediateIntersection::NO_INDEX;
last_intersection.in = 0;
steps.pop_back();
@ -1433,7 +1349,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
// as the segment before it. Thus, we have to copy the names
// and travel modes from the new next_to_last step.
auto &new_next_to_last = *(steps.end() - 2);
forwardStepSignage(next_to_last_step, new_next_to_last);
next_to_last_step.AdaptStepSignage(new_next_to_last);
next_to_last_step.mode = new_next_to_last.mode;
// the geometry indices of the last step are already correct;
}
@ -1560,10 +1476,8 @@ std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps)
BOOST_ASSERT(compatible(steps[last_valid_instruction], step));
// count intersections. We cannot use exit, since intersections can follow directly
// after a roundabout
steps[last_valid_instruction] =
elongate(std::move(steps[last_valid_instruction]), step);
step.maneuver.instruction = TurnInstruction::NO_TURN();
invalidateStep(steps[step_index]);
steps[last_valid_instruction].ElongateBy(step);
steps[step_index].Invalidate();
}
else if (!isSilent(instruction))
{
@ -1604,13 +1518,13 @@ std::vector<RouteStep> collapseUseLane(std::vector<RouteStep> steps)
// the lane description is given left to right, lanes are counted from the right.
// Therefore we access the lane description using the reverse iterator
auto right_most_lanes = step.lanesToTheRight();
auto right_most_lanes = step.LanesToTheRight();
if (!right_most_lanes.empty() && containsTag(right_most_lanes.front(),
(extractor::guidance::TurnLaneType::straight |
extractor::guidance::TurnLaneType::none)))
return false;
auto left_most_lanes = step.lanesToTheLeft();
auto left_most_lanes = step.LanesToTheLeft();
if (!left_most_lanes.empty() && containsTag(left_most_lanes.back(),
(extractor::guidance::TurnLaneType::straight |
extractor::guidance::TurnLaneType::none)))
@ -1627,8 +1541,8 @@ std::vector<RouteStep> collapseUseLane(std::vector<RouteStep> steps)
const auto previous = getPreviousIndex(step_index, steps);
if (compatible(steps[previous], step))
{
steps[previous] = elongate(std::move(steps[previous]), steps[step_index]);
invalidateStep(steps[step_index]);
steps[previous].ElongateBy(steps[step_index]);
steps[step_index].Invalidate();
}
}
}

View File

@ -130,8 +130,7 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
// fallback, mostly necessary for dead ends
if (intersection_node == to_node)
{
const auto result = ExtractCoordinateAtLength(
skipping_inaccuracies_distance, coordinates);
const auto result = ExtractCoordinateAtLength(skipping_inaccuracies_distance, coordinates);
BOOST_ASSERT(is_valid_result(result));
return result;
}

View File

@ -10,8 +10,8 @@
#include "extractor/restriction_parser.hpp"
#include "util/coordinate.hpp"
#include "util/exception.hpp"
#include "util/lua_util.hpp"
#include "util/log.hpp"
#include "util/lua_util.hpp"
#include "util/typedefs.hpp"
#include <osmium/osm.hpp>
@ -51,7 +51,7 @@ auto get_value_by_key(T const &object, const char *key) -> decltype(object.get_v
}
template <class T, class D>
const char* get_value_by_key(T const &object, const char *key, D const default_value)
const char *get_value_by_key(T const &object, const char *key, D const default_value)
{
auto v = get_value_by_key(object, key);
if (v && *v)
@ -176,8 +176,13 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
static_cast<void (std::vector<std::string>::*)(const std::string &)>(
&std::vector<std::string>::push_back));
context.state.new_usertype<osmium::Location>(
"Location", "lat", &osmium::Location::lat, "lon", &osmium::Location::lon, "valid", &osmium::Location::valid);
context.state.new_usertype<osmium::Location>("Location",
"lat",
&osmium::Location::lat,
"lon",
&osmium::Location::lon,
"valid",
&osmium::Location::valid);
context.state.new_usertype<osmium::Way>("Way",
"get_value_by_key",
@ -272,12 +277,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"lat",
&latToDouble<ExternalMemoryNode>);
context.state.new_usertype<util::Coordinate>(
"Coordinate",
"lon",
sol::property(&lonToDouble<util::Coordinate>),
"lat",
sol::property(&latToDouble<util::Coordinate>));
context.state.new_usertype<util::Coordinate>("Coordinate",
"lon",
sol::property(&lonToDouble<util::Coordinate>),
"lat",
sol::property(&latToDouble<util::Coordinate>));
context.state.new_usertype<RasterDatum>(
"RasterDatum", "datum", &RasterDatum::datum, "invalid_data", &RasterDatum::get_invalid);

View File

@ -14,7 +14,8 @@ constexpr double bearing_scale = 360.0 / 256.0;
// discretizes a bearing into distinct units of 1.4 degrees
TurnBearing::TurnBearing(const double value) : bearing(value / bearing_scale)
{
BOOST_ASSERT_MSG(value >= 0 && value < 360.0, "Bearing value needs to be between 0 and 360 (exclusive)");
BOOST_ASSERT_MSG(value >= 0 && value < 360.0,
"Bearing value needs to be between 0 and 360 (exclusive)");
}
double TurnBearing::Get() const { return bearing * bearing_scale; }

View File

@ -17,7 +17,10 @@
namespace
{
osrm::util::Coordinate getZeroCoordinate() { return {osrm::util::FloatLongitude{0}, osrm::util::FloatLatitude{0}}; }
osrm::util::Coordinate getZeroCoordinate()
{
return {osrm::util::FloatLongitude{0}, osrm::util::FloatLatitude{0}};
}
}
BOOST_AUTO_TEST_SUITE(limits)