link ConnectedRoad and TurnOperation via class hierarchy

and empower intersection by adding basic functionality to pod type
refactor extractor/toolkit into intersection
This commit is contained in:
Moritz Kobitzsch 2016-11-03 10:18:27 +01:00
parent 388d84a89e
commit cd03877c90
26 changed files with 665 additions and 661 deletions

View File

@ -75,6 +75,32 @@ template <typename Iter, typename Fn> inline Fn forEachRoundabout(Iter first, It
return fn;
}
LaneID inline numLanesToTheRight(const engine::guidance::RouteStep &step)
{
return step.intersections.front().lanes.first_lane_from_the_right;
}
LaneID inline numLanesToTheLeft(const engine::guidance::RouteStep &step)
{
LaneID const total = step.intersections.front().lane_description.size();
return total - (step.intersections.front().lanes.lanes_in_turn +
step.intersections.front().lanes.first_lane_from_the_right);
}
auto inline lanesToTheLeft(const engine::guidance::RouteStep &step)
{
const auto &description = step.intersections.front().lane_description;
LaneID num_lanes_left = numLanesToTheLeft(step);
return boost::make_iterator_range(description.begin(), description.begin() + num_lanes_left);
}
auto inline lanesToTheRight(const engine::guidance::RouteStep &step)
{
const auto &description = step.intersections.front().lane_description;
LaneID num_lanes_right = numLanesToTheRight(step);
return boost::make_iterator_range(description.end() - num_lanes_right, description.end());
}
} // namespace guidance
} // namespace engine
} // namespace osrm

View File

@ -6,6 +6,7 @@
#include "extractor/guidance/turn_instruction.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp" // EdgeID
namespace osrm
@ -18,7 +19,7 @@ namespace guidance
// Every Turn Operation describes a way of switching onto a segment, indicated by an EdgeID. The
// associated turn is described by an angle and an instruction that is used to announce it.
// The Turn Operation indicates what is exposed to the outside of the turn analysis.
struct TurnOperation final
struct TurnOperation
{
EdgeID eid;
double angle;
@ -48,13 +49,23 @@ struct TurnOperation final
// aaaaaaaa
//
// We would perceive a->c as a sharp turn, a->b as a slight turn, and b->c as a slight turn.
struct ConnectedRoad final
struct ConnectedRoad final : public TurnOperation
{
using Base = TurnOperation;
ConnectedRoad(const TurnOperation turn, const bool entry_allowed = false);
// a turn may be relevant to good instructions, even if we cannot enter the road
bool entry_allowed;
TurnOperation turn;
// used to sort the set of connected roads (we require sorting throughout turn handling)
bool compareByAngle(const ConnectedRoad &other) const;
// make a left turn into an equivalent right turn and vice versa
void mirror();
OSRM_ATTR_WARN_UNUSED
ConnectedRoad getMirroredCopy() const;
};
// small helper function to print the content of a connected road
@ -64,25 +75,24 @@ struct Intersection final : public std::vector<ConnectedRoad>
{
using Base = std::vector<ConnectedRoad>;
inline Base::iterator findClosestTurn(double angle)
{
return std::min_element(this->begin(),
this->end(),
[angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
return util::guidance::angularDeviation(lhs.turn.angle, angle) <
util::guidance::angularDeviation(rhs.turn.angle, angle);
});
}
/*
* find the turn whose angle offers the least angularDeviation to the specified angle
* E.g. for turn angles [0,90,260] and a query of 180 we return the 260 degree turn (difference
* 80 over the difference of 90 to the 90 degree turn)
*/
Base::iterator findClosestTurn(double angle);
Base::const_iterator findClosestTurn(double angle) const;
inline Base::const_iterator findClosestTurn(double angle) const
{
return std::min_element(this->begin(),
this->end(),
[angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
return util::guidance::angularDeviation(lhs.turn.angle, angle) <
util::guidance::angularDeviation(rhs.turn.angle, angle);
});
}
/*
* Check validity of the intersection object. We assume a few basic properties every set of
* connected roads should follow throughout guidance pre-processing. This utility function
* allows checking intersections for validity
*/
bool valid() const;
// given all possible turns, which is the highest connected number of lanes per turn. This value
// is used, for example, during generation of intersections.
std::uint8_t getHighestConnectedLaneCount(const util::NodeBasedDynamicGraph &) const;
};
Intersection::const_iterator findClosestTurn(const Intersection &intersection, const double angle);

View File

@ -18,12 +18,9 @@
#include "extractor/guidance/road_classification.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "engine/guidance/route_step.hpp"
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <map>
#include <string>
#include <unordered_map>
#include <utility>
@ -51,26 +48,6 @@ using util::guidance::leavesRoundabout;
// To simplify handling of Left/Right hand turns, we can mirror turns and write an intersection
// handler only for one side. The mirror function turns a left-hand turn in a equivalent right-hand
// turn and vice versa.
OSRM_ATTR_WARN_UNUSED
inline ConnectedRoad mirror(ConnectedRoad road)
{
const constexpr DirectionModifier::Enum mirrored_modifiers[] = {DirectionModifier::UTurn,
DirectionModifier::SharpLeft,
DirectionModifier::Left,
DirectionModifier::SlightLeft,
DirectionModifier::Straight,
DirectionModifier::SlightRight,
DirectionModifier::Right,
DirectionModifier::SharpRight};
if (angularDeviation(road.turn.angle, 0) > std::numeric_limits<double>::epsilon())
{
road.turn.angle = 360 - road.turn.angle;
road.turn.instruction.direction_modifier =
mirrored_modifiers[road.turn.instruction.direction_modifier];
}
return road;
}
inline bool hasRoundaboutType(const TurnInstruction instruction)
{
@ -184,42 +161,6 @@ inline std::string applyAccessTokens(std::string lane_string, const std::string
return result_string;
}
LaneID inline numLanesToTheRight(const engine::guidance::RouteStep &step)
{
return step.intersections.front().lanes.first_lane_from_the_right;
}
LaneID inline numLanesToTheLeft(const engine::guidance::RouteStep &step)
{
LaneID const total = step.intersections.front().lane_description.size();
return total - (step.intersections.front().lanes.lanes_in_turn +
step.intersections.front().lanes.first_lane_from_the_right);
}
auto inline lanesToTheLeft(const engine::guidance::RouteStep &step)
{
const auto &description = step.intersections.front().lane_description;
LaneID num_lanes_left = numLanesToTheLeft(step);
return boost::make_iterator_range(description.begin(), description.begin() + num_lanes_left);
}
auto inline lanesToTheRight(const engine::guidance::RouteStep &step)
{
const auto &description = step.intersections.front().lane_description;
LaneID num_lanes_right = numLanesToTheRight(step);
return boost::make_iterator_range(description.end() - num_lanes_right, description.end());
}
inline std::uint8_t getLaneCountAtIntersection(const NodeID intersection_node,
const util::NodeBasedDynamicGraph &node_based_graph)
{
std::uint8_t lanes = 0;
for (const EdgeID onto_edge : node_based_graph.GetAdjacentEdgeRange(intersection_node))
lanes = std::max(
lanes, node_based_graph.GetEdgeData(onto_edge).road_classification.GetNumberOfLanes());
return lanes;
}
inline bool obviousByRoadClass(const RoadClassification in_classification,
const RoadClassification obvious_candidate,
const RoadClassification compare_candidate)
@ -282,6 +223,16 @@ leastSquareRegression(const std::vector<util::Coordinate> &coordinates)
return {regression_first, regression_end};
}
inline std::uint8_t getLaneCountAtIntersection(const NodeID intersection_node,
const util::NodeBasedDynamicGraph &node_based_graph)
{
std::uint8_t lanes = 0;
for (const EdgeID onto_edge : node_based_graph.GetAdjacentEdgeRange(intersection_node))
lanes = std::max(
lanes, node_based_graph.GetEdgeData(onto_edge).road_classification.GetNumberOfLanes());
return lanes;
}
} // namespace guidance
} // namespace extractor
} // namespace osrm

View File

@ -23,12 +23,12 @@ namespace api
struct ParsedURL;
}
class ServiceHandlerInterface
{
public:
virtual ~ServiceHandlerInterface() {}
virtual engine::Status RunQuery(api::ParsedURL parsed_url, service::BaseService::ResultT & result) = 0;
virtual engine::Status RunQuery(api::ParsedURL parsed_url,
service::BaseService::ResultT &result) = 0;
};
class ServiceHandler final : public ServiceHandlerInterface

View File

@ -73,8 +73,7 @@ inline void print(const NodeBasedDynamicGraph &node_based_graph,
for (const auto &road : intersection)
{
std::cout << "\t" << toString(road) << "\n";
std::cout << "\t\t"
<< node_based_graph.GetEdgeData(road.turn.eid).road_classification.ToString()
std::cout << "\t\t" << node_based_graph.GetEdgeData(road.eid).road_classification.ToString()
<< "\n";
}
std::cout << std::flush;

View File

@ -42,7 +42,6 @@ unsigned calculateOverviewZoomLevel(const std::vector<LegGeometry> &leg_geometri
return util::viewport::getFittedZoom(south_west, north_east);
}
}
std::vector<util::Coordinate> assembleOverview(const std::vector<LegGeometry> &leg_geometries,
@ -62,7 +61,8 @@ std::vector<util::Coordinate> assembleOverview(const std::vector<LegGeometry> &l
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)
{
@ -77,7 +77,8 @@ std::vector<util::Coordinate> assembleOverview(const std::vector<LegGeometry> &l
const auto zoom_level = std::min(18u, calculateOverviewZoomLevel(leg_geometries));
for (const auto &geometry : leg_geometries)
{
const auto simplified = douglasPeucker(geometry.locations.begin(), geometry.locations.end(), zoom_level);
const auto simplified =
douglasPeucker(geometry.locations.begin(), geometry.locations.end(), zoom_level);
insert_without_overlap(simplified.begin(), simplified.end());
}
}

View File

@ -2,7 +2,7 @@
#include "util/group_by.hpp"
#include "util/guidance/toolkit.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "engine/guidance/toolkit.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "engine/guidance/post_processing.hpp"
@ -16,8 +16,6 @@ namespace DirectionModifier = osrm::extractor::guidance::DirectionModifier;
using osrm::util::guidance::isLeftTurn;
using osrm::util::guidance::isRightTurn;
using osrm::extractor::guidance::numLanesToTheRight;
using osrm::extractor::guidance::numLanesToTheLeft;
namespace osrm
{

View File

@ -1,7 +1,7 @@
#include "engine/guidance/post_processing.hpp"
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "engine/guidance/toolkit.hpp"
#include "engine/guidance/assemble_steps.hpp"
#include "engine/guidance/lane_processing.hpp"
@ -1599,13 +1599,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 = extractor::guidance::lanesToTheRight(step);
auto right_most_lanes = lanesToTheRight(step);
if (!right_most_lanes.empty() && containsTag(right_most_lanes.front(),
(extractor::guidance::TurnLaneType::straight |
extractor::guidance::TurnLaneType::none)))
return false;
auto left_most_lanes = extractor::guidance::lanesToTheLeft(step);
auto left_most_lanes = lanesToTheLeft(step);
if (!left_most_lanes.empty() && containsTag(left_most_lanes.back(),
(extractor::guidance::TurnLaneType::straight |
extractor::guidance::TurnLaneType::none)))

View File

@ -376,6 +376,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const NodeID node_v = m_node_based_graph->GetTarget(edge_from_u);
++node_based_edge_counter;
auto intersection = turn_analysis.getIntersection(node_u, edge_from_u);
BOOST_ASSERT(intersection.valid());
intersection =
turn_analysis.assignTurnTypes(node_u, edge_from_u, std::move(intersection));
intersection =
@ -462,7 +463,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
turn_instruction,
entry_class_id,
edge_data1.travel_mode,
util::guidance::TurnBearing(intersection[0].turn.bearing),
util::guidance::TurnBearing(intersection[0].bearing),
util::guidance::TurnBearing(turn.bearing));
}
else if (is_encoded_backwards)
@ -476,7 +477,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
turn_instruction,
entry_class_id,
edge_data1.travel_mode,
util::guidance::TurnBearing(intersection[0].turn.bearing),
util::guidance::TurnBearing(intersection[0].bearing),
util::guidance::TurnBearing(turn.bearing));
}

View File

@ -24,8 +24,7 @@ operator()(const NodeID intersection_node,
{
// request the number of lanes. This process needs to be in sync with what happens over at
// intersection_generator
const auto intersection_lanes =
extractor::guidance::getLaneCountAtIntersection(intersection_node, node_based_graph);
const auto intersection_lanes = intersection.getHighestConnectedLaneCount(node_based_graph);
std::vector<util::Coordinate> coordinates;
coordinates.reserve(intersection.size());
@ -33,9 +32,9 @@ operator()(const NodeID intersection_node,
const auto road_to_coordinate = [&](const extractor::guidance::ConnectedRoad &connected_road) {
const constexpr auto FORWARD = false;
const auto to_node = node_based_graph.GetTarget(connected_road.turn.eid);
const auto to_node = node_based_graph.GetTarget(connected_road.eid);
return coordinate_extractor.GetCoordinateAlongRoad(
intersection_node, connected_road.turn.eid, FORWARD, to_node, intersection_lanes);
intersection_node, connected_road.eid, FORWARD, to_node, intersection_lanes);
};
std::transform(intersection.begin(),

View File

@ -1,6 +1,13 @@
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/toolkit.hpp"
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <algorithm>
#include <functional>
#include <limits>
namespace osrm
{
namespace extractor
@ -9,44 +16,101 @@ namespace guidance
{
ConnectedRoad::ConnectedRoad(const TurnOperation turn, const bool entry_allowed)
: entry_allowed(entry_allowed), turn(turn)
: TurnOperation(turn), entry_allowed(entry_allowed)
{
}
bool ConnectedRoad::compareByAngle(const ConnectedRoad &other) const { return angle < other.angle; }
void ConnectedRoad::mirror()
{
const constexpr DirectionModifier::Enum mirrored_modifiers[] = {DirectionModifier::UTurn,
DirectionModifier::SharpLeft,
DirectionModifier::Left,
DirectionModifier::SlightLeft,
DirectionModifier::Straight,
DirectionModifier::SlightRight,
DirectionModifier::Right,
DirectionModifier::SharpRight};
static_assert(sizeof(mirrored_modifiers) / sizeof(DirectionModifier::Enum) ==
DirectionModifier::MaxDirectionModifier,
"The list of mirrored modifiers needs to match the available modifiers in size.");
if (angularDeviation(angle, 0) > std::numeric_limits<double>::epsilon())
{
angle = 360 - angle;
instruction.direction_modifier = mirrored_modifiers[instruction.direction_modifier];
}
}
ConnectedRoad ConnectedRoad::getMirroredCopy() const
{
ConnectedRoad copy(*this);
copy.mirror();
return copy;
}
std::string toString(const ConnectedRoad &road)
{
std::string result = "[connection] ";
result += std::to_string(road.turn.eid);
result += std::to_string(road.eid);
result += " allows entry: ";
result += std::to_string(road.entry_allowed);
result += " angle: ";
result += std::to_string(road.turn.angle);
result += std::to_string(road.angle);
result += " bearing: ";
result += std::to_string(road.turn.bearing);
result += std::to_string(road.bearing);
result += " instruction: ";
result += std::to_string(static_cast<std::int32_t>(road.turn.instruction.type)) + " " +
std::to_string(static_cast<std::int32_t>(road.turn.instruction.direction_modifier)) +
" " + std::to_string(static_cast<std::int32_t>(road.turn.lane_data_id));
result += std::to_string(static_cast<std::int32_t>(road.instruction.type)) + " " +
std::to_string(static_cast<std::int32_t>(road.instruction.direction_modifier)) + " " +
std::to_string(static_cast<std::int32_t>(road.lane_data_id));
return result;
}
Intersection::iterator findClosestTurn(Intersection &intersection, const double angle)
Intersection::Base::iterator Intersection::findClosestTurn(double angle)
{
return std::min_element(intersection.begin(),
intersection.end(),
[angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
return angularDeviation(lhs.turn.angle, angle) <
angularDeviation(rhs.turn.angle, angle);
// use the const operator to avoid code duplication
return begin() +
std::distance(cbegin(), static_cast<const Intersection *>(this)->findClosestTurn(angle));
}
Intersection::Base::const_iterator Intersection::findClosestTurn(double angle) const
{
return std::min_element(
begin(), end(), [angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
return util::guidance::angularDeviation(lhs.angle, angle) <
util::guidance::angularDeviation(rhs.angle, angle);
});
}
Intersection::const_iterator findClosestTurn(const Intersection &intersection, const double angle)
bool Intersection::valid() const
{
return std::min_element(intersection.cbegin(),
intersection.cend(),
[angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
return angularDeviation(lhs.turn.angle, angle) <
angularDeviation(rhs.turn.angle, angle);
});
return !empty() &&
std::is_sorted(begin(), end(), std::mem_fn(&ConnectedRoad::compareByAngle)) &&
operator[](0).angle < std::numeric_limits<double>::epsilon();
}
std::uint8_t Intersection::getHighestConnectedLaneCount(
const util::NodeBasedDynamicGraph &node_based_graph) const
{
BOOST_ASSERT(valid()); // non empty()
std::vector<ConnectedRoad> test;
const auto to_lane_count = [&](const ConnectedRoad &road) {
return node_based_graph.GetEdgeData(road.eid).road_classification.GetNumberOfLanes();
};
// boost::range::transformed sadly does not work with lamdas since they are not copy
// constructable. We need to work around this :(
std::uint8_t max_lanes = 0;
const auto extract_maximal_value = [&max_lanes](std::uint8_t value) {
max_lanes = std::max(max_lanes, value);
return false;
};
const auto view = test | boost::adaptors::transformed(to_lane_count);
boost::range::find_if(view, extract_maximal_value);
return max_lanes;
}
} // namespace guidance

View File

@ -3,6 +3,7 @@
#include "extractor/guidance/toolkit.hpp"
#include <algorithm>
#include <functional>
#include <iomanip>
#include <iterator>
#include <limits>
@ -179,13 +180,12 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
false});
}
const auto ByAngle = [](const ConnectedRoad &first, const ConnectedRoad second) {
return first.turn.angle < second.turn.angle;
};
std::sort(std::begin(intersection), std::end(intersection), ByAngle);
std::sort(std::begin(intersection),
std::end(intersection),
std::mem_fn(&ConnectedRoad::compareByAngle));
BOOST_ASSERT(intersection[0].turn.angle >= 0. &&
intersection[0].turn.angle < std::numeric_limits<double>::epsilon());
BOOST_ASSERT(intersection[0].angle >= 0. &&
intersection[0].angle < std::numeric_limits<double>::epsilon());
const auto valid_count =
boost::count_if(intersection, [](const ConnectedRoad &road) { return road.entry_allowed; });
@ -196,13 +196,13 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
// that was inserted together with setting uturn_could_be_valid flag
std::size_t self_u_turn = 0;
while (self_u_turn < intersection.size() &&
intersection[self_u_turn].turn.angle < std::numeric_limits<double>::epsilon() &&
from_node != node_based_graph.GetTarget(intersection[self_u_turn].turn.eid))
intersection[self_u_turn].angle < std::numeric_limits<double>::epsilon() &&
from_node != node_based_graph.GetTarget(intersection[self_u_turn].eid))
{
++self_u_turn;
}
BOOST_ASSERT(from_node == node_based_graph.GetTarget(intersection[self_u_turn].turn.eid));
BOOST_ASSERT(from_node == node_based_graph.GetTarget(intersection[self_u_turn].eid));
intersection[self_u_turn].entry_allowed = true;
}
return intersection;
@ -215,8 +215,8 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection,
std::size_t first_index,
std::size_t second_index) const
{
const auto &first_data = node_based_graph.GetEdgeData(intersection[first_index].turn.eid);
const auto &second_data = node_based_graph.GetEdgeData(intersection[second_index].turn.eid);
const auto &first_data = node_based_graph.GetEdgeData(intersection[first_index].eid);
const auto &second_data = node_based_graph.GetEdgeData(intersection[second_index].eid);
// only merge named ids
if (first_data.name_id == EMPTY_NAMEID)
@ -245,17 +245,16 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection,
return false;
// mergeable if the angle is not too big
const auto angle_between = angularDeviation(intersection[first_index].turn.angle,
intersection[second_index].turn.angle);
const auto angle_between =
angularDeviation(intersection[first_index].angle, intersection[second_index].angle);
const auto intersection_lanes =
getLaneCountAtIntersection(node_at_intersection, node_based_graph);
const auto intersection_lanes = intersection.getHighestConnectedLaneCount(node_based_graph);
const auto coordinate_at_in_edge = coordinate_extractor.GetCoordinateAlongRoad(
node_at_intersection,
intersection[0].turn.eid,
const auto coordinate_at_in_edge =
coordinate_extractor.GetCoordinateAlongRoad(node_at_intersection,
intersection[0].eid,
!INVERT,
node_based_graph.GetTarget(intersection[0].turn.eid),
node_based_graph.GetTarget(intersection[0].eid),
intersection_lanes);
const auto coordinate_at_intersection = node_info_list[node_at_intersection];
@ -272,7 +271,7 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection,
const auto GetActualTarget = [&](const std::size_t index) {
EdgeID last_in_edge_id;
GetActualNextIntersection(
node_at_intersection, intersection[index].turn.eid, nullptr, &last_in_edge_id);
node_at_intersection, intersection[index].eid, nullptr, &last_in_edge_id);
return node_based_graph.GetTarget(last_in_edge_id);
};
@ -292,12 +291,11 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection,
const bool becomes_narrower =
angularDeviation(turn_angle, other_turn_angle) < NARROW_TURN_ANGLE &&
angularDeviation(turn_angle, other_turn_angle) <=
angularDeviation(intersection[index].turn.angle,
intersection[other_index].turn.angle);
angularDeviation(intersection[index].angle, intersection[other_index].angle);
const bool has_same_deviation =
std::abs(angularDeviation(intersection[index].turn.angle, STRAIGHT_ANGLE) -
angularDeviation(intersection[other_index].turn.angle, STRAIGHT_ANGLE)) <
std::abs(angularDeviation(intersection[index].angle, STRAIGHT_ANGLE) -
angularDeviation(intersection[other_index].angle, STRAIGHT_ANGLE)) <
MAXIMAL_ALLOWED_NO_TURN_DEVIATION;
return becomes_narrower || has_same_deviation;
@ -330,17 +328,14 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection,
}();
// needs to be same road coming in
if (node_based_graph.GetEdgeData(intersection[third_index].turn.eid).name_id !=
first_data.name_id)
if (node_based_graph.GetEdgeData(intersection[third_index].eid).name_id != first_data.name_id)
return false;
// we only allow collapsing of a Y like fork. So the angle to the third index has to be
// roughly equal:
const auto y_angle_difference =
angularDeviation(angularDeviation(intersection[third_index].turn.angle,
intersection[first_index].turn.angle),
angularDeviation(intersection[third_index].turn.angle,
intersection[second_index].turn.angle));
const auto y_angle_difference = angularDeviation(
angularDeviation(intersection[third_index].angle, intersection[first_index].angle),
angularDeviation(intersection[third_index].angle, intersection[second_index].angle));
// Allow larger angles if its three roads only of the same name
// This is a heuristic and might need to be revised.
@ -403,10 +398,10 @@ Intersection IntersectionGenerator::MergeSegregatedRoads(const NodeID intersecti
const auto merge = [combineAngles](const ConnectedRoad &first,
const ConnectedRoad &second) -> ConnectedRoad {
ConnectedRoad result = first.entry_allowed ? first : second;
result.turn.angle = combineAngles(first.turn.angle, second.turn.angle);
result.turn.bearing = combineAngles(first.turn.bearing, second.turn.bearing);
BOOST_ASSERT(0 <= result.turn.angle && result.turn.angle <= 360.0);
BOOST_ASSERT(0 <= result.turn.bearing && result.turn.bearing <= 360.0);
result.angle = combineAngles(first.angle, second.angle);
result.bearing = combineAngles(first.bearing, second.bearing);
BOOST_ASSERT(0 <= result.angle && result.angle <= 360.0);
BOOST_ASSERT(0 <= result.bearing && result.bearing <= 360.0);
return result;
};
@ -416,7 +411,7 @@ Intersection IntersectionGenerator::MergeSegregatedRoads(const NodeID intersecti
const bool is_connected_to_roundabout = [this, &intersection]() {
for (const auto &road : intersection)
{
if (node_based_graph.GetEdgeData(road.turn.eid).roundabout)
if (node_based_graph.GetEdgeData(road.eid).roundabout)
return true;
}
return false;
@ -459,26 +454,25 @@ Intersection IntersectionGenerator::MergeSegregatedRoads(const NodeID intersecti
{
merged_first = true;
// moving `a` to the left
const double correction_factor =
(360 - intersection[intersection.size() - 1].turn.angle) / 2;
const double correction_factor = (360 - intersection[intersection.size() - 1].angle) / 2;
for (std::size_t i = 1; i + 1 < intersection.size(); ++i)
intersection[i].turn.angle += correction_factor;
intersection[i].angle += correction_factor;
// FIXME if we have a left-sided country, we need to switch this off and enable it
// below
intersection[0] = merge(intersection.front(), intersection.back());
intersection[0].turn.angle = 0;
intersection[0].angle = 0;
intersection.pop_back();
}
else if (CanMerge(intersection_node, intersection, 0, 1))
{
merged_first = true;
// moving `a` to the right
const double correction_factor = (intersection[1].turn.angle) / 2;
const double correction_factor = (intersection[1].angle) / 2;
for (std::size_t i = 2; i < intersection.size(); ++i)
intersection[i].turn.angle -= correction_factor;
intersection[i].angle -= correction_factor;
intersection[0] = merge(intersection[0], intersection[1]);
intersection[0].turn.angle = 0;
intersection[0].angle = 0;
intersection.erase(intersection.begin() + 1);
}
@ -510,10 +504,9 @@ Intersection IntersectionGenerator::MergeSegregatedRoads(const NodeID intersecti
}
}
const auto ByAngle = [](const ConnectedRoad &first, const ConnectedRoad second) {
return first.turn.angle < second.turn.angle;
};
std::sort(std::begin(intersection), std::end(intersection), ByAngle);
std::sort(std::begin(intersection),
std::end(intersection),
std::mem_fn(&ConnectedRoad::compareByAngle));
return intersection;
}
@ -552,13 +545,12 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i
// to find out about the above situation, we need to look at the next intersection (at d in
// the example). If the initial road can be merged to the left/right, we are about to adjust
// the angle.
const auto next_intersection_along_road =
GetConnectedRoads(node_at_intersection, road.turn.eid);
const auto next_intersection_along_road = GetConnectedRoads(node_at_intersection, road.eid);
if (next_intersection_along_road.size() <= 1)
continue;
const auto node_at_next_intersection = node_based_graph.GetTarget(road.turn.eid);
const auto node_at_next_intersection = node_based_graph.GetTarget(road.eid);
const util::Coordinate coordinate_at_next_intersection =
node_info_list[node_at_next_intersection];
if (util::coordinate_calculation::haversineDistance(coordinate_at_intersection,
@ -580,7 +572,7 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i
// the order does not matter
const auto get_offset = [](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
return 0.5 * angularDeviation(lhs.turn.angle, rhs.turn.angle);
return 0.5 * angularDeviation(lhs.angle, rhs.angle);
};
// When offsetting angles in our turns, we don't want to get past the next turn. This
@ -590,7 +582,7 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i
const ConnectedRoad &road,
const ConnectedRoad &next_road_in_offset_direction) {
const auto offset_limit =
angularDeviation(road.turn.angle, next_road_in_offset_direction.turn.angle);
angularDeviation(road.angle, next_road_in_offset_direction.angle);
// limit the offset with an additional buffer
return (offset + MAXIMAL_ALLOWED_NO_TURN_DEVIATION > offset_limit) ? 0.5 * offset_limit
: offset;
@ -608,8 +600,8 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i
get_corrected_offset(offset, road, intersection[(index + 1) % intersection.size()]);
// at the target intersection, we merge to the right, so we need to shift the current
// angle to the left
road.turn.angle = adjustAngle(road.turn.angle, corrected_offset);
road.turn.bearing = adjustAngle(road.turn.bearing, corrected_offset);
road.angle = adjustAngle(road.angle, corrected_offset);
road.bearing = adjustAngle(road.bearing, corrected_offset);
}
else if (CanMerge(node_at_next_intersection,
next_intersection_along_road,
@ -624,8 +616,8 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i
get_corrected_offset(offset, road, intersection[index - 1]);
// at the target intersection, we merge to the left, so we need to shift the current
// angle to the right
road.turn.angle = adjustAngle(road.turn.angle, -corrected_offset);
road.turn.bearing = adjustAngle(road.turn.bearing, -corrected_offset);
road.angle = adjustAngle(road.angle, -corrected_offset);
road.bearing = adjustAngle(road.bearing, -corrected_offset);
}
}
return intersection;
@ -653,11 +645,11 @@ IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node,
while (visited_nodes.count(node_at_intersection) == 0 &&
(result.size() == 2 &&
node_based_graph.GetEdgeData(via_edge).IsCompatibleTo(
node_based_graph.GetEdgeData(result[1].turn.eid))))
node_based_graph.GetEdgeData(result[1].eid))))
{
visited_nodes.insert(node_at_intersection);
node_at_intersection = node_based_graph.GetTarget(incoming_edge);
incoming_edge = result[1].turn.eid;
incoming_edge = result[1].eid;
result = GetConnectedRoads(node_at_intersection, incoming_edge);
// When looping back to the original node, we obviously are in a loop. Stop there.

View File

@ -50,7 +50,7 @@ TurnType::Enum IntersectionHandler::findBasicTurnType(const EdgeID via_edge,
{
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
const auto &out_data = node_based_graph.GetEdgeData(road.eid);
bool on_ramp = in_data.road_classification.IsRampClass();
@ -75,20 +75,20 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
const auto type = findBasicTurnType(via_edge, road);
// handle travel modes:
const auto in_mode = node_based_graph.GetEdgeData(via_edge).travel_mode;
const auto out_mode = node_based_graph.GetEdgeData(road.turn.eid).travel_mode;
const auto out_mode = node_based_graph.GetEdgeData(road.eid).travel_mode;
if (type == TurnType::OnRamp)
{
return {TurnType::OnRamp, getTurnDirection(road.turn.angle)};
return {TurnType::OnRamp, getTurnDirection(road.angle)};
}
if (angularDeviation(road.turn.angle, 0) < 0.01)
if (angularDeviation(road.angle, 0) < 0.01)
{
return {TurnType::Turn, DirectionModifier::UTurn};
}
if (type == TurnType::Turn)
{
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
const auto &out_data = node_based_graph.GetEdgeData(road.eid);
if (in_data.name_id != out_data.name_id &&
util::guidance::requiresNameAnnounced(name_table.GetNameForID(in_data.name_id),
name_table.GetRefForID(in_data.name_id),
@ -104,7 +104,7 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
// that could potentially also offer different choices
if (out_data.road_classification.IsMotorwayClass())
return {TurnType::Merge,
road.turn.angle > STRAIGHT_ANGLE ? DirectionModifier::SlightRight
road.angle > STRAIGHT_ANGLE ? DirectionModifier::SlightRight
: DirectionModifier::SlightLeft};
else if (in_data.road_classification.IsRampClass() &&
out_data.road_classification.IsRampClass())
@ -113,7 +113,7 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
// cannot reach this, since all ramps are exposing the same travel type. But we
// could see toll-type at some point.
return {in_mode == out_mode ? TurnType::Suppressed : TurnType::Notification,
getTurnDirection(road.turn.angle)};
getTurnDirection(road.angle)};
}
else
{
@ -129,40 +129,40 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
// precalculated distance value.
const auto distance = util::coordinate_calculation::haversineDistance(
node_info_list[node_based_graph.GetTarget(via_edge)],
node_info_list[node_based_graph.GetTarget(road.turn.eid)]);
return {TurnType::Turn,
(angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <
FUZZY_ANGLE_DIFFERENCE ||
node_info_list[node_based_graph.GetTarget(road.eid)]);
return {
TurnType::Turn,
(angularDeviation(road.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE ||
distance > 2 * MAX_COLLAPSE_DISTANCE)
? DirectionModifier::Straight
: getTurnDirection(road.turn.angle)};
: getTurnDirection(road.angle)};
}
}
else
{
return {in_mode == out_mode ? TurnType::NewName : TurnType::Notification,
getTurnDirection(road.turn.angle)};
getTurnDirection(road.angle)};
}
}
// name has not changed, suppress a turn here or indicate mode change
else
{
return {in_mode == out_mode ? TurnType::Suppressed : TurnType::Notification,
getTurnDirection(road.turn.angle)};
getTurnDirection(road.angle)};
}
}
BOOST_ASSERT(type == TurnType::Continue);
if (in_mode != out_mode)
{
return {TurnType::Notification, getTurnDirection(road.turn.angle)};
return {TurnType::Notification, getTurnDirection(road.angle)};
}
if (num_roads > 2)
{
return {TurnType::Suppressed, getTurnDirection(road.turn.angle)};
return {TurnType::Suppressed, getTurnDirection(road.angle)};
}
else
{
return {TurnType::NoTurn, getTurnDirection(road.turn.angle)};
return {TurnType::NoTurn, getTurnDirection(road.angle)};
}
}
@ -172,107 +172,105 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
{
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
const bool low_priority_left =
node_based_graph.GetEdgeData(left.turn.eid).road_classification.IsLowPriorityRoadClass();
node_based_graph.GetEdgeData(left.eid).road_classification.IsLowPriorityRoadClass();
const bool low_priority_right =
node_based_graph.GetEdgeData(right.turn.eid).road_classification.IsLowPriorityRoadClass();
if ((angularDeviation(left.turn.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(right.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE))
node_based_graph.GetEdgeData(right.eid).road_classification.IsLowPriorityRoadClass();
if ((angularDeviation(left.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(right.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE))
{
// left side is actually straight
const auto &out_data = node_based_graph.GetEdgeData(left.turn.eid);
const auto &out_data = node_based_graph.GetEdgeData(left.eid);
if (detail::requiresAnnouncement(in_data, out_data))
{
if (low_priority_right && !low_priority_left)
{
left.turn.instruction = getInstructionForObvious(3, via_edge, false, left);
right.turn.instruction = {findBasicTurnType(via_edge, right),
left.instruction = getInstructionForObvious(3, via_edge, false, left);
right.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
else
{
if (low_priority_left && !low_priority_right)
{
left.turn.instruction = {findBasicTurnType(via_edge, left),
left.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
right.turn.instruction = {findBasicTurnType(via_edge, right),
right.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
else
{
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
right.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
}
}
}
else
{
left.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
right.turn.instruction = {findBasicTurnType(via_edge, right),
left.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
right.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
}
else if (angularDeviation(right.turn.angle, STRAIGHT_ANGLE) <
MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(left.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)
else if (angularDeviation(right.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(left.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)
{
// right side is actually straight
const auto &out_data = node_based_graph.GetEdgeData(right.turn.eid);
if (angularDeviation(right.turn.angle, STRAIGHT_ANGLE) <
MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(left.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)
const auto &out_data = node_based_graph.GetEdgeData(right.eid);
if (angularDeviation(right.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(left.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)
{
if (detail::requiresAnnouncement(in_data, out_data))
{
if (low_priority_left && !low_priority_right)
{
left.turn.instruction = {findBasicTurnType(via_edge, left),
left.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
right.turn.instruction = getInstructionForObvious(3, via_edge, false, right);
right.instruction = getInstructionForObvious(3, via_edge, false, right);
}
else
{
if (low_priority_right && !low_priority_left)
{
left.turn.instruction = {findBasicTurnType(via_edge, left),
left.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
right.turn.instruction = {findBasicTurnType(via_edge, right),
right.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
else
{
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
right.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
}
}
}
else
{
right.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
left.turn.instruction = {findBasicTurnType(via_edge, left),
right.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
left.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
}
}
}
// left side of fork
if (low_priority_right && !low_priority_left)
left.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
left.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
else
{
if (low_priority_left && !low_priority_right)
left.turn.instruction = {TurnType::Turn, DirectionModifier::SlightLeft};
left.instruction = {TurnType::Turn, DirectionModifier::SlightLeft};
else
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
}
// right side of fork
if (low_priority_left && !low_priority_right)
right.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
right.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
else
{
if (low_priority_right && !low_priority_left)
right.turn.instruction = {TurnType::Turn, DirectionModifier::SlightRight};
right.instruction = {TurnType::Turn, DirectionModifier::SlightRight};
else
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
right.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
}
}
@ -284,25 +282,25 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
// TODO handle low priority road classes in a reasonable way
if (left.entry_allowed && center.entry_allowed && right.entry_allowed)
{
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
if (angularDeviation(center.turn.angle, 180) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
if (angularDeviation(center.angle, 180) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
{
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
const auto &out_data = node_based_graph.GetEdgeData(center.turn.eid);
const auto &out_data = node_based_graph.GetEdgeData(center.eid);
if (detail::requiresAnnouncement(in_data, out_data))
{
center.turn.instruction = {TurnType::Fork, DirectionModifier::Straight};
center.instruction = {TurnType::Fork, DirectionModifier::Straight};
}
else
{
center.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
center.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
}
}
else
{
center.turn.instruction = {TurnType::Fork, DirectionModifier::Straight};
center.instruction = {TurnType::Fork, DirectionModifier::Straight};
}
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
right.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
}
else if (left.entry_allowed)
{
@ -311,22 +309,20 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
else if (center.entry_allowed)
assignFork(via_edge, left, center);
else
left.turn.instruction = {findBasicTurnType(via_edge, left),
getTurnDirection(left.turn.angle)};
left.instruction = {findBasicTurnType(via_edge, left), getTurnDirection(left.angle)};
}
else if (right.entry_allowed)
{
if (center.entry_allowed)
assignFork(via_edge, center, right);
else
right.turn.instruction = {findBasicTurnType(via_edge, right),
getTurnDirection(right.turn.angle)};
right.instruction = {findBasicTurnType(via_edge, right), getTurnDirection(right.angle)};
}
else
{
if (center.entry_allowed)
center.turn.instruction = {findBasicTurnType(via_edge, center),
getTurnDirection(center.turn.angle)};
center.instruction = {findBasicTurnType(via_edge, center),
getTurnDirection(center.angle)};
}
}
@ -337,18 +333,17 @@ void IntersectionHandler::assignTrivialTurns(const EdgeID via_eid,
{
for (std::size_t index = begin; index != end; ++index)
if (intersection[index].entry_allowed)
intersection[index].turn.instruction = {
findBasicTurnType(via_eid, intersection[index]),
getTurnDirection(intersection[index].turn.angle)};
intersection[index].instruction = {findBasicTurnType(via_eid, intersection[index]),
getTurnDirection(intersection[index].angle)};
}
bool IntersectionHandler::isThroughStreet(const std::size_t index,
const Intersection &intersection) const
{
if (node_based_graph.GetEdgeData(intersection[index].turn.eid).name_id == EMPTY_NAMEID)
if (node_based_graph.GetEdgeData(intersection[index].eid).name_id == EMPTY_NAMEID)
return false;
const auto &data_at_index = node_based_graph.GetEdgeData(intersection[index].turn.eid);
const auto &data_at_index = node_based_graph.GetEdgeData(intersection[index].eid);
// a through street cannot start at our own position -> index 1
for (std::size_t road_index = 1; road_index < intersection.size(); ++road_index)
@ -357,11 +352,10 @@ bool IntersectionHandler::isThroughStreet(const std::size_t index,
continue;
const auto &road = intersection[road_index];
const auto &road_data = node_based_graph.GetEdgeData(road.turn.eid);
const auto &road_data = node_based_graph.GetEdgeData(road.eid);
// roads have a near straight angle (180 degree)
const bool is_nearly_straight =
angularDeviation(road.turn.angle, intersection[index].turn.angle) >
const bool is_nearly_straight = angularDeviation(road.angle, intersection[index].angle) >
(STRAIGHT_ANGLE - FUZZY_ANGLE_DIFFERENCE);
const bool have_same_name = data_at_index.name_id == road_data.name_id;
@ -397,13 +391,13 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
for (std::size_t i = 1; i < intersection.size(); ++i)
{
const double deviation = angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE);
const double deviation = angularDeviation(intersection[i].angle, STRAIGHT_ANGLE);
if (!intersection[i].entry_allowed)
continue;
const auto out_data = node_based_graph.GetEdgeData(intersection[i].turn.eid);
const auto out_data = node_based_graph.GetEdgeData(intersection[i].eid);
const auto continue_class =
node_based_graph.GetEdgeData(intersection[best_continue].turn.eid).road_classification;
node_based_graph.GetEdgeData(intersection[best_continue].eid).road_classification;
if (out_data.name_id == in_data.name_id &&
(best_continue == 0 ||
@ -419,7 +413,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
}
const auto current_best_class =
node_based_graph.GetEdgeData(intersection[best_continue].turn.eid).road_classification;
node_based_graph.GetEdgeData(intersection[best_continue].eid).road_classification;
// don't prefer low priority classes
if (best != 0 && out_data.road_classification.IsLowPriorityRoadClass() &&
@ -459,7 +453,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
for (std::size_t i = 1; i < intersection.size(); ++i)
{
const auto &road = intersection[i];
if ((in_data.name_id == node_based_graph.GetEdgeData(road.turn.eid).name_id))
if ((in_data.name_id == node_based_graph.GetEdgeData(road.eid).name_id))
{
++count;
if (road.entry_allowed)
@ -471,10 +465,10 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
}();
if (0 != best_continue && best != best_continue &&
angularDeviation(intersection[best].turn.angle, STRAIGHT_ANGLE) <
angularDeviation(intersection[best].angle, STRAIGHT_ANGLE) <
MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
node_based_graph.GetEdgeData(intersection[best_continue].turn.eid).road_classification ==
node_based_graph.GetEdgeData(intersection[best].turn.eid).road_classification)
node_based_graph.GetEdgeData(intersection[best_continue].eid).road_classification ==
node_based_graph.GetEdgeData(intersection[best].eid).road_classification)
{
// if the best angle is going straight but the road is turning, we don't name anything
// obvious
@ -487,14 +481,13 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
return std::count_if(
intersection.begin() + 1, intersection.end(), [&](const ConnectedRoad &road) {
return (in_data.name_id ==
node_based_graph.GetEdgeData(road.turn.eid).name_id) &&
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE;
return (in_data.name_id == node_based_graph.GetEdgeData(road.eid).name_id) &&
angularDeviation(road.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE;
}) == num_continue_names.first;
}();
// has no obvious continued road
const auto &best_data = node_based_graph.GetEdgeData(intersection[best].turn.eid);
const auto &best_data = node_based_graph.GetEdgeData(intersection[best].eid);
const auto check_non_continue = [&]() {
// no continue road exists
@ -512,8 +505,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
return true;
// continue data now most certainly exists
const auto &continue_data =
node_based_graph.GetEdgeData(intersection[best_continue].turn.eid);
const auto &continue_data = node_based_graph.GetEdgeData(intersection[best_continue].eid);
if (obviousByRoadClass(in_data.road_classification,
continue_data.road_classification,
@ -550,7 +542,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
if (index_candidate == 0)
return index_candidate;
const auto &candidate_data =
node_based_graph.GetEdgeData(intersection[index_candidate].turn.eid);
node_based_graph.GetEdgeData(intersection[index_candidate].eid);
if (obviousByRoadClass(in_data.road_classification,
best_data.road_classification,
candidate_data.road_classification))
@ -565,7 +557,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
if (index_candidate == 0)
return index_candidate;
const auto candidate_data =
node_based_graph.GetEdgeData(intersection[index_candidate].turn.eid);
node_based_graph.GetEdgeData(intersection[index_candidate].eid);
if (obviousByRoadClass(in_data.road_classification,
best_data.road_classification,
candidate_data.road_classification))
@ -575,16 +567,16 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
}();
const double left_deviation =
angularDeviation(intersection[left_index].turn.angle, STRAIGHT_ANGLE);
angularDeviation(intersection[left_index].angle, STRAIGHT_ANGLE);
const double right_deviation =
angularDeviation(intersection[right_index].turn.angle, STRAIGHT_ANGLE);
angularDeviation(intersection[right_index].angle, STRAIGHT_ANGLE);
if (best_deviation < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
std::min(left_deviation, right_deviation) > FUZZY_ANGLE_DIFFERENCE)
return best;
const auto &left_data = node_based_graph.GetEdgeData(intersection[left_index].turn.eid);
const auto &right_data = node_based_graph.GetEdgeData(intersection[right_index].turn.eid);
const auto &left_data = node_based_graph.GetEdgeData(intersection[left_index].eid);
const auto &right_data = node_based_graph.GetEdgeData(intersection[right_index].eid);
const bool obvious_to_left =
left_index == 0 || obviousByRoadClass(in_data.road_classification,
@ -598,7 +590,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
// if the best turn isn't narrow, but there is a nearly straight turn, we don't consider the
// turn obvious
const auto check_narrow = [&intersection, best_deviation](const std::size_t index) {
return angularDeviation(intersection[index].turn.angle, STRAIGHT_ANGLE) <=
return angularDeviation(intersection[index].angle, STRAIGHT_ANGLE) <=
FUZZY_ANGLE_DIFFERENCE &&
(best_deviation > NARROW_TURN_ANGLE || intersection[index].entry_allowed);
};
@ -624,7 +616,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
// a bit less obvious are road classes
else if (in_data.road_classification == best_data.road_classification &&
best_data.road_classification.GetPriority() <
node_based_graph.GetEdgeData(intersection[index].turn.eid)
node_based_graph.GetEdgeData(intersection[index].eid)
.road_classification.GetPriority())
return 0.8 * DISTINCTION_RATIO;
// if road classes are the same, we use the full ratio
@ -644,9 +636,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
else
{
const double deviation =
angularDeviation(intersection[best_continue].turn.angle, STRAIGHT_ANGLE);
const auto &continue_data =
node_based_graph.GetEdgeData(intersection[best_continue].turn.eid);
angularDeviation(intersection[best_continue].angle, STRAIGHT_ANGLE);
const auto &continue_data = node_based_graph.GetEdgeData(intersection[best_continue].eid);
if (std::abs(deviation) < 1)
return best_continue;
@ -656,7 +647,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
if (i == best_continue || !intersection[i].entry_allowed)
continue;
const auto &turn_data = node_based_graph.GetEdgeData(intersection[i].turn.eid);
const auto &turn_data = node_based_graph.GetEdgeData(intersection[i].eid);
const bool is_obvious_by_road_class =
obviousByRoadClass(in_data.road_classification,
continue_data.road_classification,
@ -672,8 +663,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
continue;
// perfectly straight turns prevent obviousness
const auto turn_deviation =
angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE);
const auto turn_deviation = angularDeviation(intersection[i].angle, STRAIGHT_ANGLE);
if (turn_deviation < FUZZY_ANGLE_DIFFERENCE)
return 0;
@ -708,7 +698,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
const auto node_at_intersection = node_based_graph.GetTarget(via_edge);
const util::Coordinate coordinate_at_intersection = node_info_list[node_at_intersection];
const auto node_at_u_turn = node_based_graph.GetTarget(intersection[0].turn.eid);
const auto node_at_u_turn = node_based_graph.GetTarget(intersection[0].eid);
const util::Coordinate coordinate_at_u_turn = node_info_list[node_at_u_turn];
const double constexpr MAX_COLLAPSE_DISTANCE = 30;
@ -720,7 +710,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
// try to find whether there is a turn going to the opposite direction of our obvious
// turn, this should be alright.
const auto previous_intersection = intersection_generator.GetActualNextIntersection(
node_at_intersection, intersection[0].turn.eid, nullptr, nullptr);
node_at_intersection, intersection[0].eid, nullptr, nullptr);
const auto continue_road = intersection[best_continue];
for (const auto &comparison_road : previous_intersection)
@ -729,9 +719,9 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
// actually represents a near 180 degree different in bearings between the two
// roads. So if there is a road that is enterable in the opposite direction just
// prior, a turn is not obvious
const auto &turn_data = node_based_graph.GetEdgeData(comparison_road.turn.eid);
if (angularDeviation(comparison_road.turn.angle, STRAIGHT_ANGLE) > GROUP_ANGLE &&
angularDeviation(comparison_road.turn.angle, continue_road.turn.angle) <
const auto &turn_data = node_based_graph.GetEdgeData(comparison_road.eid);
if (angularDeviation(comparison_road.angle, STRAIGHT_ANGLE) > GROUP_ANGLE &&
angularDeviation(comparison_road.angle, continue_road.angle) <
FUZZY_ANGLE_DIFFERENCE &&
!turn_data.reversed && continue_data.CanCombineWith(turn_data))
return 0;

View File

@ -17,9 +17,9 @@ bool isEndOfRoad(const ConnectedRoad &,
const ConnectedRoad &possible_right_turn,
const ConnectedRoad &possible_left_turn)
{
return angularDeviation(possible_right_turn.turn.angle, 90) < NARROW_TURN_ANGLE &&
angularDeviation(possible_left_turn.turn.angle, 270) < NARROW_TURN_ANGLE &&
angularDeviation(possible_right_turn.turn.angle, possible_left_turn.turn.angle) >
return angularDeviation(possible_right_turn.angle, 90) < NARROW_TURN_ANGLE &&
angularDeviation(possible_left_turn.angle, 270) < NARROW_TURN_ANGLE &&
angularDeviation(possible_right_turn.angle, possible_left_turn.angle) >
2 * NARROW_TURN_ANGLE;
}

View File

@ -30,7 +30,7 @@ inline bool isMotorwayClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_
inline RoadClassification roadClass(const ConnectedRoad &road,
const util::NodeBasedDynamicGraph &graph)
{
return graph.GetEdgeData(road.turn.eid).road_classification;
return graph.GetEdgeData(road.eid).road_classification;
}
inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph)
@ -63,14 +63,14 @@ bool MotorwayHandler::canProcess(const NodeID,
for (const auto &road : intersection)
{
// not merging or forking?
if (road.entry_allowed && angularDeviation(road.turn.angle, STRAIGHT_ANGLE) > 60)
if (road.entry_allowed && angularDeviation(road.angle, STRAIGHT_ANGLE) > 60)
return false;
else if (isMotorwayClass(road.turn.eid, node_based_graph))
else if (isMotorwayClass(road.eid, node_based_graph))
{
if (road.entry_allowed)
has_motorway = true;
}
else if (!isRampClass(road.turn.eid, node_based_graph))
else if (!isRampClass(road.eid, node_based_graph))
has_normal_roads = true;
}
@ -88,8 +88,8 @@ operator()(const NodeID, const EdgeID via_eid, Intersection intersection) const
{
intersection = fromMotorway(via_eid, std::move(intersection));
std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) {
if (road.turn.instruction.type == TurnType::OnRamp)
road.turn.instruction.type = TurnType::OffRamp;
if (road.instruction.type == TurnType::OnRamp)
road.instruction.type = TurnType::OffRamp;
});
return intersection;
}
@ -109,7 +109,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
unsigned count = 0;
for (const auto &road : intersection)
{
if (road.entry_allowed && isMotorwayClass(road.turn.eid, node_based_graph))
if (road.entry_allowed && isMotorwayClass(road.eid, node_based_graph))
++count;
}
return count;
@ -119,24 +119,24 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
const auto getContinueAngle = [this, in_data](const Intersection &intersection) {
for (const auto &road : intersection)
{
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
if (road.turn.angle != 0 && in_data.name_id == out_data.name_id &&
in_data.name_id != EMPTY_NAMEID && isMotorwayClass(road.turn.eid, node_based_graph))
return road.turn.angle;
const auto &out_data = node_based_graph.GetEdgeData(road.eid);
if (road.angle != 0 && in_data.name_id == out_data.name_id &&
in_data.name_id != EMPTY_NAMEID && isMotorwayClass(road.eid, node_based_graph))
return road.angle;
}
return intersection[0].turn.angle;
return intersection[0].angle;
};
const auto getMostLikelyContinue = [this, in_data](const Intersection &intersection) {
double angle = intersection[0].turn.angle;
double angle = intersection[0].angle;
double best = 180;
for (const auto &road : intersection)
{
if (isMotorwayClass(road.turn.eid, node_based_graph) &&
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < best)
if (isMotorwayClass(road.eid, node_based_graph) &&
angularDeviation(road.angle, STRAIGHT_ANGLE) < best)
{
best = angularDeviation(road.turn.angle, STRAIGHT_ANGLE);
angle = road.turn.angle;
best = angularDeviation(road.angle, STRAIGHT_ANGLE);
angle = road.angle;
}
}
return angle;
@ -144,7 +144,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
const auto findBestContinue = [&]() {
const double continue_angle = getContinueAngle(intersection);
if (continue_angle != intersection[0].turn.angle)
if (continue_angle != intersection[0].angle)
return continue_angle;
else
return getMostLikelyContinue(intersection);
@ -153,13 +153,13 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
// find continue angle
const double continue_angle = findBestContinue();
// highway does not continue and has no obvious choice
if (continue_angle == intersection[0].turn.angle)
if (continue_angle == intersection[0].angle)
{
if (intersection.size() == 2)
{
// do not announce ramps at the end of a highway
intersection[1].turn.instruction = {TurnType::NoTurn,
getTurnDirection(intersection[1].turn.angle)};
intersection[1].instruction = {TurnType::NoTurn,
getTurnDirection(intersection[1].angle)};
}
else if (intersection.size() == 3)
{
@ -172,11 +172,11 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
{
// ending in a passing ramp
if (intersection[1].entry_allowed)
intersection[1].turn.instruction = {
TurnType::NoTurn, getTurnDirection(intersection[1].turn.angle)};
intersection[1].instruction = {TurnType::NoTurn,
getTurnDirection(intersection[1].angle)};
else
intersection[2].turn.instruction = {
TurnType::NoTurn, getTurnDirection(intersection[2].turn.angle)};
intersection[2].instruction = {TurnType::NoTurn,
getTurnDirection(intersection[2].angle)};
}
}
else if (intersection.size() == 4 &&
@ -209,9 +209,8 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
{
if (road.entry_allowed)
{
BOOST_ASSERT(isRampClass(road.turn.eid, node_based_graph));
road.turn.instruction =
TurnInstruction::SUPPRESSED(getTurnDirection(road.turn.angle));
BOOST_ASSERT(isRampClass(road.eid, node_based_graph));
road.instruction = TurnInstruction::SUPPRESSED(getTurnDirection(road.angle));
}
}
}
@ -220,9 +219,9 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
// normal motorway passing some ramps or mering onto another motorway
if (intersection.size() == 2)
{
BOOST_ASSERT(!isRampClass(intersection[1].turn.eid, node_based_graph));
BOOST_ASSERT(!isRampClass(intersection[1].eid, node_based_graph));
intersection[1].turn.instruction =
intersection[1].instruction =
getInstructionForObvious(intersection.size(),
via_eid,
isThroughStreet(1, intersection),
@ -237,25 +236,25 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
if (!road.entry_allowed)
continue;
if (road.turn.angle == continue_angle)
if (road.angle == continue_angle)
{
road.turn.instruction = getInstructionForObvious(
road.instruction = getInstructionForObvious(
intersection.size(), via_eid, isThroughStreet(1, intersection), road);
}
else if (road.turn.angle < continue_angle)
else if (road.angle < continue_angle)
{
road.turn.instruction = {
isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp
road.instruction = {isRampClass(road.eid, node_based_graph)
? TurnType::OffRamp
: TurnType::Turn,
(road.turn.angle < 145) ? DirectionModifier::Right
(road.angle < 145) ? DirectionModifier::Right
: DirectionModifier::SlightRight};
}
else if (road.turn.angle > continue_angle)
else if (road.angle > continue_angle)
{
road.turn.instruction = {
isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp
road.instruction = {isRampClass(road.eid, node_based_graph)
? TurnType::OffRamp
: TurnType::Turn,
(road.turn.angle > 215) ? DirectionModifier::Left
(road.angle > 215) ? DirectionModifier::Left
: DirectionModifier::SlightLeft};
}
}
@ -266,7 +265,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
{
if (exiting_motorways == 2 && intersection.size() == 2)
{
intersection[1].turn.instruction =
intersection[1].instruction =
getInstructionForObvious(intersection.size(),
via_eid,
isThroughStreet(1, intersection),
@ -282,7 +281,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
for (std::size_t i = 0; i < intersection.size(); ++i)
{
if (intersection[i].entry_allowed &&
isMotorwayClass(intersection[i].turn.eid, node_based_graph))
isMotorwayClass(intersection[i].eid, node_based_graph))
{
if (first_valid < intersection.size())
{
@ -306,7 +305,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
for (std::size_t i = 0; i < intersection.size(); ++i)
{
if (intersection[i].entry_allowed &&
isMotorwayClass(intersection[i].turn.eid, node_based_graph))
isMotorwayClass(intersection[i].eid, node_based_graph))
{
if (second_valid < intersection.size())
{
@ -346,9 +345,9 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
if (intersection.size() == 2 && num_valid_turns == 1)
{
BOOST_ASSERT(!intersection[0].entry_allowed);
BOOST_ASSERT(isMotorwayClass(intersection[1].turn.eid, node_based_graph));
BOOST_ASSERT(isMotorwayClass(intersection[1].eid, node_based_graph));
intersection[1].turn.instruction = getInstructionForObvious(
intersection[1].instruction = getInstructionForObvious(
intersection.size(), via_eid, isThroughStreet(1, intersection), intersection[1]);
}
else if (intersection.size() == 3)
@ -367,24 +366,23 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
// 0
if (intersection[1].entry_allowed)
{
if (isMotorwayClass(intersection[1].turn.eid, node_based_graph) &&
node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id !=
EMPTY_NAMEID &&
node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id ==
node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id)
if (isMotorwayClass(intersection[1].eid, node_based_graph) &&
node_based_graph.GetEdgeData(intersection[2].eid).name_id != EMPTY_NAMEID &&
node_based_graph.GetEdgeData(intersection[2].eid).name_id ==
node_based_graph.GetEdgeData(intersection[1].eid).name_id)
{
// circular order indicates a merge to the left (0-3 onto 4
if (angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) <
if (angularDeviation(intersection[1].angle, STRAIGHT_ANGLE) <
2 * NARROW_TURN_ANGLE)
intersection[1].turn.instruction = {TurnType::Merge,
intersection[1].instruction = {TurnType::Merge,
DirectionModifier::SlightLeft};
else // fallback
intersection[1].turn.instruction = {
TurnType::Merge, getTurnDirection(intersection[1].turn.angle)};
intersection[1].instruction = {TurnType::Merge,
getTurnDirection(intersection[1].angle)};
}
else // passing by the end of a motorway
{
intersection[1].turn.instruction =
intersection[1].instruction =
getInstructionForObvious(intersection.size(),
via_eid,
isThroughStreet(1, intersection),
@ -394,24 +392,23 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
else
{
BOOST_ASSERT(intersection[2].entry_allowed);
if (isMotorwayClass(intersection[2].turn.eid, node_based_graph) &&
node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id !=
EMPTY_NAMEID &&
node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id ==
node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id)
if (isMotorwayClass(intersection[2].eid, node_based_graph) &&
node_based_graph.GetEdgeData(intersection[1].eid).name_id != EMPTY_NAMEID &&
node_based_graph.GetEdgeData(intersection[2].eid).name_id ==
node_based_graph.GetEdgeData(intersection[1].eid).name_id)
{
// circular order (5-0) onto 4
if (angularDeviation(intersection[2].turn.angle, STRAIGHT_ANGLE) <
if (angularDeviation(intersection[2].angle, STRAIGHT_ANGLE) <
2 * NARROW_TURN_ANGLE)
intersection[2].turn.instruction = {TurnType::Merge,
intersection[2].instruction = {TurnType::Merge,
DirectionModifier::SlightRight};
else // fallback
intersection[2].turn.instruction = {
TurnType::Merge, getTurnDirection(intersection[2].turn.angle)};
intersection[2].instruction = {TurnType::Merge,
getTurnDirection(intersection[2].angle)};
}
else // passing the end of a highway
{
intersection[2].turn.instruction =
intersection[2].instruction =
getInstructionForObvious(intersection.size(),
via_eid,
isThroughStreet(2, intersection),
@ -431,8 +428,8 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
// \ /
// |
// R
if (isMotorwayClass(intersection[1].turn.eid, node_based_graph) &&
isMotorwayClass(intersection[2].turn.eid, node_based_graph))
if (isMotorwayClass(intersection[1].eid, node_based_graph) &&
isMotorwayClass(intersection[2].eid, node_based_graph))
{
assignFork(via_eid, intersection[2], intersection[1]);
}
@ -443,11 +440,10 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
// M R
// | /
// R
if (isMotorwayClass(intersection[1].turn.eid, node_based_graph))
if (isMotorwayClass(intersection[1].eid, node_based_graph))
{
intersection[1].turn.instruction = {TurnType::Turn,
DirectionModifier::SlightRight};
intersection[2].turn.instruction = {TurnType::Continue,
intersection[1].instruction = {TurnType::Turn, DirectionModifier::SlightRight};
intersection[2].instruction = {TurnType::Continue,
DirectionModifier::SlightLeft};
}
else
@ -463,20 +459,20 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
bool passed_highway_entry = false;
for (auto &road : intersection)
{
if (!road.entry_allowed && isMotorwayClass(road.turn.eid, node_based_graph))
if (!road.entry_allowed && isMotorwayClass(road.eid, node_based_graph))
{
passed_highway_entry = true;
}
else if (isMotorwayClass(road.turn.eid, node_based_graph))
else if (isMotorwayClass(road.eid, node_based_graph))
{
road.turn.instruction = {TurnType::Merge,
road.instruction = {TurnType::Merge,
passed_highway_entry ? DirectionModifier::SlightRight
: DirectionModifier::SlightLeft};
}
else
{
BOOST_ASSERT(isRampClass(road.turn.eid, node_based_graph));
road.turn.instruction = {TurnType::OffRamp, getTurnDirection(road.turn.angle)};
BOOST_ASSERT(isRampClass(road.eid, node_based_graph));
road.instruction = {TurnType::OffRamp, getTurnDirection(road.angle)};
}
}
}
@ -498,25 +494,23 @@ Intersection MotorwayHandler::fallback(Intersection intersection) const
continue;
const auto type =
isMotorwayClass(road.turn.eid, node_based_graph) ? TurnType::Merge : TurnType::Turn;
isMotorwayClass(road.eid, node_based_graph) ? TurnType::Merge : TurnType::Turn;
if (type == TurnType::Turn)
{
if (angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE)
road.turn.instruction = {type, DirectionModifier::Straight};
if (angularDeviation(road.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE)
road.instruction = {type, DirectionModifier::Straight};
else
{
road.turn.instruction = {type,
road.turn.angle > STRAIGHT_ANGLE
? DirectionModifier::SlightLeft
road.instruction = {type,
road.angle > STRAIGHT_ANGLE ? DirectionModifier::SlightLeft
: DirectionModifier::SlightRight};
}
}
else
{
road.turn.instruction = {type,
road.turn.angle < STRAIGHT_ANGLE
? DirectionModifier::SlightLeft
road.instruction = {type,
road.angle < STRAIGHT_ANGLE ? DirectionModifier::SlightLeft
: DirectionModifier::SlightRight};
}
}

View File

@ -29,13 +29,11 @@ bool LengthLimitedCoordinateAccumulator::terminate() { return accumulated_length
// update the accumulator
void LengthLimitedCoordinateAccumulator::update(const NodeID from_node,
const EdgeID via_edge,
const NodeID to_node)
const NodeID /*to_node*/)
{
const util::NodeBasedEdgeData &edge_data = node_based_graph.GetEdgeData(via_edge);
const auto current_coordinates = coordinate_extractor.GetForwardCoordinatesAlongRoad(
from_node, via_edge);
const auto current_coordinates =
coordinate_extractor.GetForwardCoordinatesAlongRoad(from_node, via_edge);
const auto length = util::coordinate_calculation::getLength(
coordinates, util::coordinate_calculation::haversineDistance);
@ -77,10 +75,10 @@ operator()(const NodeID /*nid*/,
result_score += 360.;
// 180 for undesired name-ids
if (desired_name_id != node_based_graph.GetEdgeData(road.turn.eid).name_id)
if (desired_name_id != node_based_graph.GetEdgeData(road.eid).name_id)
result_score += 180;
return result_score + angularDeviation(road.turn.angle, STRAIGHT_ANGLE);
return result_score + angularDeviation(road.angle, STRAIGHT_ANGLE);
};
return score(lhs) < score(rhs);
@ -92,7 +90,7 @@ operator()(const NodeID /*nid*/,
if (min_element == intersection.end() || (requires_entry && !min_element->entry_allowed))
return {};
else
return min_element->turn.eid;
return (*min_element).eid;
}
} // namespace guidance

View File

@ -77,7 +77,7 @@ detail::RoundaboutFlags RoundaboutHandler::getRoundaboutFlags(
++cnt, idx += step)
{
const auto &road = intersection[idx];
const auto &edge_data = node_based_graph.GetEdgeData(road.turn.eid);
const auto &edge_data = node_based_graph.GetEdgeData(road.eid);
// only check actual outgoing edges
if (edge_data.reversed || !road.entry_allowed)
continue;
@ -93,7 +93,7 @@ detail::RoundaboutFlags RoundaboutHandler::getRoundaboutFlags(
// the roundabout.
// The sorting of the angles represents a problem for left-sided driving, though.
// FIXME requires consideration of crossing the roundabout
else if (node_based_graph.GetTarget(road.turn.eid) != from_nid && !can_enter_roundabout)
else if (node_based_graph.GetTarget(road.eid) != from_nid && !can_enter_roundabout)
{
can_exit_roundabout_separately = true;
}
@ -116,7 +116,7 @@ void RoundaboutHandler::invalidateExitAgainstDirection(const NodeID from_nid,
++cnt, idx += step)
{
auto &road = intersection[idx];
const auto &edge_data = node_based_graph.GetEdgeData(road.turn.eid);
const auto &edge_data = node_based_graph.GetEdgeData(road.eid);
// only check actual outgoing edges
if (edge_data.reversed)
{
@ -131,7 +131,7 @@ void RoundaboutHandler::invalidateExitAgainstDirection(const NodeID from_nid,
// This workaround handles cases in which an exit precedes and entry. The resulting
// u-turn against the roundabout direction is invalidated.
// The sorting of the angles represents a problem for left-sided driving, though.
if (!edge_data.roundabout && node_based_graph.GetTarget(road.turn.eid) != from_nid &&
if (!edge_data.roundabout && node_based_graph.GetTarget(road.eid) != from_nid &&
past_roundabout_angle)
{
road.entry_allowed = false;
@ -379,8 +379,8 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
++cnt, idx += step)
{
auto &road = intersection[idx];
auto &turn = road.turn;
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
auto &turn = road;
const auto &out_data = node_based_graph.GetEdgeData(road.eid);
if (out_data.roundabout)
{
// TODO can forks happen in roundabouts? E.g. required lane changes
@ -419,7 +419,7 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
auto &road = intersection[idx];
if (!road.entry_allowed)
continue;
auto &turn = road.turn;
auto &turn = road;
const auto &out_data = node_based_graph.GetEdgeData(turn.eid);
if (out_data.roundabout)
{

View File

@ -53,8 +53,8 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
const auto findNextIntersectionForRoad =
[&](const NodeID at_node, const ConnectedRoad &road, NodeID &output_node) {
auto intersection = intersection_generator(at_node, road.turn.eid);
auto in_edge = road.turn.eid;
auto intersection = intersection_generator(at_node, road.eid);
auto in_edge = road.eid;
// skip over traffic lights
// to prevent ending up in an endless loop, we remember all visited nodes. This is
// necessary, since merging of roads can actually create enterable loops of degree two
@ -71,7 +71,7 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
intersection.clear();
return intersection;
}
in_edge = intersection[1].turn.eid;
in_edge = intersection[1].eid;
output_node = node_based_graph.GetTarget(in_edge);
intersection = intersection_generator(node, in_edge);
}
@ -87,8 +87,7 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
const auto index = findObviousTurn(source_edge_id, intersection);
if (index != 0)
return index;
else if (intersection.size() == 3 &&
intersection[1].turn.instruction.type == TurnType::Fork)
else if (intersection.size() == 3 && intersection[1].instruction.type == TurnType::Fork)
{
// Forks themselves do not contain a `obvious` turn index. If we look at a fork that has
// a one-sided sliproad, however, the non-sliproad can be considered `obvious`. Here we
@ -136,10 +135,10 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
const auto &next_road = intersection[obvious_turn_index];
const auto linkTest = [this, next_road](const ConnectedRoad &road) {
return !node_based_graph.GetEdgeData(road.turn.eid).roundabout && road.entry_allowed &&
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <= 2 * NARROW_TURN_ANGLE &&
!hasRoundaboutType(road.turn.instruction) &&
angularDeviation(next_road.turn.angle, road.turn.angle) >
return !node_based_graph.GetEdgeData(road.eid).roundabout && road.entry_allowed &&
angularDeviation(road.angle, STRAIGHT_ANGLE) <= 2 * NARROW_TURN_ANGLE &&
!hasRoundaboutType(road.instruction) &&
angularDeviation(next_road.angle, road.angle) >
std::numeric_limits<double>::epsilon();
};
@ -151,7 +150,7 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
const auto source_edge_data = node_based_graph.GetEdgeData(source_edge_id);
// check whether the continue road is valid
const auto check_valid = [this, source_edge_data](const ConnectedRoad &road) {
const auto road_edge_data = node_based_graph.GetEdgeData(road.turn.eid);
const auto road_edge_data = node_based_graph.GetEdgeData(road.eid);
// Test to see if the source edge and the one we're looking at are the same road
return road_edge_data.road_classification == source_edge_data.road_classification &&
road_edge_data.name_id != EMPTY_NAMEID &&
@ -165,13 +164,13 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
const auto coordinate_extractor = intersection_generator.GetCoordinateExtractor();
const auto next_road_length = util::coordinate_calculation::getLength(
coordinate_extractor.GetForwardCoordinatesAlongRoad(
node_based_graph.GetTarget(source_edge_id), next_road.turn.eid),
node_based_graph.GetTarget(source_edge_id), next_road.eid),
&util::coordinate_calculation::haversineDistance);
if (next_road_length > MAX_SLIPROAD_THRESHOLD)
{
return intersection;
}
auto next_intersection_node = node_based_graph.GetTarget(next_road.turn.eid);
auto next_intersection_node = node_based_graph.GetTarget(next_road.eid);
const auto next_road_next_intersection =
findNextIntersectionForRoad(intersection_node_id, next_road, next_intersection_node);
@ -187,7 +186,7 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
for (const auto &road : next_road_next_intersection)
{
const auto &target_data = node_based_graph.GetEdgeData(road.turn.eid);
const auto &target_data = node_based_graph.GetEdgeData(road.eid);
target_road_names.insert(target_data.name_id);
}
@ -195,20 +194,20 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
{
if (linkTest(road))
{
EdgeID candidate_in = road.turn.eid;
EdgeID candidate_in = road.eid;
const auto target_intersection = [&](NodeID node) {
auto intersection = intersection_generator(node, candidate_in);
// skip over traffic lights
if (intersection.size() == 2)
{
node = node_based_graph.GetTarget(candidate_in);
candidate_in = intersection[1].turn.eid;
candidate_in = intersection[1].eid;
intersection = intersection_generator(node, candidate_in);
}
return intersection;
}(intersection_node_id);
const auto link_data = node_based_graph.GetEdgeData(road.turn.eid);
const auto link_data = node_based_graph.GetEdgeData(road.eid);
// Check if the road continues here
const bool is_through_street =
!target_intersection.empty() &&
@ -216,7 +215,7 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
std::find_if(target_intersection.begin() + 1,
target_intersection.end(),
[this, &link_data](const ConnectedRoad &road) {
return node_based_graph.GetEdgeData(road.turn.eid).name_id ==
return node_based_graph.GetEdgeData(road.eid).name_id ==
link_data.name_id;
});
@ -226,26 +225,24 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
for (const auto &candidate_road : target_intersection)
{
const auto &candidate_data = node_based_graph.GetEdgeData(candidate_road.turn.eid);
const auto &candidate_data = node_based_graph.GetEdgeData(candidate_road.eid);
if (target_road_names.count(candidate_data.name_id) > 0)
{
if (node_based_graph.GetTarget(candidate_road.turn.eid) ==
next_intersection_node)
if (node_based_graph.GetTarget(candidate_road.eid) == next_intersection_node)
{
road.turn.instruction.type = TurnType::Sliproad;
road.instruction.type = TurnType::Sliproad;
break;
}
else
{
const auto skip_traffic_light_intersection = intersection_generator(
node_based_graph.GetTarget(candidate_in), candidate_road.turn.eid);
node_based_graph.GetTarget(candidate_in), candidate_road.eid);
if (skip_traffic_light_intersection.size() == 2 &&
node_based_graph.GetTarget(
skip_traffic_light_intersection[1].turn.eid) ==
node_based_graph.GetTarget(skip_traffic_light_intersection[1].eid) ==
next_intersection_node)
{
road.turn.instruction.type = TurnType::Sliproad;
road.instruction.type = TurnType::Sliproad;
break;
}
}
@ -254,27 +251,27 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
}
}
if (next_road.turn.instruction.type == TurnType::Fork)
if (next_road.instruction.type == TurnType::Fork)
{
const auto &next_data = node_based_graph.GetEdgeData(next_road.turn.eid);
const auto &next_data = node_based_graph.GetEdgeData(next_road.eid);
if (next_data.name_id == source_edge_data.name_id)
{
if (angularDeviation(next_road.turn.angle, STRAIGHT_ANGLE) < 5)
intersection[obvious_turn_index].turn.instruction.type = TurnType::Suppressed;
if (angularDeviation(next_road.angle, STRAIGHT_ANGLE) < 5)
intersection[obvious_turn_index].instruction.type = TurnType::Suppressed;
else
intersection[obvious_turn_index].turn.instruction.type = TurnType::Continue;
intersection[obvious_turn_index].turn.instruction.direction_modifier =
getTurnDirection(intersection[obvious_turn_index].turn.angle);
intersection[obvious_turn_index].instruction.type = TurnType::Continue;
intersection[obvious_turn_index].instruction.direction_modifier =
getTurnDirection(intersection[obvious_turn_index].angle);
}
else if (next_data.name_id != EMPTY_NAMEID)
{
intersection[obvious_turn_index].turn.instruction.type = TurnType::NewName;
intersection[obvious_turn_index].turn.instruction.direction_modifier =
getTurnDirection(intersection[obvious_turn_index].turn.angle);
intersection[obvious_turn_index].instruction.type = TurnType::NewName;
intersection[obvious_turn_index].instruction.direction_modifier =
getTurnDirection(intersection[obvious_turn_index].angle);
}
else
{
intersection[obvious_turn_index].turn.instruction.type = TurnType::Suppressed;
intersection[obvious_turn_index].instruction.type = TurnType::Suppressed;
}
}

View File

@ -101,8 +101,8 @@ Intersection TurnAnalysis::assignTurnTypes(const NodeID from_nid,
if (node_based_graph.GetEdgeData(via_eid).road_classification.IsMotorwayClass())
{
std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) {
if (road.turn.instruction.type == TurnType::OnRamp)
road.turn.instruction.type = TurnType::OffRamp;
if (road.instruction.type == TurnType::OnRamp)
road.instruction.type = TurnType::OffRamp;
});
}
return intersection;
@ -114,7 +114,7 @@ TurnAnalysis::transformIntersectionIntoTurns(const Intersection &intersection) c
std::vector<TurnOperation> turns;
for (auto road : intersection)
if (road.entry_allowed)
turns.emplace_back(road.turn);
turns.emplace_back(road);
return turns;
}
@ -133,12 +133,12 @@ TurnAnalysis::setTurnTypes(const NodeID from_nid, const EdgeID, Intersection int
if (!road.entry_allowed)
continue;
const EdgeID onto_edge = road.turn.eid;
const EdgeID onto_edge = road.eid;
const NodeID to_nid = node_based_graph.GetTarget(onto_edge);
road.turn.instruction = {TurnType::Turn,
road.instruction = {TurnType::Turn,
(from_nid == to_nid) ? DirectionModifier::UTurn
: getTurnDirection(road.turn.angle)};
: getTurnDirection(road.angle)};
}
return intersection;
}

View File

@ -35,7 +35,7 @@ classifyIntersection(Intersection intersection)
std::sort(intersection.begin(),
intersection.end(),
[](const ConnectedRoad &left, const ConnectedRoad &right) {
return left.turn.bearing < right.turn.bearing;
return left.bearing < right.bearing;
});
util::guidance::EntryClass entry_class;
@ -46,11 +46,11 @@ classifyIntersection(Intersection intersection)
return true;
DiscreteBearing last_discrete_bearing = util::guidance::BearingClass::getDiscreteBearing(
std::round(intersection.back().turn.bearing));
std::round(intersection.back().bearing));
for (const auto road : intersection)
{
const DiscreteBearing discrete_bearing =
util::guidance::BearingClass::getDiscreteBearing(std::round(road.turn.bearing));
util::guidance::BearingClass::getDiscreteBearing(std::round(road.bearing));
if (discrete_bearing == last_discrete_bearing)
return false;
last_discrete_bearing = discrete_bearing;
@ -62,8 +62,8 @@ classifyIntersection(Intersection intersection)
std::size_t number = 0;
if (canBeDiscretized)
{
if (util::guidance::BearingClass::getDiscreteBearing(intersection.back().turn.bearing) <
util::guidance::BearingClass::getDiscreteBearing(intersection.front().turn.bearing))
if (util::guidance::BearingClass::getDiscreteBearing(intersection.back().bearing) <
util::guidance::BearingClass::getDiscreteBearing(intersection.front().bearing))
{
intersection.insert(intersection.begin(), intersection.back());
intersection.pop_back();
@ -73,7 +73,7 @@ classifyIntersection(Intersection intersection)
if (road.entry_allowed)
entry_class.activate(number);
auto discrete_bearing_class =
util::guidance::BearingClass::getDiscreteBearing(std::round(road.turn.bearing));
util::guidance::BearingClass::getDiscreteBearing(std::round(road.bearing));
bearing_class.add(std::round(discrete_bearing_class *
util::guidance::BearingClass::discrete_step_size));
++number;
@ -85,7 +85,7 @@ classifyIntersection(Intersection intersection)
{
if (road.entry_allowed)
entry_class.activate(number);
bearing_class.add(std::round(road.turn.bearing));
bearing_class.add(std::round(road.bearing));
++number;
}
}

View File

@ -48,28 +48,28 @@ bool findPreviousIntersection(const NodeID node_v,
// Node -> Via_Edge -> Intersection[0 == UTURN] -> reverse_of(via_edge) -> Intersection at node
// (looking at the reverse direction).
const auto node_w = node_based_graph.GetTarget(via_edge);
const auto u_turn_at_node_w = intersection[0].turn.eid;
const auto u_turn_at_node_w = intersection[0].eid;
const auto node_v_reverse_intersection =
turn_analysis.getIntersection(node_w, u_turn_at_node_w);
// Continue along the straightmost turn. If there is no straight turn, we cannot find a valid
// previous intersection.
const auto straightmost_at_v_in_reverse =
findClosestTurn(node_v_reverse_intersection, STRAIGHT_ANGLE);
node_v_reverse_intersection.findClosestTurn(STRAIGHT_ANGLE);
// TODO evaluate if narrow turn is the right criterion here... Might be that other angles are
// valid
if (angularDeviation(straightmost_at_v_in_reverse->turn.angle, STRAIGHT_ANGLE) > GROUP_ANGLE)
if (angularDeviation(straightmost_at_v_in_reverse->angle, STRAIGHT_ANGLE) > GROUP_ANGLE)
return false;
const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->turn.eid);
const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->eid);
const auto node_u_reverse_intersection =
turn_analysis.getIntersection(node_v, straightmost_at_v_in_reverse->turn.eid);
turn_analysis.getIntersection(node_v, straightmost_at_v_in_reverse->eid);
// now check that the u-turn at the given intersection connects to via-edge
// The u-turn at the now found intersection should, hopefully, represent the previous edge.
result_node = node_u;
result_via_edge = node_u_reverse_intersection[0].turn.eid;
result_via_edge = node_u_reverse_intersection[0].eid;
// if the edge is not traversable, we obviously don't have a previous intersection or couldn't
// find it.
@ -85,7 +85,7 @@ bool findPreviousIntersection(const NodeID node_v,
result_intersection.end() !=
std::find_if(result_intersection.begin(),
result_intersection.end(),
[via_edge](const ConnectedRoad &road) { return road.turn.eid == via_edge; });
[via_edge](const ConnectedRoad &road) { return road.eid == via_edge; });
if (!check_via_edge)
{

View File

@ -47,7 +47,7 @@ operator()(const NodeID, const EdgeID via_edge, Intersection intersection) const
if (intersection[0].entry_allowed)
{
intersection[0].turn.instruction = {findBasicTurnType(via_edge, intersection[0]),
intersection[0].instruction = {findBasicTurnType(via_edge, intersection[0]),
DirectionModifier::UTurn};
}
@ -62,14 +62,14 @@ operator()(const NodeID, const EdgeID via_edge, Intersection intersection) const
Intersection TurnHandler::handleOneWayTurn(Intersection intersection) const
{
BOOST_ASSERT(intersection[0].turn.angle < 0.001);
BOOST_ASSERT(intersection[0].angle < 0.001);
return intersection;
}
Intersection TurnHandler::handleTwoWayTurn(const EdgeID via_edge, Intersection intersection) const
{
BOOST_ASSERT(intersection[0].turn.angle < 0.001);
intersection[1].turn.instruction =
BOOST_ASSERT(intersection[0].angle < 0.001);
intersection[1].instruction =
getInstructionForObvious(intersection.size(), via_edge, false, intersection[1]);
return intersection;
@ -81,8 +81,8 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,
{
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
const auto &first_data = node_based_graph.GetEdgeData(road.turn.eid);
const auto &second_data = node_based_graph.GetEdgeData(other.turn.eid);
const auto &first_data = node_based_graph.GetEdgeData(road.eid);
const auto &second_data = node_based_graph.GetEdgeData(other.eid);
const auto &first_classification = first_data.road_classification;
const auto &second_classification = second_data.road_classification;
const bool is_ramp = first_classification.IsRampClass();
@ -107,19 +107,18 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,
return false;
const bool turn_is_perfectly_straight =
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < std::numeric_limits<double>::epsilon();
angularDeviation(road.angle, STRAIGHT_ANGLE) < std::numeric_limits<double>::epsilon();
if (turn_is_perfectly_straight && in_data.name_id != EMPTY_NAMEID &&
in_data.name_id == node_based_graph.GetEdgeData(road.turn.eid).name_id)
in_data.name_id == node_based_graph.GetEdgeData(road.eid).name_id)
return true;
const bool is_much_narrower_than_other =
angularDeviation(other.turn.angle, STRAIGHT_ANGLE) /
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) >
angularDeviation(other.angle, STRAIGHT_ANGLE) /
angularDeviation(road.angle, STRAIGHT_ANGLE) >
INCREASES_BY_FOURTY_PERCENT &&
angularDeviation(angularDeviation(other.turn.angle, STRAIGHT_ANGLE),
angularDeviation(road.turn.angle, STRAIGHT_ANGLE)) >
FUZZY_ANGLE_DIFFERENCE;
angularDeviation(angularDeviation(other.angle, STRAIGHT_ANGLE),
angularDeviation(road.angle, STRAIGHT_ANGLE)) > FUZZY_ANGLE_DIFFERENCE;
return is_much_narrower_than_other;
}
@ -127,7 +126,7 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,
Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection intersection) const
{
const auto obvious_index = findObviousTurn(via_edge, intersection);
BOOST_ASSERT(intersection[0].turn.angle < 0.001);
BOOST_ASSERT(intersection[0].angle < 0.001);
/* Two nearly straight turns -> FORK
OOOOOOO
/
@ -151,26 +150,26 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
if (intersection[1].entry_allowed)
{
if (TurnType::OnRamp != findBasicTurnType(via_edge, intersection[1]))
intersection[1].turn.instruction = {TurnType::EndOfRoad, DirectionModifier::Right};
intersection[1].instruction = {TurnType::EndOfRoad, DirectionModifier::Right};
else
intersection[1].turn.instruction = {TurnType::OnRamp, DirectionModifier::Right};
intersection[1].instruction = {TurnType::OnRamp, DirectionModifier::Right};
}
if (intersection[2].entry_allowed)
{
if (TurnType::OnRamp != findBasicTurnType(via_edge, intersection[2]))
intersection[2].turn.instruction = {TurnType::EndOfRoad, DirectionModifier::Left};
intersection[2].instruction = {TurnType::EndOfRoad, DirectionModifier::Left};
else
intersection[2].turn.instruction = {TurnType::OnRamp, DirectionModifier::Left};
intersection[2].instruction = {TurnType::OnRamp, DirectionModifier::Left};
}
}
else if (obvious_index != 0) // has an obvious continuing road/obvious turn
{
const auto direction_at_one = getTurnDirection(intersection[1].turn.angle);
const auto direction_at_two = getTurnDirection(intersection[2].turn.angle);
const auto direction_at_one = getTurnDirection(intersection[1].angle);
const auto direction_at_two = getTurnDirection(intersection[2].angle);
if (obvious_index == 1)
{
intersection[1].turn.instruction = getInstructionForObvious(
intersection[1].instruction = getInstructionForObvious(
3, via_edge, isThroughStreet(1, intersection), intersection[1]);
const auto second_direction = (direction_at_one == direction_at_two &&
@ -178,13 +177,13 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
? DirectionModifier::SlightLeft
: direction_at_two;
intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]),
intersection[2].instruction = {findBasicTurnType(via_edge, intersection[2]),
second_direction};
}
else
{
BOOST_ASSERT(obvious_index == 2);
intersection[2].turn.instruction = getInstructionForObvious(
intersection[2].instruction = getInstructionForObvious(
3, via_edge, isThroughStreet(2, intersection), intersection[2]);
const auto first_direction = (direction_at_one == direction_at_two &&
@ -192,16 +191,16 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
? DirectionModifier::SlightRight
: direction_at_one;
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
intersection[1].instruction = {findBasicTurnType(via_edge, intersection[1]),
first_direction};
}
}
else // basic turn assignment
{
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
getTurnDirection(intersection[1].turn.angle)};
intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]),
getTurnDirection(intersection[2].turn.angle)};
intersection[1].instruction = {findBasicTurnType(via_edge, intersection[1]),
getTurnDirection(intersection[1].angle)};
intersection[2].instruction = {findBasicTurnType(via_edge, intersection[2]),
getTurnDirection(intersection[2].angle)};
}
return intersection;
}
@ -214,7 +213,7 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection
double straightmost_deviation = 180;
for (std::size_t i = 0; i < intersection.size(); ++i)
{
const double deviation = angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE);
const double deviation = angularDeviation(intersection[i].angle, STRAIGHT_ANGLE);
if (deviation < straightmost_deviation)
{
straightmost_deviation = deviation;
@ -225,7 +224,7 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection
// check whether the obvious choice is actually a through street
if (obvious_index != 0)
{
intersection[obvious_index].turn.instruction =
intersection[obvious_index].instruction =
getInstructionForObvious(intersection.size(),
via_edge,
isThroughStreet(obvious_index, intersection),
@ -242,23 +241,23 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection
auto &left = intersection[fork_range.second];
auto &right = intersection[fork_range.first];
const auto left_classification =
node_based_graph.GetEdgeData(left.turn.eid).road_classification;
node_based_graph.GetEdgeData(left.eid).road_classification;
const auto right_classification =
node_based_graph.GetEdgeData(right.turn.eid).road_classification;
node_based_graph.GetEdgeData(right.eid).road_classification;
if (canBeSeenAsFork(left_classification, right_classification))
assignFork(via_edge, left, right);
else if (left_classification.GetPriority() > right_classification.GetPriority())
{
right.turn.instruction =
right.instruction =
getInstructionForObvious(intersection.size(), via_edge, false, right);
left.turn.instruction = {findBasicTurnType(via_edge, left),
left.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
}
else
{
left.turn.instruction =
left.instruction =
getInstructionForObvious(intersection.size(), via_edge, false, left);
right.turn.instruction = {findBasicTurnType(via_edge, right),
right.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
}
@ -281,13 +280,13 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection
intersection = assignRightTurns(via_edge, std::move(intersection), straightmost_turn);
}
// no straight turn
else if (intersection[straightmost_turn].turn.angle > 180)
else if (intersection[straightmost_turn].angle > 180)
{
// at most three turns on either side
intersection = assignLeftTurns(via_edge, std::move(intersection), straightmost_turn);
intersection = assignRightTurns(via_edge, std::move(intersection), straightmost_turn);
}
else if (intersection[straightmost_turn].turn.angle < 180)
else if (intersection[straightmost_turn].angle < 180)
{
intersection = assignLeftTurns(via_edge, std::move(intersection), straightmost_turn + 1);
intersection = assignRightTurns(via_edge, std::move(intersection), straightmost_turn + 1);
@ -312,7 +311,7 @@ Intersection TurnHandler::assignLeftTurns(const EdgeID via_edge,
BOOST_ASSERT(!intersection.empty());
for (auto &road : intersection)
road = mirror(std::move(road));
road.mirror();
std::reverse(intersection.begin() + 1, intersection.end());
};
@ -349,8 +348,8 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
// Handle Turns 1-3
else if (up_to == 3)
{
const auto first_direction = getTurnDirection(intersection[1].turn.angle);
const auto second_direction = getTurnDirection(intersection[2].turn.angle);
const auto first_direction = getTurnDirection(intersection[1].angle);
const auto second_direction = getTurnDirection(intersection[2].angle);
if (first_direction == second_direction)
{
// conflict
@ -364,9 +363,9 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
// Handle Turns 1-4
else if (up_to == 4)
{
const auto first_direction = getTurnDirection(intersection[1].turn.angle);
const auto second_direction = getTurnDirection(intersection[2].turn.angle);
const auto third_direction = getTurnDirection(intersection[3].turn.angle);
const auto first_direction = getTurnDirection(intersection[1].angle);
const auto second_direction = getTurnDirection(intersection[2].angle);
const auto third_direction = getTurnDirection(intersection[3].angle);
if (first_direction != second_direction && second_direction != third_direction)
{
// due to the circular order, the turn directions are unique
@ -395,28 +394,26 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
// triggered 2>= ...)
//
// Conflicting Turns, but at least farther than what we call a narrow turn
else if (angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) >=
else if (angularDeviation(intersection[1].angle, intersection[2].angle) >=
NARROW_TURN_ANGLE &&
angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) >=
angularDeviation(intersection[2].angle, intersection[3].angle) >=
NARROW_TURN_ANGLE)
{
BOOST_ASSERT(intersection[1].entry_allowed && intersection[2].entry_allowed &&
intersection[3].entry_allowed);
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
intersection[1].instruction = {findBasicTurnType(via_edge, intersection[1]),
DirectionModifier::SharpRight};
intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]),
intersection[2].instruction = {findBasicTurnType(via_edge, intersection[2]),
DirectionModifier::Right};
intersection[3].turn.instruction = {findBasicTurnType(via_edge, intersection[3]),
intersection[3].instruction = {findBasicTurnType(via_edge, intersection[3]),
DirectionModifier::SlightRight};
}
else if (((first_direction == second_direction && second_direction == third_direction) ||
(first_direction == second_direction &&
angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) <
GROUP_ANGLE) ||
angularDeviation(intersection[2].angle, intersection[3].angle) < GROUP_ANGLE) ||
(second_direction == third_direction &&
angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) <
GROUP_ANGLE)))
angularDeviation(intersection[1].angle, intersection[2].angle) < GROUP_ANGLE)))
{
BOOST_ASSERT(intersection[1].entry_allowed && intersection[2].entry_allowed &&
intersection[3].entry_allowed);
@ -424,25 +421,22 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
assignTrivialTurns(via_edge, intersection, 1, up_to);
}
else if (((first_direction == second_direction &&
angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) >=
GROUP_ANGLE) ||
angularDeviation(intersection[2].angle, intersection[3].angle) >= GROUP_ANGLE) ||
(second_direction == third_direction &&
angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) >=
GROUP_ANGLE)))
angularDeviation(intersection[1].angle, intersection[2].angle) >= GROUP_ANGLE)))
{
BOOST_ASSERT(intersection[1].entry_allowed && intersection[2].entry_allowed &&
intersection[3].entry_allowed);
if (angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) >=
GROUP_ANGLE)
if (angularDeviation(intersection[2].angle, intersection[3].angle) >= GROUP_ANGLE)
{
handleDistinctConflict(via_edge, intersection[2], intersection[1]);
intersection[3].turn.instruction = {findBasicTurnType(via_edge, intersection[3]),
intersection[3].instruction = {findBasicTurnType(via_edge, intersection[3]),
third_direction};
}
else
{
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
intersection[1].instruction = {findBasicTurnType(via_edge, intersection[1]),
first_direction};
handleDistinctConflict(via_edge, intersection[3], intersection[2]);
}
@ -469,7 +463,7 @@ std::pair<std::size_t, std::size_t> TurnHandler::findFork(const EdgeID via_edge,
// TODO handle road classes
for (std::size_t i = 1; i < intersection.size(); ++i)
{
const double deviation = angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE);
const double deviation = angularDeviation(intersection[i].angle, STRAIGHT_ANGLE);
if (intersection[i].entry_allowed && deviation < best_deviation)
{
best_deviation = deviation;
@ -479,20 +473,19 @@ std::pair<std::size_t, std::size_t> TurnHandler::findFork(const EdgeID via_edge,
if (best_deviation <= NARROW_TURN_ANGLE)
{
std::size_t left = best, right = best;
while (left + 1 < intersection.size() &&
(angularDeviation(intersection[left + 1].turn.angle, STRAIGHT_ANGLE) <=
NARROW_TURN_ANGLE ||
(angularDeviation(intersection[left].turn.angle,
intersection[left + 1].turn.angle) <= NARROW_TURN_ANGLE &&
angularDeviation(intersection[left].turn.angle, STRAIGHT_ANGLE) <= GROUP_ANGLE)))
while (
left + 1 < intersection.size() &&
(angularDeviation(intersection[left + 1].angle, STRAIGHT_ANGLE) <= NARROW_TURN_ANGLE ||
(angularDeviation(intersection[left].angle, intersection[left + 1].angle) <=
NARROW_TURN_ANGLE &&
angularDeviation(intersection[left].angle, STRAIGHT_ANGLE) <= GROUP_ANGLE)))
++left;
while (
right > 1 &&
(angularDeviation(intersection[right - 1].turn.angle, STRAIGHT_ANGLE) <=
NARROW_TURN_ANGLE ||
(angularDeviation(intersection[right].turn.angle, intersection[right - 1].turn.angle) <
(angularDeviation(intersection[right - 1].angle, STRAIGHT_ANGLE) <= NARROW_TURN_ANGLE ||
(angularDeviation(intersection[right].angle, intersection[right - 1].angle) <
NARROW_TURN_ANGLE &&
angularDeviation(intersection[right - 1].turn.angle, STRAIGHT_ANGLE) <= GROUP_ANGLE)))
angularDeviation(intersection[right - 1].angle, STRAIGHT_ANGLE) <= GROUP_ANGLE)))
--right;
if (left == right)
@ -500,12 +493,11 @@ std::pair<std::size_t, std::size_t> TurnHandler::findFork(const EdgeID via_edge,
const bool valid_indices = 0 < right && right < left;
const bool separated_at_left_side =
angularDeviation(intersection[left].turn.angle,
intersection[(left + 1) % intersection.size()].turn.angle) >=
GROUP_ANGLE;
angularDeviation(intersection[left].angle,
intersection[(left + 1) % intersection.size()].angle) >= GROUP_ANGLE;
const bool separated_at_right_side =
right > 0 &&
angularDeviation(intersection[right].turn.angle, intersection[right - 1].turn.angle) >=
angularDeviation(intersection[right].angle, intersection[right - 1].angle) >=
GROUP_ANGLE;
const bool not_more_than_three = (left - right) <= 2;
@ -527,28 +519,27 @@ std::pair<std::size_t, std::size_t> TurnHandler::findFork(const EdgeID via_edge,
// A fork can only happen between edges of similar types where none of the ones is obvious
const bool has_compatible_classes = [&]() {
const bool ramp_class = node_based_graph.GetEdgeData(intersection[right].turn.eid)
const bool ramp_class = node_based_graph.GetEdgeData(intersection[right].eid)
.road_classification.IsLinkClass();
for (std::size_t index = right + 1; index <= left; ++index)
if (ramp_class !=
node_based_graph.GetEdgeData(intersection[index].turn.eid)
node_based_graph.GetEdgeData(intersection[index].eid)
.road_classification.IsLinkClass())
return false;
const auto in_classification =
node_based_graph.GetEdgeData(intersection[0].turn.eid).road_classification;
node_based_graph.GetEdgeData(intersection[0].eid).road_classification;
for (std::size_t base_index = right; base_index <= left; ++base_index)
{
const auto base_classification =
node_based_graph.GetEdgeData(intersection[base_index].turn.eid)
.road_classification;
node_based_graph.GetEdgeData(intersection[base_index].eid).road_classification;
for (std::size_t compare_index = right; compare_index <= left; ++compare_index)
{
if (base_index == compare_index)
continue;
const auto compare_classification =
node_based_graph.GetEdgeData(intersection[compare_index].turn.eid)
node_based_graph.GetEdgeData(intersection[compare_index].eid)
.road_classification;
if (obviousByRoadClass(
in_classification, base_classification, compare_classification))
@ -589,25 +580,22 @@ void TurnHandler::handleDistinctConflict(const EdgeID via_edge,
{
// single turn of both is valid (don't change the valid one)
// or multiple identical angles -> bad OSM intersection
if ((!left.entry_allowed || !right.entry_allowed) || (left.turn.angle == right.turn.angle))
if ((!left.entry_allowed || !right.entry_allowed) || (left.angle == right.angle))
{
if (left.entry_allowed)
left.turn.instruction = {findBasicTurnType(via_edge, left),
getTurnDirection(left.turn.angle)};
left.instruction = {findBasicTurnType(via_edge, left), getTurnDirection(left.angle)};
if (right.entry_allowed)
right.turn.instruction = {findBasicTurnType(via_edge, right),
getTurnDirection(right.turn.angle)};
right.instruction = {findBasicTurnType(via_edge, right), getTurnDirection(right.angle)};
return;
}
if (getTurnDirection(left.turn.angle) == DirectionModifier::Straight ||
getTurnDirection(left.turn.angle) == DirectionModifier::SlightLeft ||
getTurnDirection(right.turn.angle) == DirectionModifier::SlightRight)
if (getTurnDirection(left.angle) == DirectionModifier::Straight ||
getTurnDirection(left.angle) == DirectionModifier::SlightLeft ||
getTurnDirection(right.angle) == DirectionModifier::SlightRight)
{
const auto left_classification =
node_based_graph.GetEdgeData(left.turn.eid).road_classification;
const auto left_classification = node_based_graph.GetEdgeData(left.eid).road_classification;
const auto right_classification =
node_based_graph.GetEdgeData(right.turn.eid).road_classification;
node_based_graph.GetEdgeData(right.eid).road_classification;
if (canBeSeenAsFork(left_classification, right_classification))
assignFork(via_edge, left, right);
else if (left_classification.GetPriority() > right_classification.GetPriority())
@ -616,9 +604,8 @@ void TurnHandler::handleDistinctConflict(const EdgeID via_edge,
// here we don't know about the intersection size. To be on the save side,
// we declare it
// as complex (at least size 4)
right.turn.instruction = getInstructionForObvious(4, via_edge, false, right);
left.turn.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
right.instruction = getInstructionForObvious(4, via_edge, false, right);
left.instruction = {findBasicTurnType(via_edge, left), DirectionModifier::SlightLeft};
}
else
{
@ -626,81 +613,81 @@ void TurnHandler::handleDistinctConflict(const EdgeID via_edge,
// here we don't know about the intersection size. To be on the save side,
// we declare it
// as complex (at least size 4)
left.turn.instruction = getInstructionForObvious(4, via_edge, false, left);
right.turn.instruction = {findBasicTurnType(via_edge, right),
left.instruction = getInstructionForObvious(4, via_edge, false, left);
right.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
}
const auto left_type = findBasicTurnType(via_edge, left);
const auto right_type = findBasicTurnType(via_edge, right);
// Two Right Turns
if (angularDeviation(left.turn.angle, 90) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
if (angularDeviation(left.angle, 90) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
{
// Keep left perfect, shift right
left.turn.instruction = {left_type, DirectionModifier::Right};
right.turn.instruction = {right_type, DirectionModifier::SharpRight};
left.instruction = {left_type, DirectionModifier::Right};
right.instruction = {right_type, DirectionModifier::SharpRight};
return;
}
if (angularDeviation(right.turn.angle, 90) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
if (angularDeviation(right.angle, 90) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
{
// Keep Right perfect, shift left
left.turn.instruction = {left_type, DirectionModifier::SlightRight};
right.turn.instruction = {right_type, DirectionModifier::Right};
left.instruction = {left_type, DirectionModifier::SlightRight};
right.instruction = {right_type, DirectionModifier::Right};
return;
}
// Two Right Turns
if (angularDeviation(left.turn.angle, 270) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
if (angularDeviation(left.angle, 270) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
{
// Keep left perfect, shift right
left.turn.instruction = {left_type, DirectionModifier::Left};
right.turn.instruction = {right_type, DirectionModifier::SlightLeft};
left.instruction = {left_type, DirectionModifier::Left};
right.instruction = {right_type, DirectionModifier::SlightLeft};
return;
}
if (angularDeviation(right.turn.angle, 270) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
if (angularDeviation(right.angle, 270) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
{
// Keep Right perfect, shift left
left.turn.instruction = {left_type, DirectionModifier::SharpLeft};
right.turn.instruction = {right_type, DirectionModifier::Left};
left.instruction = {left_type, DirectionModifier::SharpLeft};
right.instruction = {right_type, DirectionModifier::Left};
return;
}
// Shift the lesser penalty
if (getTurnDirection(left.turn.angle) == DirectionModifier::SharpLeft)
if (getTurnDirection(left.angle) == DirectionModifier::SharpLeft)
{
left.turn.instruction = {left_type, DirectionModifier::SharpLeft};
right.turn.instruction = {right_type, DirectionModifier::Left};
left.instruction = {left_type, DirectionModifier::SharpLeft};
right.instruction = {right_type, DirectionModifier::Left};
return;
}
if (getTurnDirection(right.turn.angle) == DirectionModifier::SharpRight)
if (getTurnDirection(right.angle) == DirectionModifier::SharpRight)
{
left.turn.instruction = {left_type, DirectionModifier::Right};
right.turn.instruction = {right_type, DirectionModifier::SharpRight};
left.instruction = {left_type, DirectionModifier::Right};
right.instruction = {right_type, DirectionModifier::SharpRight};
return;
}
if (getTurnDirection(left.turn.angle) == DirectionModifier::Right)
if (getTurnDirection(left.angle) == DirectionModifier::Right)
{
if (angularDeviation(left.turn.angle, 85) >= angularDeviation(right.turn.angle, 85))
if (angularDeviation(left.angle, 85) >= angularDeviation(right.angle, 85))
{
left.turn.instruction = {left_type, DirectionModifier::Right};
right.turn.instruction = {right_type, DirectionModifier::SharpRight};
left.instruction = {left_type, DirectionModifier::Right};
right.instruction = {right_type, DirectionModifier::SharpRight};
}
else
{
left.turn.instruction = {left_type, DirectionModifier::SlightRight};
right.turn.instruction = {right_type, DirectionModifier::Right};
left.instruction = {left_type, DirectionModifier::SlightRight};
right.instruction = {right_type, DirectionModifier::Right};
}
}
else
{
if (angularDeviation(left.turn.angle, 265) >= angularDeviation(right.turn.angle, 265))
if (angularDeviation(left.angle, 265) >= angularDeviation(right.angle, 265))
{
left.turn.instruction = {left_type, DirectionModifier::SharpLeft};
right.turn.instruction = {right_type, DirectionModifier::Left};
left.instruction = {left_type, DirectionModifier::SharpLeft};
right.instruction = {right_type, DirectionModifier::Left};
}
else
{
left.turn.instruction = {left_type, DirectionModifier::Left};
right.turn.instruction = {right_type, DirectionModifier::SlightLeft};
left.instruction = {left_type, DirectionModifier::Left};
right.instruction = {right_type, DirectionModifier::SlightLeft};
}
}
}

View File

@ -113,8 +113,8 @@ LaneDataVector augmentMultiple(const std::size_t none_index,
if (intersection[intersection_index].entry_allowed)
{
// FIXME this probably can be only a subset of these turns here?
lane_data.push_back({tag_by_modifier[intersection[intersection_index]
.turn.instruction.direction_modifier],
lane_data.push_back(
{tag_by_modifier[intersection[intersection_index].instruction.direction_modifier],
lane_data[none_index].from,
lane_data[none_index].to,
false});
@ -162,7 +162,7 @@ LaneDataVector handleRenamingSituations(const std::size_t none_index,
if (!road.entry_allowed)
continue;
const auto modifier = road.turn.instruction.direction_modifier;
const auto modifier = road.instruction.direction_modifier;
has_right |= modifier == DirectionModifier::Right;
has_right |= modifier == DirectionModifier::SlightRight;
has_right |= modifier == DirectionModifier::SharpRight;

View File

@ -167,8 +167,8 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at,
(intersection.size() == 2 &&
((lane_description_id != INVALID_LANE_DESCRIPTIONID &&
lane_description_id ==
node_based_graph.GetEdgeData(intersection[1].turn.eid).lane_description_id) ||
angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE));
node_based_graph.GetEdgeData(intersection[1].eid).lane_description_id) ||
angularDeviation(intersection[1].angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE));
if (is_going_straight_and_turns_continue)
return TurnLaneScenario::NONE;
@ -201,9 +201,9 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at,
const auto &road = previous_intersection[road_index];
// in case of a sliproad that is connected to road of simlar angle, we handle the
// turn as a combined turn
if (road.turn.instruction.type == TurnType::Sliproad)
if (road.instruction.type == TurnType::Sliproad)
{
if (via_edge == road.turn.eid)
if (via_edge == road.eid)
return TurnLaneScenario::SLIPROAD;
const auto &closest_road = [&]() {
@ -217,16 +217,16 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at,
BOOST_ASSERT(road_index + 1 < previous_intersection.size());
return previous_intersection[road_index + 1];
}
else if (angularDeviation(road.turn.angle,
previous_intersection.at(road_index - 1).turn.angle) <
angularDeviation(road.turn.angle,
previous_intersection.at(road_index + 1).turn.angle))
else if (angularDeviation(road.angle,
previous_intersection.at(road_index - 1).angle) <
angularDeviation(road.angle,
previous_intersection.at(road_index + 1).angle))
return previous_intersection[road_index - 1];
else
return previous_intersection[road_index + 1];
}();
if (via_edge == closest_road.turn.eid)
if (via_edge == closest_road.eid)
return TurnLaneScenario::SLIPROAD;
}
}
@ -482,8 +482,8 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
all_simple &= (best_match->entry_allowed ||
// check for possible u-turn match on non-reversed edge
((match_index == 0 || match_index + 1 == intersection.size()) &&
!node_based_graph.GetEdgeData(best_match->turn.eid).reversed));
all_simple &= isValidMatch(data.tag, best_match->turn.instruction);
!node_based_graph.GetEdgeData(best_match->eid).reversed));
all_simple &= isValidMatch(data.tag, best_match->instruction);
}
// either all indices are matched, or we have a single none-value
@ -527,7 +527,7 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
// Try and maitch lanes to available turns. For Turns that are not directly matchable, check
// whether we can match them at the upcoming intersection.
const auto straightmost = findClosestTurn(intersection, STRAIGHT_ANGLE);
const auto straightmost = intersection.findClosestTurn(STRAIGHT_ANGLE);
BOOST_ASSERT(straightmost < intersection.cend());
@ -540,9 +540,9 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
// find out about the next intersection. To check for valid matches, we also need the turn
// types
auto next_intersection = turn_analysis.getIntersection(at, straightmost->turn.eid);
auto next_intersection = turn_analysis.getIntersection(at, straightmost->eid);
next_intersection =
turn_analysis.assignTurnTypes(at, straightmost->turn.eid, std::move(next_intersection));
turn_analysis.assignTurnTypes(at, straightmost->eid, std::move(next_intersection));
// check where we can match turn lanes
std::size_t straightmost_tag_index = turn_lane_data.size();
@ -554,7 +554,7 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
const auto best_match = findBestMatch(turn_lane_data[lane].tag, intersection);
if (best_match->entry_allowed &&
isValidMatch(turn_lane_data[lane].tag, best_match->turn.instruction))
isValidMatch(turn_lane_data[lane].tag, best_match->instruction))
{
matched_at_first[lane] = true;
@ -565,8 +565,7 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
const auto best_match_at_next_intersection =
findBestMatch(turn_lane_data[lane].tag, next_intersection);
if (best_match_at_next_intersection->entry_allowed &&
isValidMatch(turn_lane_data[lane].tag,
best_match_at_next_intersection->turn.instruction))
isValidMatch(turn_lane_data[lane].tag, best_match_at_next_intersection->instruction))
{
if (!matched_at_first[lane] || turn_lane_data[lane].tag == TurnLaneType::straight ||
getMatchingQuality(turn_lane_data[lane].tag, *best_match) >
@ -679,7 +678,7 @@ Intersection TurnLaneHandler::handleSliproadTurn(Intersection intersection,
std::find_if(previous_intersection.begin(),
previous_intersection.end(),
[](const ConnectedRoad &road) {
return road.turn.instruction.type == TurnType::Sliproad;
return road.instruction.type == TurnType::Sliproad;
}));
BOOST_ASSERT(sliproad_index <= previous_intersection.size());
@ -697,18 +696,18 @@ Intersection TurnLaneHandler::handleSliproadTurn(Intersection intersection,
BOOST_ASSERT(sliproad_index + 1 < previous_intersection.size());
return previous_intersection[sliproad_index + 1];
}
else if (angularDeviation(sliproad.turn.angle,
previous_intersection.at(sliproad_index - 1).turn.angle) <
angularDeviation(sliproad.turn.angle,
previous_intersection.at(sliproad_index + 1).turn.angle))
else if (angularDeviation(sliproad.angle,
previous_intersection.at(sliproad_index - 1).angle) <
angularDeviation(sliproad.angle,
previous_intersection.at(sliproad_index + 1).angle))
return previous_intersection[sliproad_index - 1];
else
return previous_intersection[sliproad_index + 1];
}();
const auto main_description_id =
node_based_graph.GetEdgeData(main_road.turn.eid).lane_description_id;
node_based_graph.GetEdgeData(main_road.eid).lane_description_id;
const auto sliproad_description_id =
node_based_graph.GetEdgeData(sliproad.turn.eid).lane_description_id;
node_based_graph.GetEdgeData(sliproad.eid).lane_description_id;
if (main_description_id == INVALID_LANE_DESCRIPTIONID ||
sliproad_description_id == INVALID_LANE_DESCRIPTIONID)
@ -716,7 +715,7 @@ Intersection TurnLaneHandler::handleSliproadTurn(Intersection intersection,
TurnLaneDescription combined_description;
// is the sliproad going off to the right?
if (main_road.turn.angle > sliproad.turn.angle)
if (main_road.angle > sliproad.angle)
{
combined_description.insert(
combined_description.end(),

View File

@ -109,7 +109,7 @@ double getMatchingQuality(const TurnLaneType::Mask tag, const ConnectedRoad &roa
BOOST_ASSERT(static_cast<std::size_t>(modifier) <
sizeof(idealized_turn_angles) / sizeof(*idealized_turn_angles));
const auto idealized_angle = idealized_turn_angles[modifier];
return angularDeviation(idealized_angle, road.turn.angle);
return angularDeviation(idealized_angle, road.angle);
}
// Every tag is somewhat idealized in form of the expected angle. A through lane should go straight
@ -123,9 +123,9 @@ typename Intersection::const_iterator findBestMatch(const TurnLaneType::Mask tag
intersection.end(),
[tag](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
// prefer valid matches
if (isValidMatch(tag, lhs.turn.instruction) !=
isValidMatch(tag, rhs.turn.instruction))
return isValidMatch(tag, lhs.turn.instruction);
if (isValidMatch(tag, lhs.instruction) !=
isValidMatch(tag, rhs.instruction))
return isValidMatch(tag, lhs.instruction);
// if the entry allowed flags don't match, we select the one with
// entry allowed set to true
@ -154,8 +154,8 @@ typename Intersection::const_iterator findBestMatchForReverse(const TurnLaneType
intersection.end(),
[tag](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
// prefer valid matches
if (isValidMatch(tag, lhs.turn.instruction) != isValidMatch(tag, rhs.turn.instruction))
return isValidMatch(tag, lhs.turn.instruction);
if (isValidMatch(tag, lhs.instruction) != isValidMatch(tag, rhs.instruction))
return isValidMatch(tag, lhs.instruction);
// if the entry allowed flags don't match, we select the one with
// entry allowed set to true
@ -182,7 +182,7 @@ bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &l
if (intersection[road_index].entry_allowed)
{
BOOST_ASSERT(lane_data[lane].from != INVALID_LANEID);
if (!isValidMatch(lane_data[lane].tag, intersection[road_index].turn.instruction))
if (!isValidMatch(lane_data[lane].tag, intersection[road_index].instruction))
return false;
if (findBestMatch(lane_data[lane].tag, intersection) !=
@ -216,7 +216,7 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
lane_data_id = it->second;
// set lane id instead after the switch:
road.turn.lane_data_id = lane_data_id;
road.lane_data_id = lane_data_id;
};
if (!lane_data.empty() && lane_data.front().tag == TurnLaneType::uturn)
@ -225,11 +225,10 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
if (intersection[0].entry_allowed)
{
std::size_t u_turn = 0;
if (node_based_graph.GetEdgeData(intersection[0].turn.eid).reversed)
if (node_based_graph.GetEdgeData(intersection[0].eid).reversed)
{
if (intersection.size() <= 1 || !intersection[1].entry_allowed ||
intersection[1].turn.instruction.direction_modifier !=
DirectionModifier::SharpRight)
intersection[1].instruction.direction_modifier != DirectionModifier::SharpRight)
{
// cannot match u-turn in a valid way
return intersection;
@ -238,8 +237,8 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
road_index = 2;
}
intersection[u_turn].entry_allowed = true;
intersection[u_turn].turn.instruction.type = TurnType::Turn;
intersection[u_turn].turn.instruction.direction_modifier = DirectionModifier::UTurn;
intersection[u_turn].instruction.type = TurnType::Turn;
intersection[u_turn].instruction.direction_modifier = DirectionModifier::UTurn;
matchRoad(intersection[u_turn], lane_data.back());
// continue with the first lane
@ -254,14 +253,13 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
if (intersection[road_index].entry_allowed)
{
BOOST_ASSERT(lane_data[lane].from != INVALID_LANEID);
BOOST_ASSERT(
isValidMatch(lane_data[lane].tag, intersection[road_index].turn.instruction));
BOOST_ASSERT(isValidMatch(lane_data[lane].tag, intersection[road_index].instruction));
BOOST_ASSERT(findBestMatch(lane_data[lane].tag, intersection) ==
intersection.begin() + road_index);
if (TurnType::Suppressed == intersection[road_index].turn.instruction.type &&
if (TurnType::Suppressed == intersection[road_index].instruction.type &&
!lane_data[lane].suppress_assignment)
intersection[road_index].turn.instruction.type = TurnType::UseLane;
intersection[road_index].instruction.type = TurnType::UseLane;
matchRoad(intersection[road_index], lane_data[lane]);
++lane;
@ -272,11 +270,10 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
if (lane + 1 == lane_data.size() && lane_data.back().tag == TurnLaneType::uturn)
{
std::size_t u_turn = 0;
if (node_based_graph.GetEdgeData(intersection[0].turn.eid).reversed)
if (node_based_graph.GetEdgeData(intersection[0].eid).reversed)
{
if (!intersection.back().entry_allowed ||
intersection.back().turn.instruction.direction_modifier !=
DirectionModifier::SharpLeft)
intersection.back().instruction.direction_modifier != DirectionModifier::SharpLeft)
{
// cannot match u-turn in a valid way
return intersection;
@ -284,8 +281,8 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
u_turn = intersection.size() - 1;
}
intersection[u_turn].entry_allowed = true;
intersection[u_turn].turn.instruction.type = TurnType::Turn;
intersection[u_turn].turn.instruction.direction_modifier = DirectionModifier::UTurn;
intersection[u_turn].instruction.type = TurnType::Turn;
intersection[u_turn].instruction.direction_modifier = DirectionModifier::UTurn;
matchRoad(intersection[u_turn], lane_data.back());
}

View File

@ -30,7 +30,8 @@ namespace osrm
namespace server
{
void RequestHandler::RegisterServiceHandler(std::unique_ptr<ServiceHandlerInterface> service_handler_)
void RequestHandler::RegisterServiceHandler(
std::unique_ptr<ServiceHandlerInterface> service_handler_)
{
service_handler = std::move(service_handler_);
}