handle all our new strings correctly, introduce rotary_pronunciation
This commit is contained in:
parent
9123c93a90
commit
938dff011f
@ -17,6 +17,7 @@
|
||||
- BREAKING: Fixed a bug that could crash postprocessing of instructions on invalid roundabout taggings. This change requires reprocessing datasets with osrm-extract and osrm-contract
|
||||
- Fixed an issue that could emit `invalid` as instruction when ending on a sliproad after a traffic-light
|
||||
- Fixed an issue that would detect turning circles as sliproads
|
||||
- Fixed a bug where post-processing instructions (e.g. left + left -> uturn) could result in false pronunciations
|
||||
|
||||
# 5.3.0
|
||||
Changes from 5.3.0-rc.3
|
||||
|
@ -537,7 +537,7 @@ step.
|
||||
| `use lane` | going straight on a specific lane |
|
||||
| `continue` | Turn in direction of `modifier` to stay on the same road |
|
||||
| `roundabout` | traverse roundabout, has additional field `exit` with NR if the roundabout is left. `the modifier specifies the direction of entering the roundabout` |
|
||||
| `rotary` | a larger version of a roundabout, can offer `rotary_name` in addition to the `exit` parameter. |
|
||||
| `rotary` | a larger version of a roundabout, can offer `rotary_name/rotary_pronunciation` in addition to the `exit` parameter. |
|
||||
| `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
|
||||
| `notification` | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction |
|
||||
|
||||
|
@ -48,3 +48,31 @@ Feature: Car - Street names in instructions
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | c | tertiary,residential,residential |
|
||||
|
||||
Scenario: Inner city expressway with on road
|
||||
Given the node map
|
||||
| a | b | | | | c | g |
|
||||
| | | | | f | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | d | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | e | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | name:pronunciation |
|
||||
| abc | primary | road | roooaad |
|
||||
| cg | primary | road | roooaad |
|
||||
| bfd | trunk_link | | |
|
||||
| cde | trunk | trunk | truank |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | abc | cde | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | pronunciations |
|
||||
| a,e | road,trunk,trunk | depart,turn right,arrive | roooaad,truank,truank |
|
||||
|
@ -112,6 +112,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
std::move(pronunciation),
|
||||
std::move(destinations),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
segment_duration / 10.0,
|
||||
distance,
|
||||
path_point.travel_mode,
|
||||
@ -170,6 +171,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
facade.GetPronunciationForID(step_name_id),
|
||||
facade.GetDestinationsForID(step_name_id),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
distance,
|
||||
target_mode,
|
||||
@ -195,6 +197,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
facade.GetPronunciationForID(source_node.name_id),
|
||||
facade.GetDestinationsForID(source_node.name_id),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
leg_geometry.segment_distances[segment_index],
|
||||
source_mode,
|
||||
@ -229,6 +232,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
facade.GetPronunciationForID(target_node.name_id),
|
||||
facade.GetDestinationsForID(target_node.name_id),
|
||||
NO_ROTARY_NAME,
|
||||
NO_ROTARY_NAME,
|
||||
ZERO_DURATION,
|
||||
ZERO_DISTANCE,
|
||||
target_mode,
|
||||
|
@ -61,6 +61,7 @@ struct RouteStep
|
||||
std::string pronunciation;
|
||||
std::string destinations;
|
||||
std::string rotary_name;
|
||||
std::string rotary_pronunciation;
|
||||
double duration;
|
||||
double distance;
|
||||
extractor::TravelMode mode;
|
||||
@ -78,6 +79,7 @@ inline RouteStep getInvalidRouteStep()
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
0,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
|
@ -240,7 +240,13 @@ util::json::Object makeRouteStep(guidance::RouteStep step, util::json::Value geo
|
||||
if (!step.destinations.empty())
|
||||
route_step.values["destinations"] = std::move(step.destinations);
|
||||
if (!step.rotary_name.empty())
|
||||
{
|
||||
route_step.values["rotary_name"] = std::move(step.rotary_name);
|
||||
if (!step.rotary_pronunciation.empty())
|
||||
{
|
||||
route_step.values["rotary_pronunciation"] = std::move(step.rotary_pronunciation);
|
||||
}
|
||||
}
|
||||
|
||||
route_step.values["mode"] = detail::modeToString(std::move(step.mode));
|
||||
route_step.values["maneuver"] = makeStepManeuver(std::move(step.maneuver));
|
||||
|
@ -44,6 +44,16 @@ inline bool hasManeuver(const RouteStep &first, const RouteStep &second)
|
||||
second.maneuver.instruction.type != TurnType::Suppressed;
|
||||
}
|
||||
|
||||
// forward all signage/name data from one step to another.
|
||||
// When we collapse a step, we might have to transfer the name, pronunciation and similar tags.
|
||||
inline void forwardStepSignage(RouteStep &destination, const RouteStep &origin)
|
||||
{
|
||||
destination.name_id = origin.name_id;
|
||||
destination.name = origin.name;
|
||||
destination.pronunciation = origin.pronunciation;
|
||||
destination.destinations = origin.destinations;
|
||||
}
|
||||
|
||||
inline bool choiceless(const RouteStep &step, const RouteStep &previous)
|
||||
{
|
||||
// if the next turn is choiceless, we consider longer turn roads collapsable than usually
|
||||
@ -156,7 +166,10 @@ void fixFinalRoundabout(std::vector<RouteStep> &steps)
|
||||
// remember the current name as rotary name in tha case we end in a rotary
|
||||
if (propagation_step.maneuver.instruction.type == TurnType::EnterRotary ||
|
||||
propagation_step.maneuver.instruction.type == TurnType::EnterRotaryAtExit)
|
||||
{
|
||||
propagation_step.rotary_name = propagation_step.name;
|
||||
propagation_step.rotary_pronunciation = propagation_step.pronunciation;
|
||||
}
|
||||
|
||||
else if (propagation_step.maneuver.instruction.type ==
|
||||
TurnType::EnterRoundaboutIntersection ||
|
||||
@ -254,7 +267,10 @@ void closeOffRoundabout(const bool on_roundabout,
|
||||
};
|
||||
steps[1].maneuver.instruction.type = exitToEnter(step.maneuver.instruction.type);
|
||||
if (steps[1].maneuver.instruction.type == TurnType::EnterRotary)
|
||||
{
|
||||
steps[1].rotary_name = steps[0].name;
|
||||
steps[1].rotary_pronunciation = steps[0].pronunciation;
|
||||
}
|
||||
}
|
||||
|
||||
// Normal exit from the roundabout, or exit from a previously fixed roundabout. Propagate the
|
||||
@ -266,8 +282,7 @@ void closeOffRoundabout(const bool on_roundabout,
|
||||
// intersections are locations passed along the way
|
||||
const auto exit_intersection = steps[step_index].intersections.front();
|
||||
const auto exit_bearing = exit_intersection.bearings[exit_intersection.out];
|
||||
const auto destination_name = step.name;
|
||||
const auto destinatino_name_id = step.name_id;
|
||||
const auto destination_copy = step;
|
||||
if (step_index > 1)
|
||||
{
|
||||
// The very first route-step is head, so we cannot iterate past that one
|
||||
@ -285,6 +300,7 @@ void closeOffRoundabout(const bool on_roundabout,
|
||||
propagation_step.maneuver.instruction.type == TurnType::EnterRotaryAtExit)
|
||||
{
|
||||
propagation_step.rotary_name = propagation_step.name;
|
||||
propagation_step.rotary_pronunciation = propagation_step.pronunciation;
|
||||
}
|
||||
else if (propagation_step.maneuver.instruction.type ==
|
||||
TurnType::EnterRoundaboutIntersection ||
|
||||
@ -301,8 +317,7 @@ void closeOffRoundabout(const bool on_roundabout,
|
||||
::osrm::util::guidance::getTurnDirection(angle);
|
||||
}
|
||||
|
||||
propagation_step.name = destination_name;
|
||||
propagation_step.name_id = destinatino_name_id;
|
||||
forwardStepSignage(propagation_step, destination_copy);
|
||||
invalidateStep(steps[propagation_index + 1]);
|
||||
break;
|
||||
}
|
||||
@ -424,8 +439,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
util::guidance::mirrorDirectionModifier(
|
||||
steps[one_back_index].maneuver.instruction.direction_modifier);
|
||||
}
|
||||
steps[one_back_index].name = current_step.name;
|
||||
steps[one_back_index].name_id = current_step.name_id;
|
||||
forwardStepSignage(steps[one_back_index], current_step);
|
||||
invalidateStep(steps[step_index]);
|
||||
}
|
||||
}
|
||||
@ -441,7 +455,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
{
|
||||
BOOST_ASSERT(two_back_index < steps.size());
|
||||
// the simple case is a u-turn that changes directly into the in-name again
|
||||
const bool direct_u_turn = steps[two_back_index].name == current_step.name;
|
||||
const bool direct_u_turn = steps[two_back_index].name_id == current_step.name_id;
|
||||
|
||||
// however, we might also deal with a dual-collapse scenario in which we have to
|
||||
// additionall collapse a name-change as welll
|
||||
@ -451,7 +465,8 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
(steps[next_step_index].maneuver.instruction.type == TurnType::UseLane ||
|
||||
isCollapsableInstruction(steps[next_step_index].maneuver.instruction));
|
||||
const bool u_turn_with_name_change =
|
||||
continues_with_name_change && steps[next_step_index].name == steps[two_back_index].name;
|
||||
continues_with_name_change &&
|
||||
steps[next_step_index].name_id == steps[two_back_index].name_id;
|
||||
|
||||
if (direct_u_turn || u_turn_with_name_change)
|
||||
{
|
||||
@ -466,8 +481,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
// beginning of this function
|
||||
}
|
||||
|
||||
steps[one_back_index].name = steps[two_back_index].name;
|
||||
steps[one_back_index].name_id = steps[two_back_index].name_id;
|
||||
forwardStepSignage(steps[one_back_index], steps[two_back_index]);
|
||||
steps[one_back_index].maneuver.instruction.type = TurnType::Continue;
|
||||
steps[one_back_index].maneuver.instruction.direction_modifier =
|
||||
DirectionModifier::UTurn;
|
||||
@ -780,8 +794,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
steps[one_back_index] =
|
||||
elongate(std::move(steps[one_back_index]), steps[step_index]);
|
||||
|
||||
steps[one_back_index].name_id = steps[step_index].name_id;
|
||||
steps[one_back_index].name = steps[step_index].name;
|
||||
forwardStepSignage(steps[one_back_index], steps[step_index]);
|
||||
// the turn lanes for this turn are on the sliproad itself, so we have to
|
||||
// remember them
|
||||
steps[one_back_index].intersections.front().lanes =
|
||||
@ -807,7 +820,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
// These have to be handled in post-processing
|
||||
else if (isCollapsableInstruction(current_step.maneuver.instruction) &&
|
||||
current_step.maneuver.instruction.type != TurnType::Suppressed &&
|
||||
steps[getPreviousNameIndex(step_index)].name == current_step.name &&
|
||||
steps[getPreviousNameIndex(step_index)].name_id == current_step.name_id &&
|
||||
canCollapseAll(getPreviousNameIndex(step_index) + 1, next_step_index))
|
||||
{
|
||||
BOOST_ASSERT(step_index > 0);
|
||||
@ -831,8 +844,8 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
const auto two_back_index = getPreviousIndex(one_back_index);
|
||||
BOOST_ASSERT(two_back_index < steps.size());
|
||||
// valid, since one_back is collapsable or a turn and therefore not depart:
|
||||
const auto &coming_from_name = steps[two_back_index].name;
|
||||
if (current_step.name == coming_from_name)
|
||||
const auto &coming_from_name_id = steps[two_back_index].name_id;
|
||||
if (current_step.name_id == coming_from_name_id)
|
||||
{
|
||||
if (compatible(one_back_step, steps[two_back_index]))
|
||||
{
|
||||
@ -861,7 +874,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
else if (step_index + 2 < steps.size() &&
|
||||
current_step.maneuver.instruction.type == TurnType::NewName &&
|
||||
steps[next_step_index].maneuver.instruction.type == TurnType::NewName &&
|
||||
one_back_step.name == steps[next_step_index].name)
|
||||
one_back_step.name_id == steps[next_step_index].name_id)
|
||||
{
|
||||
// if we are crossing an intersection and go immediately after into a name change,
|
||||
// we don't wan't to collapse the initial intersection.
|
||||
@ -1077,8 +1090,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
||||
// as the segment before it. Thus, we have to copy the names
|
||||
// and travel modes from the new next_to_last step.
|
||||
auto &new_next_to_last = *(steps.end() - 2);
|
||||
next_to_last_step.name = new_next_to_last.name;
|
||||
next_to_last_step.name_id = new_next_to_last.name_id;
|
||||
forwardStepSignage(next_to_last_step, new_next_to_last);
|
||||
next_to_last_step.mode = new_next_to_last.mode;
|
||||
// the geometry indices of the last step are already correct;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user