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:
parent
3cbac0f012
commit
bc081b7132
@ -302,16 +302,16 @@ class GraphContractor
|
|||||||
|
|
||||||
util::UnbufferedLog log;
|
util::UnbufferedLog log;
|
||||||
log << "initializing elimination PQ ...";
|
log << "initializing elimination PQ ...";
|
||||||
tbb::parallel_for(
|
tbb::parallel_for(tbb::blocked_range<NodeID>(0, number_of_nodes, PQGrainSize),
|
||||||
tbb::blocked_range<NodeID>(0, number_of_nodes, PQGrainSize),
|
[this, &node_priorities, &node_depth, &thread_data_list](
|
||||||
[this, &node_priorities, &node_depth, &thread_data_list](
|
const tbb::blocked_range<NodeID> &range) {
|
||||||
const tbb::blocked_range<NodeID> &range) {
|
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
for (auto x = range.begin(), end = range.end(); x != end; ++x)
|
||||||
for (auto x = range.begin(), end = range.end(); x != end; ++x)
|
{
|
||||||
{
|
node_priorities[x] =
|
||||||
node_priorities[x] = this->EvaluateNodePriority(data, node_depth[x], x);
|
this->EvaluateNodePriority(data, node_depth[x], x);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
log << "ok";
|
log << "ok";
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(node_priorities.size() == number_of_nodes);
|
BOOST_ASSERT(node_priorities.size() == number_of_nodes);
|
||||||
@ -552,8 +552,7 @@ class GraphContractor
|
|||||||
[this, &node_priorities, &remaining_nodes, &node_depth, &thread_data_list](
|
[this, &node_priorities, &remaining_nodes, &node_depth, &thread_data_list](
|
||||||
const tbb::blocked_range<NodeID> &range) {
|
const tbb::blocked_range<NodeID> &range) {
|
||||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||||
for (auto position = range.begin(), end = range.end();
|
for (auto position = range.begin(), end = range.end(); position != end;
|
||||||
position != end;
|
|
||||||
++position)
|
++position)
|
||||||
{
|
{
|
||||||
NodeID x = remaining_nodes[position].id;
|
NodeID x = remaining_nodes[position].id;
|
||||||
|
@ -70,13 +70,13 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
WaypointType::Depart,
|
WaypointType::Depart,
|
||||||
0};
|
0};
|
||||||
|
|
||||||
Intersection intersection{source_node.location,
|
IntermediateIntersection intersection{source_node.location,
|
||||||
std::vector<short>({bearings.second}),
|
std::vector<short>({bearings.second}),
|
||||||
std::vector<bool>({true}),
|
std::vector<bool>({true}),
|
||||||
Intersection::NO_INDEX,
|
IntermediateIntersection::NO_INDEX,
|
||||||
0,
|
0,
|
||||||
util::guidance::LaneTuple(),
|
util::guidance::LaneTuple(),
|
||||||
{}};
|
{}};
|
||||||
|
|
||||||
if (leg_data.size() > 0)
|
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<short>({static_cast<short>(util::reverseBearing(bearings.first))}),
|
||||||
std::vector<bool>({true}),
|
std::vector<bool>({true}),
|
||||||
0,
|
0,
|
||||||
Intersection::NO_INDEX,
|
IntermediateIntersection::NO_INDEX,
|
||||||
util::guidance::LaneTuple(),
|
util::guidance::LaneTuple(),
|
||||||
{}};
|
{}};
|
||||||
|
|
||||||
|
@ -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.
|
// maneuvers that can, in some form, be seen as one. Lookahead of one step.
|
||||||
bool collapsable(const RouteStep &step, const RouteStep &next);
|
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.
|
// trim initial/final segment of very short length.
|
||||||
// This function uses in/out parameter passing to modify both steps and geometry in place.
|
// 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
|
// We use this method since both steps and geometry are closely coupled logically but
|
||||||
|
@ -30,7 +30,7 @@ namespace guidance
|
|||||||
// Arrive: a --> b --> t. The segment (b,t) is already covered by the previous segment.
|
// Arrive: a --> b --> t. The segment (b,t) is already covered by the previous segment.
|
||||||
|
|
||||||
// A representation of intermediate intersections
|
// A representation of intermediate intersections
|
||||||
struct Intersection
|
struct IntermediateIntersection
|
||||||
{
|
{
|
||||||
static const constexpr std::size_t NO_INDEX = std::numeric_limits<std::size_t>::max();
|
static const constexpr std::size_t NO_INDEX = std::numeric_limits<std::size_t>::max();
|
||||||
util::Coordinate location;
|
util::Coordinate location;
|
||||||
@ -44,13 +44,13 @@ struct Intersection
|
|||||||
extractor::guidance::TurnLaneDescription lane_description;
|
extractor::guidance::TurnLaneDescription lane_description;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Intersection getInvalidIntersection()
|
inline IntermediateIntersection getInvalidIntersection()
|
||||||
{
|
{
|
||||||
return {util::Coordinate{util::FloatLongitude{0.0}, util::FloatLatitude{0.0}},
|
return {util::Coordinate{util::FloatLongitude{0.0}, util::FloatLatitude{0.0}},
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
Intersection::NO_INDEX,
|
IntermediateIntersection::NO_INDEX,
|
||||||
Intersection::NO_INDEX,
|
IntermediateIntersection::NO_INDEX,
|
||||||
util::guidance::LaneTuple(),
|
util::guidance::LaneTuple(),
|
||||||
{}};
|
{}};
|
||||||
}
|
}
|
||||||
@ -71,55 +71,135 @@ struct RouteStep
|
|||||||
// indices into the locations array stored the LegGeometry
|
// indices into the locations array stored the LegGeometry
|
||||||
std::size_t geometry_begin;
|
std::size_t geometry_begin;
|
||||||
std::size_t geometry_end;
|
std::size_t geometry_end;
|
||||||
std::vector<Intersection> intersections;
|
std::vector<IntermediateIntersection> intersections;
|
||||||
|
|
||||||
LaneID numLanesToTheRight() const
|
// remove all information from the route step, marking it as invalid (used to indicate empty
|
||||||
{
|
// steps to be removed).
|
||||||
return intersections.front().lanes.first_lane_from_the_right;
|
void Invalidate();
|
||||||
}
|
|
||||||
|
|
||||||
LaneID numLanesToTheLeft() const
|
// Elongate by another step in front
|
||||||
{
|
RouteStep &AddInFront(const RouteStep &preceeding_step);
|
||||||
LaneID const total = intersections.front().lane_description.size();
|
|
||||||
return total - (intersections.front().lanes.lanes_in_turn +
|
|
||||||
intersections.front().lanes.first_lane_from_the_right);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lanesToTheLeft() const
|
// Elongate by another step in back
|
||||||
{
|
RouteStep &ElongateBy(const RouteStep &following_step);
|
||||||
const auto &description = intersections.front().lane_description;
|
|
||||||
LaneID num_lanes_left = numLanesToTheLeft();
|
|
||||||
return boost::make_iterator_range(description.begin(),
|
|
||||||
description.begin() + num_lanes_left);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lanesToTheRight() const
|
/* 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 */
|
||||||
const auto &description = intersections.front().lane_description;
|
RouteStep &MergeWith(const RouteStep &by_step);
|
||||||
LaneID num_lanes_right = numLanesToTheRight();
|
|
||||||
return boost::make_iterator_range(description.end() - num_lanes_right, description.end());
|
// 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,
|
name_id = EMPTY_NAMEID;
|
||||||
"",
|
name.clear();
|
||||||
"",
|
ref.clear();
|
||||||
"",
|
pronunciation.clear();
|
||||||
"",
|
destinations.clear();
|
||||||
"",
|
rotary_name.clear();
|
||||||
"",
|
rotary_pronunciation.clear();
|
||||||
0,
|
duration = 0;
|
||||||
0,
|
distance = 0;
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
mode = TRAVEL_MODE_INACCESSIBLE;
|
||||||
getInvalidStepManeuver(),
|
maneuver = getInvalidStepManeuver();
|
||||||
0,
|
geometry_begin = 0;
|
||||||
0,
|
geometry_end = 0;
|
||||||
{getInvalidIntersection()}};
|
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
|
#endif
|
||||||
|
@ -60,7 +60,7 @@ inline bool isValidModifier(const guidance::StepManeuver maneuver)
|
|||||||
maneuver.instruction.direction_modifier != DirectionModifier::UTurn);
|
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;
|
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)];
|
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);
|
BOOST_ASSERT(intersection.lanes.lanes_in_turn >= 1);
|
||||||
util::json::Array result;
|
util::json::Array result;
|
||||||
@ -200,7 +200,7 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
|
|||||||
return step_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::Object result;
|
||||||
util::json::Array bearings;
|
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["location"] = detail::coordinateToLonLat(intersection.location);
|
||||||
result.values["bearings"] = bearings;
|
result.values["bearings"] = bearings;
|
||||||
result.values["entry"] = entry;
|
result.values["entry"] = entry;
|
||||||
if (intersection.in != guidance::Intersection::NO_INDEX)
|
if (intersection.in != guidance::IntermediateIntersection::NO_INDEX)
|
||||||
result.values["in"] = intersection.in;
|
result.values["in"] = intersection.in;
|
||||||
if (intersection.out != guidance::Intersection::NO_INDEX)
|
if (intersection.out != guidance::IntermediateIntersection::NO_INDEX)
|
||||||
result.values["out"] = intersection.out;
|
result.values["out"] = intersection.out;
|
||||||
|
|
||||||
if (detail::hasValidLanes(intersection))
|
if (detail::hasValidLanes(intersection))
|
||||||
|
@ -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
|
// 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
|
// 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.
|
// 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_right_of_turn = current.NumLanesToTheRight();
|
||||||
const LaneID current_num_lanes_left_of_turn = current.numLanesToTheLeft();
|
const LaneID current_num_lanes_left_of_turn = current.NumLanesToTheLeft();
|
||||||
|
|
||||||
const LaneID num_shared_lanes = std::min(current_lanes.lanes_in_turn, //
|
const LaneID num_shared_lanes = std::min(current_lanes.lanes_in_turn, //
|
||||||
previous_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.
|
// step as invalid, scheduled for later removal.
|
||||||
if (collapsable(previous, current))
|
if (collapsable(previous, current))
|
||||||
{
|
{
|
||||||
previous = elongate(previous, current);
|
previous.ElongateBy(current);
|
||||||
current.maneuver.instruction = TurnInstruction::NO_TURN();
|
current.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -50,18 +50,6 @@ inline bool hasManeuver(const RouteStep &first, const RouteStep &second)
|
|||||||
second.maneuver.instruction.type != TurnType::NoTurn);
|
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)
|
inline bool choiceless(const RouteStep &step, const RouteStep &previous)
|
||||||
{
|
{
|
||||||
// if the next turn is choiceless, we consider longer turn roads collapsable than usually
|
// 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; }
|
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.
|
// Checks if name change happens the user wants to know about.
|
||||||
// Treats e.g. "Name (Ref)" -> "Name" changes still as same name.
|
// Treats e.g. "Name (Ref)" -> "Name" changes still as same name.
|
||||||
bool isNoticeableNameChange(const RouteStep &lhs, const RouteStep &rhs)
|
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;
|
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)
|
void fixFinalRoundabout(std::vector<RouteStep> &steps)
|
||||||
{
|
{
|
||||||
for (std::size_t propagation_index = steps.size() - 1; propagation_index > 0;
|
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.
|
// 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
|
// We are missing out on the final segment after the last stay-on-roundabout
|
||||||
// instruction though. it is not contained somewhere until now
|
// instruction though. it is not contained somewhere until now
|
||||||
steps[propagation_index - 1] =
|
steps[propagation_index - 1].ElongateBy(propagation_step);
|
||||||
forwardInto(std::move(steps[propagation_index - 1]), propagation_step);
|
steps[propagation_index - 1].maneuver.exit = propagation_step.maneuver.exit;
|
||||||
invalidateStep(propagation_step);
|
propagation_step.Invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,7 +199,7 @@ void closeOffRoundabout(const bool on_roundabout,
|
|||||||
steps[1].maneuver.instruction.type == TurnType::UseLane);
|
steps[1].maneuver.instruction.type == TurnType::UseLane);
|
||||||
steps[0].geometry_end = 1;
|
steps[0].geometry_end = 1;
|
||||||
steps[1].geometry_begin = 0;
|
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
|
steps[1].intersections.erase(steps[1].intersections.begin()); // otherwise we copy the
|
||||||
// source
|
// source
|
||||||
if (leavesRoundabout(steps[1].maneuver.instruction))
|
if (leavesRoundabout(steps[1].maneuver.instruction))
|
||||||
@ -282,7 +241,8 @@ void closeOffRoundabout(const bool on_roundabout,
|
|||||||
--propagation_index)
|
--propagation_index)
|
||||||
{
|
{
|
||||||
auto &propagation_step = steps[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))
|
if (entersRoundabout(propagation_step.maneuver.instruction))
|
||||||
{
|
{
|
||||||
const auto entry_intersection = propagation_step.intersections.front();
|
const auto entry_intersection = propagation_step.intersections.front();
|
||||||
@ -309,13 +269,13 @@ void closeOffRoundabout(const bool on_roundabout,
|
|||||||
getTurnDirection(angle);
|
getTurnDirection(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
forwardStepSignage(propagation_step, destination_copy);
|
propagation_step.AdaptStepSignage(destination_copy);
|
||||||
invalidateStep(steps[propagation_index + 1]);
|
steps[propagation_index + 1].Invalidate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
invalidateStep(steps[propagation_index + 1]);
|
steps[propagation_index + 1].Invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// remove exit
|
// remove exit
|
||||||
@ -445,19 +405,18 @@ void collapseUTurn(std::vector<RouteStep> &steps,
|
|||||||
|
|
||||||
if (direct_u_turn || u_turn_with_name_change)
|
if (direct_u_turn || u_turn_with_name_change)
|
||||||
{
|
{
|
||||||
steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]);
|
steps[one_back_index].ElongateBy(steps[step_index]);
|
||||||
invalidateStep(steps[step_index]);
|
steps[step_index].Invalidate();
|
||||||
if (u_turn_with_name_change)
|
if (u_turn_with_name_change)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(compatible(steps[one_back_index], steps[next_step_index]),
|
BOOST_ASSERT_MSG(compatible(steps[one_back_index], steps[next_step_index]),
|
||||||
"Compatibility should be transitive");
|
"Compatibility should be transitive");
|
||||||
steps[one_back_index] =
|
steps[one_back_index].ElongateBy(steps[next_step_index]);
|
||||||
elongate(std::move(steps[one_back_index]), steps[next_step_index]);
|
steps[next_step_index].Invalidate(); // will be skipped due to the
|
||||||
invalidateStep(steps[next_step_index]); // will be skipped due to the
|
// continue statement at the
|
||||||
// continue statement at the
|
// beginning of this function
|
||||||
// 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.type = TurnType::Continue;
|
||||||
steps[one_back_index].maneuver.instruction.direction_modifier = DirectionModifier::UTurn;
|
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
|
// If the previous instruction asked to continue, the name change will have to
|
||||||
// be changed into a turn
|
// 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
|
// very short segment after turn, turn location remains at one_back_step
|
||||||
else if (isDelayedTurn(one_back_step, current_step)) // checks for compatibility
|
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)
|
// TODO check for lanes (https://github.com/Project-OSRM/osrm-backend/issues/2553)
|
||||||
if (TurnType::Continue == one_back_step.maneuver.instruction.type &&
|
if (TurnType::Continue == one_back_step.maneuver.instruction.type &&
|
||||||
isNoticeableNameChange(steps[two_back_index], current_step))
|
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 =
|
steps[one_back_index].maneuver.instruction.direction_modifier =
|
||||||
DirectionModifier::UTurn;
|
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 ||
|
else if (TurnType::NewName == one_back_step.maneuver.instruction.type ||
|
||||||
(TurnType::NewName == current_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 = current_step.name;
|
||||||
steps[one_back_index].name_id = current_step.name_id;
|
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 &&
|
else if (TurnType::Suppressed == current_step.maneuver.instruction.type &&
|
||||||
!isNoticeableNameChange(one_back_step, current_step) &&
|
!isNoticeableNameChange(one_back_step, current_step) &&
|
||||||
compatible(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);
|
const auto angle = findTotalTurnAngle(one_back_step, current_step);
|
||||||
steps[one_back_index].maneuver.instruction.direction_modifier = getTurnDirection(angle);
|
steps[one_back_index].maneuver.instruction.direction_modifier = getTurnDirection(angle);
|
||||||
|
steps[step_index].Invalidate();
|
||||||
invalidateStep(steps[step_index]);
|
|
||||||
}
|
}
|
||||||
else if (TurnType::Turn == one_back_step.maneuver.instruction.type &&
|
else if (TurnType::Turn == one_back_step.maneuver.instruction.type &&
|
||||||
TurnType::OnRamp == current_step.maneuver.instruction.type &&
|
TurnType::OnRamp == current_step.maneuver.instruction.type &&
|
||||||
compatible(one_back_step, current_step))
|
compatible(one_back_step, current_step))
|
||||||
{
|
{
|
||||||
// turning onto a ramp makes the first turn into a ramp
|
// 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;
|
steps[one_back_index].maneuver.instruction.type = TurnType::OnRamp;
|
||||||
const auto angle = findTotalTurnAngle(one_back_step, current_step);
|
const auto angle = findTotalTurnAngle(one_back_step, current_step);
|
||||||
steps[one_back_index].maneuver.instruction.direction_modifier = getTurnDirection(angle);
|
steps[one_back_index].maneuver.instruction.direction_modifier = getTurnDirection(angle);
|
||||||
|
|
||||||
forwardStepSignage(steps[one_back_index], current_step);
|
steps[one_back_index].AdaptStepSignage(current_step);
|
||||||
invalidateStep(steps[step_index]);
|
steps[step_index].Invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,43 +822,6 @@ bool collapsable(const RouteStep &step, const RouteStep &next)
|
|||||||
return false;
|
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
|
// Post processing can invalidate some instructions. For example StayOnRoundabout
|
||||||
// is turned into exit counts. These instructions are removed by the following function
|
// 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
|
// Traffic light on the sliproad, the road itself will be handled in the next
|
||||||
// iteration, when one-back-index again points to the sliproad.
|
// iteration, when one-back-index again points to the sliproad.
|
||||||
steps[one_back_index] =
|
steps[one_back_index].ElongateBy(steps[step_index]);
|
||||||
elongate(std::move(steps[one_back_index]), steps[step_index]);
|
steps[step_index].Invalidate();
|
||||||
invalidateStep(steps[step_index]);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1110,10 +1030,9 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
|||||||
else
|
else
|
||||||
steps[one_back_index].maneuver.instruction.type = TurnType::Turn;
|
steps[one_back_index].maneuver.instruction.type = TurnType::Turn;
|
||||||
|
|
||||||
steps[one_back_index] =
|
steps[one_back_index].ElongateBy(steps[step_index]);
|
||||||
elongate(std::move(steps[one_back_index]), 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
|
// the turn lanes for this turn are on the sliproad itself, so we have to
|
||||||
// remember them
|
// remember them
|
||||||
steps[one_back_index].intersections.front().lanes =
|
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);
|
const auto angle = findTotalTurnAngle(one_back_step, current_step);
|
||||||
steps[one_back_index].maneuver.instruction.direction_modifier =
|
steps[one_back_index].maneuver.instruction.direction_modifier =
|
||||||
getTurnDirection(angle);
|
getTurnDirection(angle);
|
||||||
invalidateStep(steps[step_index]);
|
steps[step_index].Invalidate();
|
||||||
}
|
}
|
||||||
else
|
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)
|
for (std::size_t index = last_available_name_index + 1; index <= step_index; ++index)
|
||||||
{
|
{
|
||||||
steps[last_available_name_index] =
|
steps[last_available_name_index].ElongateBy(steps[index]);
|
||||||
elongate(std::move(steps[last_available_name_index]), steps[index]);
|
steps[index].Invalidate();
|
||||||
invalidateStep(steps[index]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If we look at two consecutive name changes, we can check for a name oscillation.
|
// 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]))
|
if (compatible(one_back_step, steps[two_back_index]))
|
||||||
{
|
{
|
||||||
steps[two_back_index] =
|
steps[two_back_index]
|
||||||
elongate(elongate(std::move(steps[two_back_index]), steps[one_back_index]),
|
.ElongateBy(steps[one_back_index])
|
||||||
steps[step_index]);
|
.ElongateBy(steps[step_index]);
|
||||||
invalidateStep(steps[one_back_index]);
|
steps[one_back_index].Invalidate();
|
||||||
invalidateStep(steps[step_index]);
|
steps[step_index].Invalidate();
|
||||||
}
|
}
|
||||||
// TODO discuss: we could think about changing the new-name to a pure notification
|
// TODO discuss: we could think about changing the new-name to a pure notification
|
||||||
// about mode changes
|
// 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]))
|
if (compatible(steps[two_back_index], steps[one_back_index]))
|
||||||
{
|
{
|
||||||
steps[two_back_index] =
|
steps[two_back_index].ElongateBy(steps[one_back_index]);
|
||||||
elongate(std::move(steps[two_back_index]), steps[one_back_index]);
|
steps[one_back_index].Invalidate();
|
||||||
invalidateStep(steps[one_back_index]);
|
|
||||||
if (nameSegmentLength(step_index, steps) < name_segment_cutoff_length &&
|
if (nameSegmentLength(step_index, steps) < name_segment_cutoff_length &&
|
||||||
compatible(steps[two_back_index], steps[step_index]))
|
compatible(steps[two_back_index], steps[step_index]))
|
||||||
{
|
{
|
||||||
steps[two_back_index] =
|
steps[two_back_index].ElongateBy(steps[step_index]);
|
||||||
elongate(std::move(steps[two_back_index]), steps[step_index]);
|
steps[step_index].Invalidate();
|
||||||
invalidateStep(steps[step_index]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1203,11 +1119,11 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
|||||||
// change,
|
// change,
|
||||||
// we don't wan't to collapse the initial intersection.
|
// we don't wan't to collapse the initial intersection.
|
||||||
// a - b ---BRIDGE -- c
|
// a - b ---BRIDGE -- c
|
||||||
steps[one_back_index] =
|
steps[one_back_index]
|
||||||
elongate(std::move(steps[one_back_index]),
|
.ElongateBy(steps[step_index])
|
||||||
elongate(std::move(steps[step_index]), steps[next_step_index]));
|
.ElongateBy(steps[next_step_index]);
|
||||||
invalidateStep(steps[step_index]);
|
steps[step_index].Invalidate();
|
||||||
invalidateStep(steps[next_step_index]);
|
steps[next_step_index].Invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (choiceless(current_step, one_back_step) ||
|
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();
|
designated_depart.intersections.front().lane_description.clear();
|
||||||
first_intersection.bearings = {first_intersection.bearings[first_intersection.out]};
|
first_intersection.bearings = {first_intersection.bearings[first_intersection.out]};
|
||||||
first_intersection.entry = {true};
|
first_intersection.entry = {true};
|
||||||
first_intersection.in = Intersection::NO_INDEX;
|
first_intersection.in = IntermediateIntersection::NO_INDEX;
|
||||||
first_intersection.out = 0;
|
first_intersection.out = 0;
|
||||||
|
|
||||||
// finally remove the initial (now duplicated move)
|
// 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();
|
auto &last_intersection = next_to_last_step.intersections.back();
|
||||||
last_intersection.bearings = {last_intersection.bearings[last_intersection.in]};
|
last_intersection.bearings = {last_intersection.bearings[last_intersection.in]};
|
||||||
last_intersection.entry = {true};
|
last_intersection.entry = {true};
|
||||||
last_intersection.out = Intersection::NO_INDEX;
|
last_intersection.out = IntermediateIntersection::NO_INDEX;
|
||||||
last_intersection.in = 0;
|
last_intersection.in = 0;
|
||||||
steps.pop_back();
|
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
|
// as the segment before it. Thus, we have to copy the names
|
||||||
// and travel modes from the new next_to_last step.
|
// and travel modes from the new next_to_last step.
|
||||||
auto &new_next_to_last = *(steps.end() - 2);
|
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;
|
next_to_last_step.mode = new_next_to_last.mode;
|
||||||
// the geometry indices of the last step are already correct;
|
// 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));
|
BOOST_ASSERT(compatible(steps[last_valid_instruction], step));
|
||||||
// count intersections. We cannot use exit, since intersections can follow directly
|
// count intersections. We cannot use exit, since intersections can follow directly
|
||||||
// after a roundabout
|
// after a roundabout
|
||||||
steps[last_valid_instruction] =
|
steps[last_valid_instruction].ElongateBy(step);
|
||||||
elongate(std::move(steps[last_valid_instruction]), step);
|
steps[step_index].Invalidate();
|
||||||
step.maneuver.instruction = TurnInstruction::NO_TURN();
|
|
||||||
invalidateStep(steps[step_index]);
|
|
||||||
}
|
}
|
||||||
else if (!isSilent(instruction))
|
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.
|
// the lane description is given left to right, lanes are counted from the right.
|
||||||
// Therefore we access the lane description using the reverse iterator
|
// 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(),
|
if (!right_most_lanes.empty() && containsTag(right_most_lanes.front(),
|
||||||
(extractor::guidance::TurnLaneType::straight |
|
(extractor::guidance::TurnLaneType::straight |
|
||||||
extractor::guidance::TurnLaneType::none)))
|
extractor::guidance::TurnLaneType::none)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto left_most_lanes = step.lanesToTheLeft();
|
auto left_most_lanes = step.LanesToTheLeft();
|
||||||
if (!left_most_lanes.empty() && containsTag(left_most_lanes.back(),
|
if (!left_most_lanes.empty() && containsTag(left_most_lanes.back(),
|
||||||
(extractor::guidance::TurnLaneType::straight |
|
(extractor::guidance::TurnLaneType::straight |
|
||||||
extractor::guidance::TurnLaneType::none)))
|
extractor::guidance::TurnLaneType::none)))
|
||||||
@ -1627,8 +1541,8 @@ std::vector<RouteStep> collapseUseLane(std::vector<RouteStep> steps)
|
|||||||
const auto previous = getPreviousIndex(step_index, steps);
|
const auto previous = getPreviousIndex(step_index, steps);
|
||||||
if (compatible(steps[previous], step))
|
if (compatible(steps[previous], step))
|
||||||
{
|
{
|
||||||
steps[previous] = elongate(std::move(steps[previous]), steps[step_index]);
|
steps[previous].ElongateBy(steps[step_index]);
|
||||||
invalidateStep(steps[step_index]);
|
steps[step_index].Invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,8 +130,7 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
|||||||
// fallback, mostly necessary for dead ends
|
// fallback, mostly necessary for dead ends
|
||||||
if (intersection_node == to_node)
|
if (intersection_node == to_node)
|
||||||
{
|
{
|
||||||
const auto result = ExtractCoordinateAtLength(
|
const auto result = ExtractCoordinateAtLength(skipping_inaccuracies_distance, coordinates);
|
||||||
skipping_inaccuracies_distance, coordinates);
|
|
||||||
BOOST_ASSERT(is_valid_result(result));
|
BOOST_ASSERT(is_valid_result(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
#include "extractor/restriction_parser.hpp"
|
#include "extractor/restriction_parser.hpp"
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/exception.hpp"
|
#include "util/exception.hpp"
|
||||||
#include "util/lua_util.hpp"
|
|
||||||
#include "util/log.hpp"
|
#include "util/log.hpp"
|
||||||
|
#include "util/lua_util.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include <osmium/osm.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>
|
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);
|
auto v = get_value_by_key(object, key);
|
||||||
if (v && *v)
|
if (v && *v)
|
||||||
@ -176,8 +176,13 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
static_cast<void (std::vector<std::string>::*)(const std::string &)>(
|
static_cast<void (std::vector<std::string>::*)(const std::string &)>(
|
||||||
&std::vector<std::string>::push_back));
|
&std::vector<std::string>::push_back));
|
||||||
|
|
||||||
context.state.new_usertype<osmium::Location>(
|
context.state.new_usertype<osmium::Location>("Location",
|
||||||
"Location", "lat", &osmium::Location::lat, "lon", &osmium::Location::lon, "valid", &osmium::Location::valid);
|
"lat",
|
||||||
|
&osmium::Location::lat,
|
||||||
|
"lon",
|
||||||
|
&osmium::Location::lon,
|
||||||
|
"valid",
|
||||||
|
&osmium::Location::valid);
|
||||||
|
|
||||||
context.state.new_usertype<osmium::Way>("Way",
|
context.state.new_usertype<osmium::Way>("Way",
|
||||||
"get_value_by_key",
|
"get_value_by_key",
|
||||||
@ -272,12 +277,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
"lat",
|
"lat",
|
||||||
&latToDouble<ExternalMemoryNode>);
|
&latToDouble<ExternalMemoryNode>);
|
||||||
|
|
||||||
context.state.new_usertype<util::Coordinate>(
|
context.state.new_usertype<util::Coordinate>("Coordinate",
|
||||||
"Coordinate",
|
"lon",
|
||||||
"lon",
|
sol::property(&lonToDouble<util::Coordinate>),
|
||||||
sol::property(&lonToDouble<util::Coordinate>),
|
"lat",
|
||||||
"lat",
|
sol::property(&latToDouble<util::Coordinate>));
|
||||||
sol::property(&latToDouble<util::Coordinate>));
|
|
||||||
|
|
||||||
context.state.new_usertype<RasterDatum>(
|
context.state.new_usertype<RasterDatum>(
|
||||||
"RasterDatum", "datum", &RasterDatum::datum, "invalid_data", &RasterDatum::get_invalid);
|
"RasterDatum", "datum", &RasterDatum::datum, "invalid_data", &RasterDatum::get_invalid);
|
||||||
|
@ -14,7 +14,8 @@ constexpr double bearing_scale = 360.0 / 256.0;
|
|||||||
// discretizes a bearing into distinct units of 1.4 degrees
|
// discretizes a bearing into distinct units of 1.4 degrees
|
||||||
TurnBearing::TurnBearing(const double value) : bearing(value / bearing_scale)
|
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; }
|
double TurnBearing::Get() const { return bearing * bearing_scale; }
|
||||||
|
@ -17,7 +17,10 @@
|
|||||||
|
|
||||||
namespace
|
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)
|
BOOST_AUTO_TEST_SUITE(limits)
|
||||||
|
Loading…
Reference in New Issue
Block a user