Move classes to intersection object and don't emit notifications

This commit is contained in:
Patrick Niklaus 2017-07-13 23:19:20 +00:00 committed by Patrick Niklaus
parent e413b25cd9
commit 440dccb81b
10 changed files with 84 additions and 62 deletions

View File

@ -583,7 +583,6 @@ step.
- `destinations`: The destinations of the way. Will be `undefined` if there are no destinations. - `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
- `exits`: The exit numbers or names of the way. Will be `undefined` if there are no exit numbers or names. - `exits`: The exit numbers or names of the way. Will be `undefined` if there are no exit numbers or names.
- `mode`: A string signifying the mode of transportation. - `mode`: A string signifying the mode of transportation.
- `classes`: An array of strings signifying the classes of the road as specified in the profile.
- `maneuver`: A `StepManeuver` object representing the maneuver. - `maneuver`: A `StepManeuver` object representing the maneuver.
- `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver - `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver
- `rotary_name`: The name for the rotary. Optionally included, if the step is a rotary and a rotary name is available. - `rotary_name`: The name for the rotary. Optionally included, if the step is a rotary and a rotary name is available.
@ -597,7 +596,6 @@ step.
"mode" : "driving", "mode" : "driving",
"duration" : 15.6, "duration" : 15.6,
"weight" : 15.6, "weight" : 15.6,
"classes": ["toll", "restricted"],
"intersections" : [ "intersections" : [
{ "bearings" : [ 10, 92, 184, 270 ], { "bearings" : [ 10, 92, 184, 270 ],
"lanes" : [ "lanes" : [
@ -735,6 +733,7 @@ location of the StepManeuver. Further intersections are listed for every cross-w
- `location`: A `[longitude, latitude]` pair describing the location of the turn. - `location`: A `[longitude, latitude]` pair describing the location of the turn.
- `bearings`: A list of bearing values (e.g. [0,90,180,270]) that are available at the intersection. The bearings describe all available roads at the intersection. Values are between 0-359 (0=true north) - `bearings`: A list of bearing values (e.g. [0,90,180,270]) that are available at the intersection. The bearings describe all available roads at the intersection. Values are between 0-359 (0=true north)
- `classes`: An array of strings signifying the classes (as specified in the profile) of the road exiting the intersection.
- `entry`: A list of entry flags, corresponding in a 1:1 relationship to the bearings. A value of `true` indicates that the respective road could be entered on a valid route. - `entry`: A list of entry flags, corresponding in a 1:1 relationship to the bearings. A value of `true` indicates that the respective road could be entered on a valid route.
`false` indicates that the turn onto the respective road would violate a restriction. `false` indicates that the turn onto the respective road would violate a restriction.
- `in`: index into bearings/entry array. Used to calculate the bearing just before the turn. Namely, the clockwise angle from true north to the - `in`: index into bearings/entry array. Used to calculate the bearing just before the turn. Namely, the clockwise angle from true north to the
@ -753,6 +752,7 @@ location of the StepManeuver. Further intersections are listed for every cross-w
"out":2, "out":2,
"bearings":[60,150,240,330], "bearings":[60,150,240,330],
"entry":["false","true","true","true"], "entry":["false","true","true","true"],
"classes": ["toll", "restricted"],
"lanes":{ "lanes":{
"indications": ["left", "straight"], "indications": ["left", "straight"],
"valid": "false" "valid": "false"

View File

@ -17,13 +17,13 @@ Feature: Car - Mode flag
| cd | primary | | | cd | primary | |
When I route I should get When I route I should get
| from | to | route | turns | classes | | from | to | route | turns | classes |
| a | d | ab,bc,cd,cd | depart,notification right,notification left,arrive | ,ferry,, | | a | d | ab,bc,cd,cd | depart,notification right,notification left,arrive | [()],[(ferry)],[()],[()] |
| d | a | cd,bc,ab,ab | depart,notification right,notification left,arrive | ,ferry,, | | d | a | cd,bc,ab,ab | depart,notification right,notification left,arrive | [()],[(ferry)],[()],[()] |
| c | a | bc,ab,ab | depart,notification left,arrive | ferry,, | | c | a | bc,ab,ab | depart,notification left,arrive | [(ferry)],[()],[()] |
| d | b | cd,bc,bc | depart,notification right,arrive | ,ferry,ferry | | d | b | cd,bc,bc | depart,notification right,arrive | [()],[(ferry)],[()] |
| a | c | ab,bc,bc | depart,notification right,arrive | ,ferry,ferry | | a | c | ab,bc,bc | depart,notification right,arrive | [()],[(ferry)],[()] |
| b | d | bc,cd,cd | depart,notification left,arrive | ferry,, | | b | d | bc,cd,cd | depart,notification left,arrive | [(ferry)],[()],[()] |
Scenario: Car - We tag motorways with a class Scenario: Car - We tag motorways with a class
@ -40,10 +40,10 @@ Feature: Car - Mode flag
| cd | primary | | cd | primary |
When I route I should get When I route I should get
| from | to | route | turns | classes | # | | from | to | route | turns | classes |
| a | d | ab,bc,cd | depart,notification right,arrive | ,motorway, | | | a | d | ab,cd | depart,arrive | [(),(motorway),()],[()] |
| a | c | ab,bc,bc | depart,notification right,arrive | ,motorway,motorway | | | a | c | ab,bc | depart,arrive | [(),(motorway)],[()] |
| b | d | bc,cd | depart,arrive | motorway, | we don't announce when we leave the highway | | b | d | bc,cd | depart,arrive | [(motorway),()],[()] |
Scenario: Car - We tag motorway_link with a class Scenario: Car - We tag motorway_link with a class
Given the node map Given the node map
@ -59,10 +59,10 @@ Feature: Car - Mode flag
| cd | primary | | cd | primary |
When I route I should get When I route I should get
| from | to | route | turns | classes | # | | from | to | route | turns | classes | # |
| a | d | ab,bc,cd | depart,on ramp right,arrive | ,motorway, | notification replaced by on-ramp | | a | d | ab,bc,cd | depart,on ramp right,arrive | [()],[(motorway),()],[()] | on-ramp at class change |
| a | c | ab,bc,bc | depart,on ramp right,arrive | ,motorway,motorway | " " | | a | c | ab,bc,bc | depart,on ramp right,arrive | [()],[(motorway)],[()] | " " |
| b | d | bc,cd | depart,arrive | motorway, | no announcement | | b | d | bc,cd | depart,arrive | [(motorway),()],[()] | no announcement |
Scenario: Car - We tag restricted with a class Scenario: Car - We tag restricted with a class
@ -79,8 +79,8 @@ Feature: Car - Mode flag
| cd | primary | | | cd | primary | |
When I route I should get When I route I should get
| from | to | route | turns | classes | | from | to | route | turns | classes |
| a | d | ab,bc,cd | depart,notification right,arrive| restricted,motorway;restricted, | | a | d | ab,cd | depart,arrive| [(restricted),(motorway,restricted),()],[()] |
Scenario: Car - We toll restricted with a class Scenario: Car - We toll restricted with a class
Given the node map Given the node map
@ -96,6 +96,32 @@ Feature: Car - Mode flag
| cd | primary | | | cd | primary | |
When I route I should get When I route I should get
| from | to | route | turns | classes | | from | to | route | turns | classes |
| a | d | ab,bc,cd | depart,notification right,arrive | toll,motorway;toll, | | a | d | ab,cd | depart,arrive | [(toll),(motorway,toll),()],[()] |
Scenario: Car - From roundabout on toll road
Given the node map
"""
c
/ \
a---b d---f
\ /
e
|
g
"""
And the ways
| nodes | oneway | highway | junction | toll |
| ab | yes | primary | | |
| cb | yes | primary | roundabout | |
| dc | yes | primary | roundabout | |
| be | yes | primary | roundabout | |
| ed | yes | motorway| roundabout | |
| eg | yes | primary | | |
| df | yes | motorway| | yes |
When I route I should get
| from | to | route | turns | classes |
| a | f | ab,df,df | depart,roundabout-exit-2,arrive | [()],[(),(motorway),(toll,motorway)],[()] |

View File

@ -23,11 +23,11 @@ Feature: Car - Destination only, no passing through
When I route I should get When I route I should get
| from | to | route | | from | to | route |
| a | b | ab,ab | | a | b | ab,ab |
| a | c | ab,bcd,bcd | | a | c | ab,bcd |
| a | d | ab,bcd,bcd | | a | d | ab,bcd,bcd |
| a | e | axye,axye | | a | e | axye,axye |
| e | d | de,de | | e | d | de,de |
| e | c | de,bcd,bcd | | e | c | de,bcd |
| e | b | de,bcd,bcd | | e | b | de,bcd,bcd |
| e | a | axye,axye | | e | a | axye,axye |
@ -51,12 +51,12 @@ Feature: Car - Destination only, no passing through
When I route I should get When I route I should get
| from | to | route | | from | to | route |
| a | b | ab,ab | | a | b | ab,ab |
| a | c | ab,bc,bc | | a | c | ab,bc |
| a | d | ab,bc,cd | | a | d | ab,cd |
| a | e | axye,axye | | a | e | axye,axye |
| e | d | de,de | | e | d | de,de |
| e | c | de,cd,cd | | e | c | de,cd |
| e | b | de,cd,bc | | e | b | de,bc |
| e | a | axye,axye | | e | a | axye,axye |
Scenario: Car - Routing inside a destination only area Scenario: Car - Routing inside a destination only area

View File

@ -268,7 +268,7 @@ module.exports = function () {
}; };
this.classesList = (instructions) => { this.classesList = (instructions) => {
return this.extractInstructionList(instructions, s => s.classes ? s.classes.join(';') : ''); return this.extractInstructionList(instructions, s => '[' + s.intersections.map(i => '(' + (i.classes ? i.classes.join(',') : '') + ')').join(',') + ']');
}; };
this.timeList = (instructions) => { this.timeList = (instructions) => {

View File

@ -63,7 +63,6 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
: target_node.forward_segment_id.id; : target_node.forward_segment_id.id;
const auto target_name_id = facade.GetNameIndex(target_node_id); const auto target_name_id = facade.GetNameIndex(target_node_id);
const auto target_mode = facade.GetTravelMode(target_node_id); const auto target_mode = facade.GetTravelMode(target_node_id);
auto target_classes = facade.GetClasses(facade.GetClassData(target_node_id));
const auto number_of_segments = leg_geometry.GetNumberOfSegments(); const auto number_of_segments = leg_geometry.GetNumberOfSegments();
@ -88,7 +87,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
0, 0,
util::guidance::LaneTuple(), util::guidance::LaneTuple(),
{}}; {},
source_classes};
if (leg_data.size() > 0) if (leg_data.size() > 0)
{ {
@ -118,7 +118,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const auto destinations = facade.GetDestinationsForID(step_name_id); const auto destinations = facade.GetDestinationsForID(step_name_id);
const auto exits = facade.GetExitsForID(step_name_id); const auto exits = facade.GetExitsForID(step_name_id);
const auto distance = leg_geometry.segment_distances[segment_index]; const auto distance = leg_geometry.segment_distances[segment_index];
auto classes = facade.GetClasses(path_point.classes); // intersections contain the classes of exiting road
intersection.classes = facade.GetClasses(path_point.classes);
steps.push_back(RouteStep{step_name_id, steps.push_back(RouteStep{step_name_id,
name.to_string(), name.to_string(),
@ -135,8 +136,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
maneuver, maneuver,
leg_geometry.FrontIndex(segment_index), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1, leg_geometry.BackIndex(segment_index) + 1,
{intersection}, {intersection}});
std::move(classes)});
if (leg_data_index + 1 < leg_data.size()) if (leg_data_index + 1 < leg_data.size())
{ {
@ -196,6 +196,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const auto distance = leg_geometry.segment_distances[segment_index]; const auto distance = leg_geometry.segment_distances[segment_index];
const EdgeWeight duration = segment_duration + target_duration; const EdgeWeight duration = segment_duration + target_duration;
const EdgeWeight weight = segment_weight + target_weight; const EdgeWeight weight = segment_weight + target_weight;
// intersections contain the classes of exiting road
intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id));
BOOST_ASSERT(duration >= 0); BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{step_name_id, steps.push_back(RouteStep{step_name_id,
facade.GetNameForID(step_name_id).to_string(), facade.GetNameForID(step_name_id).to_string(),
@ -212,8 +214,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
maneuver, maneuver,
leg_geometry.FrontIndex(segment_index), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1, leg_geometry.BackIndex(segment_index) + 1,
{intersection}, {intersection}});
std::move(target_classes)});
} }
// In this case the source + target are on the same edge segment // In this case the source + target are on the same edge segment
else else
@ -255,8 +256,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
std::move(maneuver), std::move(maneuver),
leg_geometry.FrontIndex(segment_index), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1, leg_geometry.BackIndex(segment_index) + 1,
{intersection}, {intersection}});
std::move(source_classes)});
} }
BOOST_ASSERT(segment_index == number_of_segments - 1); BOOST_ASSERT(segment_index == number_of_segments - 1);
@ -269,6 +269,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
0, 0,
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
util::guidance::LaneTuple(), util::guidance::LaneTuple(),
{},
{}}; {}};
// This step has length zero, the only reason we need it is the target location // This step has length zero, the only reason we need it is the target location
@ -295,8 +296,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
std::move(maneuver), std::move(maneuver),
leg_geometry.locations.size() - 1, leg_geometry.locations.size() - 1,
leg_geometry.locations.size(), leg_geometry.locations.size(),
{intersection}, {intersection}});
std::move(target_classes)});
BOOST_ASSERT(steps.front().intersections.size() == 1); BOOST_ASSERT(steps.front().intersections.size() == 1);
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1); BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);

View File

@ -42,6 +42,7 @@ struct IntermediateIntersection
// turn lane information // turn lane information
util::guidance::LaneTuple lanes; util::guidance::LaneTuple lanes;
extractor::guidance::TurnLaneDescription lane_description; extractor::guidance::TurnLaneDescription lane_description;
std::vector<std::string> classes;
}; };
inline IntermediateIntersection getInvalidIntersection() inline IntermediateIntersection getInvalidIntersection()
@ -52,6 +53,7 @@ inline IntermediateIntersection getInvalidIntersection()
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
util::guidance::LaneTuple(), util::guidance::LaneTuple(),
{},
{}}; {}};
} }
@ -74,7 +76,6 @@ struct RouteStep
std::size_t geometry_begin; std::size_t geometry_begin;
std::size_t geometry_end; std::size_t geometry_end;
std::vector<IntermediateIntersection> intersections; std::vector<IntermediateIntersection> intersections;
std::vector<std::string> classes;
// remove all information from the route step, marking it as invalid (used to indicate empty // remove all information from the route step, marking it as invalid (used to indicate empty
// steps to be removed). // steps to be removed).
@ -128,7 +129,6 @@ inline void RouteStep::Invalidate()
geometry_end = 0; geometry_end = 0;
intersections.clear(); intersections.clear();
intersections.push_back(getInvalidIntersection()); intersections.push_back(getInvalidIntersection());
classes.clear();
} }
// Elongate by another step in front // Elongate by another step in front

View File

@ -234,6 +234,18 @@ util::json::Object makeIntersection(const guidance::IntermediateIntersection &in
if (detail::hasValidLanes(intersection)) if (detail::hasValidLanes(intersection))
result.values["lanes"] = detail::lanesFromIntersection(intersection); result.values["lanes"] = detail::lanesFromIntersection(intersection);
if (!intersection.classes.empty())
{
util::json::Array classes;
classes.values.reserve(intersection.classes.size());
std::transform(
intersection.classes.begin(),
intersection.classes.end(),
std::back_inserter(classes.values),
[](const std::string &class_name) { return util::json::String{class_name}; });
result.values["classes"] = std::move(classes);
}
return result; return result;
} }
@ -265,18 +277,6 @@ util::json::Object makeRouteStep(guidance::RouteStep step, util::json::Value geo
route_step.values["maneuver"] = makeStepManeuver(std::move(step.maneuver)); route_step.values["maneuver"] = makeStepManeuver(std::move(step.maneuver));
route_step.values["geometry"] = std::move(geometry); route_step.values["geometry"] = std::move(geometry);
if (!step.classes.empty())
{
util::json::Array classes;
classes.values.reserve(step.classes.size());
std::transform(
step.classes.begin(),
step.classes.end(),
std::back_inserter(classes.values),
[](const std::string &class_name) { return util::json::String{class_name}; });
route_step.values["classes"] = std::move(classes);
}
util::json::Array intersections; util::json::Array intersections;
intersections.values.reserve(step.intersections.size()); intersections.values.reserve(step.intersections.size());
std::transform(step.intersections.begin(), std::transform(step.intersections.begin(),

View File

@ -485,7 +485,6 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
auto &new_next_to_last = *(steps.end() - 2); auto &new_next_to_last = *(steps.end() - 2);
next_to_last_step.AdaptStepSignage(new_next_to_last); next_to_last_step.AdaptStepSignage(new_next_to_last);
next_to_last_step.mode = new_next_to_last.mode; next_to_last_step.mode = new_next_to_last.mode;
next_to_last_step.classes = new_next_to_last.classes;
// the geometry indices of the last step are already correct; // the geometry indices of the last step are already correct;
} }
else if (util::coordinate_calculation::haversineDistance( else if (util::coordinate_calculation::haversineDistance(

View File

@ -88,10 +88,7 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
// handle travel modes: // handle travel modes:
const auto in_mode = node_based_graph.GetEdgeData(via_edge).travel_mode; const auto in_mode = node_based_graph.GetEdgeData(via_edge).travel_mode;
const auto out_mode = node_based_graph.GetEdgeData(road.eid).travel_mode; const auto out_mode = node_based_graph.GetEdgeData(road.eid).travel_mode;
const auto in_classes = node_based_graph.GetEdgeData(via_edge).classes; const auto needs_notification = in_mode != out_mode;
const auto out_classes = node_based_graph.GetEdgeData(road.eid).classes;
// if we just lose class flags we don't want to notify
const auto needs_notification = in_mode != out_mode || !isSubset(out_classes, in_classes);
if (type == TurnType::Turn) if (type == TurnType::Turn)
{ {

View File

@ -23,6 +23,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments)
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
0, 0,
{0, 255}, {0, 255},
{},
{}}; {}};
IntermediateIntersection intersection2{{FloatLongitude{-73.981495}, FloatLatitude{40.768275}}, IntermediateIntersection intersection2{{FloatLongitude{-73.981495}, FloatLatitude{40.768275}},
{180}, {180},
@ -30,6 +31,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments)
0, 0,
IntermediateIntersection::NO_INDEX, IntermediateIntersection::NO_INDEX,
{0, 255}, {0, 255},
{},
{}}; {}};
// Check that duplicated coordinate in the end is removed // Check that duplicated coordinate in the end is removed
@ -53,8 +55,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments)
0}, 0},
0, 0,
3, 3,
{intersection1}, {intersection1}},
{}},
{324, {324,
"Central Park West", "Central Park West",
"", "",
@ -75,8 +76,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments)
0}, 0},
2, 2,
3, 3,
{intersection2}, {intersection2}}};
{}}};
LegGeometry geometry; LegGeometry geometry;
geometry.locations = {{FloatLongitude{-73.981492}, FloatLatitude{40.768258}}, geometry.locations = {{FloatLongitude{-73.981492}, FloatLatitude{40.768258}},