Skip to content
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

Update name_id/name checks for empty IDs and empty strings #4684

Merged
merged 12 commits into from
Dec 11, 2017

Conversation

daniel-j-h
Copy link
Member

Here's a failing cucumber scenario where we get a continue right when there are no name tags but the ref tag changes. My hunch is the underlying issue is #4642 and the continue type comes from:

const auto same_name = !util::guidance::requiresNameAnnounced(
in_name, out_name, name_table, street_name_suffix_table);
if (in_name != EMPTY_NAMEID && out_name != EMPTY_NAMEID && same_name)
{
return TurnType::Continue;
}
return TurnType::Turn;

Next actions:

@karenzshea
Copy link
Contributor

@daniel-j-h can you review here?

const RouteStepIterator step_leaving_intersection,
const std::string &step_prior_name,
const std::string &step_entering_name,
const std::string &step_leaving_name);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need the strings here? Aren't they in the route steps already?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oo good catch, did not see that this was already available.

@@ -371,6 +371,9 @@ RouteSteps collapseTurnInstructions(RouteSteps steps)
break;

const auto previous_step = findPreviousTurn(current_step);
const auto previous_step_name = facade.GetNameForID(previous_step->name_id).to_string();
const auto current_step_name = facade.GetNameForID(current_step->name_id).to_string();
const auto next_step_name = facade.GetNameForID(next_step->name_id).to_string();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need a string copy here or is a string view good enough?

(the .to_string() makes a copy of the internal memory used to represent a string)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be removed since way names are already available through RouteSteps

@karenzshea karenzshea self-assigned this Nov 28, 2017
@@ -164,6 +163,9 @@ bool isStaggeredIntersection(const RouteStepIterator step_prior_to_intersection,
bool isUTurn(const RouteStepIterator step_prior_to_intersection,
const RouteStepIterator step_entering_intersection,
const RouteStepIterator step_leaving_intersection)
// const std::string &step_prior_name,
// const std::string &step_entering_name,
// const std::string &step_leaving_name)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

const RouteStep &post_link_step)
bool isLinkRoad(const RouteStep &link_step,
const std::string &pre_link_step_name,
const std::string &post_link_step_name)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the change here?

@@ -463,6 +463,7 @@ RouteSteps collapseTurnInstructions(RouteSteps steps)
if (!hasWaypointType(*previous_step))
{
const auto far_back_step = findPreviousTurn(previous_step);
const auto far_back_step_name = facade.GetNameForID(far_back_step->name_id).to_string();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused, can this be removed, and then can the facade also be removed from the function signature?

node_data_container.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
.name_id;
const auto &in_name = name_table.GetNameForID(in_name_id).to_string();
const auto &out_name = name_table.GetNameForID(out_name_id).to_string();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have to make two string copies here? Or can we already check the string view for empty?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea!

node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
.name_id;
if (name_id == EMPTY_NAMEID || road_name == EMPTY_NAMEID)
const auto road_name = name_table.GetNameForID(road_name_id).to_string();
if (name_id == EMPTY_NAMEID || road_name.empty())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this - why to we

  • receive the name_id
  • use the name_id to fetch the road name
  • and only then check if the name_id is valid?

what will happen if the name id is invalid and we call GetNameForID on it?

const auto &first_intersection_name =
name_table.GetNameForID(first_intersection_data.name_id).to_string();
const auto &second_intersection_name =
name_table.GetNameForID(second_intersection_data.name_id).to_string();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here - what happens if name id is invalid

@@ -295,7 +295,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
return SPECIAL_EDGEID;
}

if (EMPTY_NAMEID != edge_data.name_id)
const auto &edge_name = name_table.GetNameForID(edge_data.name_id).to_string();
if (!edge_name.empty())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here

@@ -474,7 +474,8 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter

// Name mismatch: check roads at `c` and `d` for same name
const auto name_mismatch = [&](const NameID road_name_id) {
const auto unnamed = road_name_id == EMPTY_NAMEID;
const auto &road_name = name_table.GetNameForID(road_name_id).to_string();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here

@@ -501,9 +502,13 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
.name_id;
const auto &sliproad_annotation =
node_data_container.GetAnnotation(sliproad_edge_data.annotation_data);
const auto &sliproad_name =
name_table.GetNameForID(sliproad_annotation.name_id).to_string();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here

@@ -199,7 +199,8 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,

const bool turn_is_perfectly_straight =
angularDeviation(road.angle, STRAIGHT_ANGLE) < std::numeric_limits<double>::epsilon();
if (via_data.name_id != EMPTY_NAMEID)
const auto &via_name = name_table.GetNameForID(via_data.name_id).to_string();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here

node_data_container.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
.name_id;
const auto &in_name_empty = name_table.GetNameForID(in_name_id).to_string().empty();
const auto &out_name_empty = name_table.GetNameForID(out_name_id).to_string().empty();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetXForID returns

http://www.boost.org/doc/libs/1_60_0/libs/utility/doc/html/string_ref.html

a zero-copy view onto the data. If you call .to_string() on it you make a copy of the data and allocate memory for that. But we only want to know if the data is empty. Check the string ref docs, there is already an empty function on the string ref.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙇‍♀️

if (name_id == EMPTY_NAMEID || road_name_id == EMPTY_NAMEID)
return true;
const auto road_name_empty = name_table.GetNameForID(road_name_id).to_string().empty();
const auto in_name_empty = name_table.GetNameForID(name_id).to_string().empty();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

return false;
const auto &road_name_empty = name_table.GetNameForID(road_name_id).to_string().empty();
const auto &required_name_empty =
name_table.GetNameForID(required_name_id).to_string().empty();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

const auto unnamed =
road_name_id == EMPTY_NAMEID
? true
: name_table.GetNameForID(road_name_id).to_string().empty();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

: name_table.GetNameForID(sliproad_annotation.name_id).to_string().empty();
const auto &main_road_name = name_table.GetNameForID(main_road_name_id).to_string();
const auto &candidate_road_name =
name_table.GetNameForID(candidate_data.name_id).to_string();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

const auto &via_name_empty =
via_data.name_id == EMPTY_NAMEID
? true
: name_table.GetNameForID(via_data.name_id).to_string().empty();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

@karenzshea karenzshea changed the title Adds cucumber test for continue not taking ref into account when name is empty Update name_id/name checks for empty IDs and empty strings Dec 1, 2017
Copy link
Member Author

@daniel-j-h daniel-j-h left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have stats from the statistics handler? Would be great to have a feeling for what this changeset changes. And maybe create a map and sample some locations.

const auto &first_intersection_name =
name_table.GetNameForID(first_intersection_data.name_id).to_string();
const auto &second_intersection_name =
name_table.GetNameForID(second_intersection_data.name_id).to_string();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy needed here?

{
const auto &edge_name = name_table.GetNameForID(edge_data.name_id).to_string();
if (!edge_name.empty())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy needed here for the empty check?

const auto main_road_name_empty =
main_road_name_id == EMPTY_NAMEID
? true
: name_table.GetNameForID(main_road_name_id).empty();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and below: you can simplify to

const auto empty = name_id == EMPTY || GetName(name_id).empty()

@@ -199,7 +199,9 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,

const bool turn_is_perfectly_straight =
angularDeviation(road.angle, STRAIGHT_ANGLE) < std::numeric_limits<double>::epsilon();
if (via_data.name_id != EMPTY_NAMEID)
const auto &via_name_empty =
via_data.name_id == EMPTY_NAMEID ? true : name_table.GetNameForID(via_data.name_id).empty();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

@karenzshea
Copy link
Contributor

Cool! I used https://github.com/mapbox/osrm-guidance-differ with a few modifications to compare current master against this branch and I saw some good changes from continue to turn maneuver types. On master, we sometimes announce a continue onto streets that are missing names, and now we announce a turn even if the street is unnamed. Mostly saw this on sliproads.
image
Previously we announced a maneuver onto the unnamed sliproad as a continue slight right, is now a turn slight right

Same here,
image

Map linked here

@TheMarex TheMarex removed the Review label Dec 5, 2017
@TheMarex TheMarex merged commit 9a8ed30 into master Dec 11, 2017
@TheMarex TheMarex deleted the name-ref-change branch December 11, 2017 15:38
@TheMarex TheMarex added this to the 5.14.2 milestone Dec 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants