-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor fork handling in guidance #3264
Conversation
5287c76
to
58537a1
Compare
// `ConnectedRoads` is a relative view of an intersection by an incoming edge. | ||
// `ConnectedRoads` are streets at an intersection ordered from from sharp right counter-clockwise to | ||
// sharp left where `connected_roads[0]` is _always_ a u-turn | ||
struct ConnectedRoads final : public std::vector<ConnectedRoad> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the change in the API here? This will break all users throughout osrm-backend.
Also semantically it it an intersection represented as ordered roads.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted
// _at_ `node_based_graph.GetTarget(via_edge)` | ||
// _from_ `NodeID` | ||
// _over_ `via_edge` | ||
// _from where_ there are other `connected_roads` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is _at_
and _from where_
all about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated comment to make it less confusing
// Checks whether a turn from `via_edge` onto `road` is a turn | ||
// - on a ramp | ||
// - a continue | ||
// - or a normal turn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this mean wrt. our turn instructions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved to unrelated todo
{ | ||
break; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can express this and above more clearly using a adjacent-ish stdlib algorithm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done. thanks!
|
||
const bool valid_indices = 0 < right && right < left; | ||
BOOST_ASSERT(0 < right); | ||
BOOST_ASSERT(right < left); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change from a check to an assert: does this always hold?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. (hopefully.) yes.
|
||
// there cannot be a fork of more than three streets | ||
std::size_t size_of_fork = left - right + 1; | ||
const bool not_more_than_three_old = (left - right) <= 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dead code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks!
Looking at your refactored findFork:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The actual change is completely hidden in the unrelated changes.
These should, at the least, be separated from each other and I feel we should really discuss this ConnectedRoads change, as I don't really agree with it.
@@ -27,7 +27,7 @@ struct IntersectionPrinter | |||
// renders the used coordinate locations for all entries/as well as the resulting | |||
// intersection-classification | |||
util::json::Array operator()(const NodeID intersection_node, | |||
const extractor::guidance::Intersection &intersection, | |||
const extractor::guidance::ConnectedRoads &intersection, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we split unrelated changes like these into a dedicated PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do.
|
||
std::vector<TurnOperation> | ||
transformIntersectionIntoTurns(const Intersection &intersection) const; | ||
transformIntersectionIntoTurns(const ConnectedRoads &intersection) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you rename it, than intersection
in the name here does not make any sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted
@@ -64,8 +65,8 @@ class TurnAnalysis | |||
const SliproadHandler sliproad_handler; | |||
|
|||
// Utility function, setting basic turn types. Prepares for normal turn handling. | |||
Intersection | |||
setTurnTypes(const NodeID from, const EdgeID via_edge, Intersection intersection) const; | |||
ConnectedRoads |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should add OSRM_ATTR_WARN_UNUSED
here.
Intersection MergeSegregatedRoads(const NodeID intersection_node, | ||
Intersection intersection) const; | ||
ConnectedRoads MergeSegregatedRoads(const NodeID intersection_node, | ||
ConnectedRoads intersection) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it's important to have it named ConnectedRoads
to you, then we should also change the name intersection
into connected_roads
to not loose sync between type and name. Right now (Intersection intersection
) connects the variable to its type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted
// | ||
// | | ||
// | | ||
// (connected_roads[i]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comments out of sync with name below (connected_roads vs intersection)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
corrected
@@ -25,7 +25,7 @@ namespace guidance | |||
{ | |||
|
|||
std::pair<util::guidance::EntryClass, util::guidance::BearingClass> | |||
classifyIntersection(Intersection intersection); | |||
classifyIntersection(ConnectedRoads intersection); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, if we name it roads, the connection between intersection
and connected roads
is not clear.
Sure, a vector<ConnectedRoad>
is a list of ConnectedRoads
, but so is std::set<ConnectedRoad>
or std::list<ConnectedRoad>
. I don't really like removing the additional information that is inherently given by having a specifically sorted list of Roads
. Especially with the added functionality.
It's a dedicated class, not simply a plain collection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted
Regarding The main reason for the change is that there is another As the discussed However, if you think we should rename it to something more similar to |
Capturing from chat: in short: yes, we should to stuff about [12:21] [12:22] [12:24] [12:25] also you have the sorting criterium which implies meaning. With the addition of In total: We are renaming the |
Being on the output part is actually the prime reason I would argue against remaining it. We always refer to this object in the docs as You could maybe use |
58537a1
to
6660a73
Compare
I did some work on this PR, things happened so far:
what these change not do:
With these thigns in mind, would you look at the code again before I continue work here? Thanks a lot, lot, lot! @daniel-j-h @MoKob |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some comments on the PR - also please see #3264 (comment)
// `angle` is given counter-clockwise: | ||
// 0 = uturn, 90 = right, 180 = straight, 270 = left | ||
// `bearing` is the direction in clockwise angle from true north after taking the turn: | ||
// 0 = heading north, 90 = east, 180 = south, 270 = west<<<<<<< HEAD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<<<< HEAD
// if no entry was found that forbids entry, the intersection entries in the range are all | ||
// valid. | ||
return true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you make this iterator based, the previous ~15 lines are
return all_of(first, last, mem_fn(&T::allowed));
@@ -45,6 +45,8 @@ std::size_t IntersectionHandler::countValid(const Intersection &intersection) co | |||
}); | |||
} | |||
|
|||
// Checks whether a turn from `via_edge` onto `road` is a turn, on a ramp, a continue, or a normal | |||
// turn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, does this comment say the only TurnTypes the function handles is Turn
, OnRamp
, Continue
?
@@ -45,9 +45,26 @@ class TurnHandler : public IntersectionHandler | |||
Intersection intersection) const override final; | |||
|
|||
private: | |||
struct Fork; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only forward declares Fork
making it an incomplete type in this header
@@ -68,8 +85,7 @@ class TurnHandler : public IntersectionHandler | |||
handleDistinctConflict(const EdgeID via_edge, ConnectedRoad &left, ConnectedRoad &right) const; | |||
|
|||
// Classification | |||
std::pair<std::size_t, std::size_t> findFork(const EdgeID via_edge, | |||
const Intersection &intersection) const; | |||
Fork findFork(const EdgeID via_edge, const Intersection &intersection) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but here you're trying to use an incomplete type by-value as return type.
} | ||
} | ||
return true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you express these two nested raw for loops via stdlib algorithms?
The outer one looks like a for each, the inner one like a any-of.
// Checks whether a three-way-intersection coming from `via_edge` is a fork | ||
// with `intersection` as described as in #IntersectionExplanation@intersection_handler.hpp | ||
TurnHandler::Fork TurnHandler::findFork(const EdgeID via_edge, | ||
const Intersection &intersection) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if intersection
is empty (the UTurn road only)? Is size = 3 a pre-condition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not a pre-condition but if intersection.size()<3
it will now return boost::none
// they cannot be fork candidates | ||
if ((left == right) || ((left - right + 1) > 3)) | ||
{ | ||
return Fork::getEmptyFork(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As said, the default constructor already does that.
const std::size_t right; | ||
const std::size_t left; | ||
const std::size_t size; | ||
const bool valid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
data + boolean valid is more or less what optional<T>
is for - just make it a plain old struct T { U data; };
and then use optional<T>
and check with if (myoptional) use(*myoptional);
// check if all entries in the fork range allow entry | ||
const bool only_valid_entries = intersection.hasValidEntries(right, left); | ||
|
||
// TODO check whether 2*NARROW_TURN is too large |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where did the 2 * narrow turn angle go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea. It was never there when I touched it. I looked into the history in master a bit and couldnt find it either. @MoKob you remember something about this or can I remove the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the comment is out of date. Feel free to remove.
daf26ee
to
908809b
Compare
908809b
to
5905851
Compare
bool hasValidEntries(Intersection::iterator first, Intersection::iterator last) const; | ||
|
||
Base::iterator findClosestTurn(double angle); | ||
Base::const_iterator findClosestTurn(double angle) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the functions here should no longer be attached to Intersection
or IntersectionView
- but instead check EnableIntersectionOps<T>
. If you have the time for it, read up about the CRTP pattern.
We need this since even though this creates a inheritance hierarchy
struct base {};
struct derived : base {};
the following types stand in no relationship to each other
using BaseVec = vector<base>;
using DerivedVec = vector<derived>;
using the CRTP pattern we inject the functionality into both collection types.
Intersection::iterator right; | ||
Intersection::iterator left; | ||
const std::size_t size; | ||
Fork(Intersection::iterator right, Intersection::iterator left); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this work on Intersection
or IntersectionView
- or both?
Check the data these types hold and decide.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fork handling is only called on Intersections (in the dedicated handlers), just as the sliproad handler. Right now this is correct. We could think about how we could update this behaviour, but right no I'd say for the scope of this PR having Intersections here is correct.
|
||
return all_of(first, last + 1, [&](const ConnectedRoad &road) { return road.entry_allowed; }); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comes from the messed up rebase.
// The Turn Operation indicates what is exposed to the outside of the turn analysis. | ||
// | ||
// `angle` is given counter-clockwise: | ||
// 0 = uturn, 90 = right, 180 = straight, 270 = left |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the intersection shape itself does not know about where you come from. It does not offer an angle
property.
// A representation of intermediate intersections | ||
// A representation of intermediate intersections: | ||
// An intersection is an ordered list of connected roads ordered from from sharp right | ||
// counter-clockwise to sharp left where `intersection[0]` is always a u-turn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the intersection in the output is a different object than the intersection in the preprocessing. Here the concept of Connected Roads
is unknown. We offer available turn bearings (in all directions, not angles) and allowed entry flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ugh. changed this. don't know how this happened
Intersection::iterator right; | ||
Intersection::iterator left; | ||
const std::size_t size; | ||
Fork(Intersection::iterator right, Intersection::iterator left); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fork handling is only called on Intersections (in the dedicated handlers), just as the sliproad handler. Right now this is correct. We could think about how we could update this behaviour, but right no I'd say for the scope of this PR having Intersections here is correct.
bool isObviousOfTwo(const EdgeID via_edge, | ||
const ConnectedRoad &road, | ||
const ConnectedRoad &other) const; | ||
|
||
bool hasObvious(const EdgeID &via_edge, const Fork) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this the replacement of the above function? Also Fork could probably benefit from a reference
, due to its size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No this is not a replacement, but yes reference sounds good.
struct Fork | ||
{ | ||
Intersection::iterator right; | ||
Intersection::iterator left; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we are using iterators, wouldn't it be better to follow the stdlib paradigm for begin
, end
here? I'd prefer a begin / end approach at least, but given that Fork
is wrapped into an optional, I'd be alright with left
/right
. However, left
and right
requires implicit knowledge about the order. So we could maybe use ccw_right
and ccw_left
to indicate the order here as well? This way you know which direction to iterate over.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moving to new issue
@@ -68,8 +85,7 @@ class TurnHandler : public IntersectionHandler | |||
handleDistinctConflict(const EdgeID via_edge, ConnectedRoad &left, ConnectedRoad &right) const; | |||
|
|||
// Classification | |||
std::pair<std::size_t, std::size_t> findFork(const EdgeID via_edge, | |||
const Intersection &intersection) const; | |||
boost::optional<Fork> findFork(const EdgeID via_edge, Intersection &intersection) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you maybe add documentation on what the difference between findFork
and findLeftmost...
versions are?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point. I also renamed findLeftAndRightmostForkCandidates
to findForkCandidatesByGeometry
which is hopefully a better name because we're just looking at angles and the geometric relations between the roads here.
using namespace osrm::extractor::guidance; | ||
// given two adjacent roads and `road1` being a candidate for a fork, | ||
// return false, if next road `road2` is also a fork candidate or | ||
// return true, if `road2` is not a suitable fork candidate and thus, `road1` the outermost fork |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adjacent == any specific order? I'd assume they are still in ccw order? Would be nice to specify this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
// if all roads are part of a fork, set `candidate` to the last road | ||
else | ||
{ | ||
return outermost - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we would use the begin
/end
paradigm I mentioned above, we wouldn't need these distinctions here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moving to new issue
} | ||
} | ||
|
||
struct StraightestTurnAtIntersection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adding a dedicated struct here seems wrong to me. the straightmost turn at an instersection can be found with getClosestTurn(STRAIGHT_ANGLE)
for any intersection and is an iterator into the intersection. It's deviation can easily be computed whenever necessary by angularDeviation(itr.angle,STRAIGHT_ANGLE)
.
The dedicated struct is overkill in my personal opinion. Is it used often enough to justify the definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After checking: given that it is used twice, I feel that introducing a dedicated struct here only adds confusion. Having the indirection using an id
instead of the iterator findClosestTurn
returns does only add confusion in my view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch. thanks!
// returns a tuple {i, angle_dev} of the road at the intersection that is closest to going straight: | ||
// `intersection[i]` is the actual road | ||
// `angle_dev` is the angle between going straight and taking the road `intersection[i]` | ||
StraightestTurnAtIntersection findClosestToStraight(const Intersection &intersection) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be removed completely and replaced with findClosestTurn(STRAIGHT_ANGLE)
in intersection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch. thanks!
aaf2397
to
32dcbb5
Compare
32dcbb5
to
138616d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one tiny item left. otherwise 👍
{ | ||
BOOST_ASSERT(end < self()->end()); | ||
|
||
return all_of(begin, end, [](const ConnectedRoad &road) { return road.entry_allowed; }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should use type auto
, since we can also call it on an intersectionView which does not have a connected road.
138616d
to
88a568d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A single Travis build is failing with
Disallowing sources: ubuntu-toolchain-r-test
Might be a blip. Please restart and check again.
{ | ||
auto comp = makeCompareAngularDeviation(angle); | ||
return std::min_element(self()->begin(), self()->end(), comp); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-const overload for the function above?
There is a trick involving a const-cast so you don't have to duplicate code.
Search around for how to implement const / non-const overloads.
Not sure if we need it here ..
bool hasAllValidEntries(const iteratorT begin, const iteratorT end) const | ||
{ | ||
return all_of(begin, end, [](const ConnectedRoad &road) { return road.entry_allowed; }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::all_of
and not all_of
- the reason the unqualified all_of
works is argument-dependant lookup (ADL, great to know, read up a bit about it): if the iterators are in the std namespace all_of
is searched in the std namespace, too.
Check std::all_of
s docs: it requires an InputIt
(make yourself comfortable with the different iterator concepts), which basically means you can run over it once. Because you are using std::all_of
your iterators now also have to be (at least) InputIterators
. You could assert that at compile time via
static_assert(std::is_base_of<std::input_iterator_tag, typename std::iterator_traits<Iter>::iterator_category>::value, "")
but what you usually do is to make the template's type just InputIt, as in
template <typename InputIt> void fn(InputIt first, InputIt last);
(C++ Concepts will change this in the future and enforce the static assert automatically)
Finally, don't hard code ConnectedRoad
as parameter here: the reason we're having the EnableOps
CRTP struct is because you don't know if it's a ConnectedRoad
or a ViewData
. Make it generic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks 🙇
template <typename Iterator> | ||
Iterator findOutermostForkCandidate(const Iterator start, const Iterator end) | ||
{ | ||
const auto outermost = std::adjacent_find(start, end, isOutermostForkCandidate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ForwardIt requirement, as explained above
|
||
// a wrapper to handle road indices of forks at intersections | ||
TurnHandler::Fork::Fork(Intersection::iterator right, Intersection::iterator left) | ||
: right(right), left(left), size((int)(left - right) + 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why int
? And why signed at all?
if (turn_is_perfectly_straight && in_data.name_id != EMPTY_NAMEID && | ||
road_data.name_id != EMPTY_NAMEID && same_name) | ||
via_data.name_id, road_data.name_id, name_table, street_name_suffix_table); | ||
if (turn_is_perfectly_straight && via_data.name_id != EMPTY_NAMEID && same_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, the empty name id check has to happen before the requiresNameAnnounced
above
for (auto road = fork.right; road < fork.left; ++road) | ||
{ | ||
if (isObviousOfTwo(via_edge, *road, *(road + 1)) || | ||
isObviousOfTwo(via_edge, *(road + 1), *road)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is +1 here? Is this always safe to do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, and it is ugly and I tagged it in another issue to fix this #3457 😞
const Intersection &intersection) const | ||
// finds a fork candidate by just looking at the geometry and angle of an intersection | ||
boost::optional<TurnHandler::Fork> | ||
TurnHandler::findForkCandidatesByGeometry(Intersection &intersection) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you ever modify the intersection? If yes, why? If no => const!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, maybe you can help me here cause I was having trouble with this part anyways: If I make intersection const, all iterators I can get are const-iterators. The function is supposed to return a Fork struct with iterators to the beginning and end of the fork end those iterators cannot be const-iterators cause later on I want to modify their instructions. The only solution I got working was to make the intersection non-const, thus resulting in that code.
you have any idea how to fix that?
return std::all_of(fork.right, fork.left + 1, [&](ConnectedRoad &base) { | ||
const auto base_class = node_based_graph.GetEdgeData(base.eid).road_classification; | ||
// check that there is no turn obvious == check that all turns are non-onvious | ||
return std::all_of(fork.right, fork.left + 1, [&](ConnectedRoad &compare) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the second loop have to exclude the road from the first road? Otherwise you're doing a self-comparison?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it's a self comparison, the inner loop will evaluate return [...] || compare.eid == base.eid;
// makes sure that the fork is isolated from other neighbouring streets on the left and | ||
// right side | ||
const auto next = | ||
(fork->left + 1) == intersection.end() ? intersection.begin() : (fork->left + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 safe to do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's safe but will also be fixed by #3457
right > 0 && | ||
angularDeviation(intersection[right].angle, intersection[right - 1].angle) >= | ||
GROUP_ANGLE; | ||
angularDeviation(fork->right->angle, (fork->right - 1)->angle) >= GROUP_ANGLE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
88a568d
to
d462ec2
Compare
d462ec2
to
e69c905
Compare
e69c905
to
696bfdb
Compare
Issue
This PR works towards #3099
Tasklist
TurnHandler::findFork()
codeTurnHandler::isObviousOfTwo()
TurnHandler::findFork()
IntersectionHandler::assignFork()
Tasklist unrelated to this PR (but arose during this work)
struct Intersection
inroute_step.hpp
BasicTurnType
isObviousByRoadClass
inturn_handler.hpp
to a dedicated .compatible() in road_class (road class refactor)struct Fork
to use abegin
andend
iterator instead ofright
andleft
Code Review Todolist
OSRM_ATTR_WARN_UNUSED
tosetTurnTypes
inturn_handler.hpp
findFork()
return type