diff --git a/CHANGELOG.md b/CHANGELOG.md index a0683d62d..9ce21078a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ - Changes from 5.4.1 - Bugfixes - #3254 Fixed a bug that could end up hiding roundabout instructions + - #3260 fixed a bug that provided the wrong location in the arrival instruction # 5.4.2 - Changes from 5.4.1 diff --git a/features/guidance/turn-location.feature b/features/guidance/turn-location.feature new file mode 100644 index 000000000..21ecb7979 --- /dev/null +++ b/features/guidance/turn-location.feature @@ -0,0 +1,23 @@ +@routing @guidance +Feature: Turn Location Feature + + Background: + Given the profile "car" + Given a grid size of 10 meters + + Scenario: Simple feature to test turn locations + Given the node map + """ + c + a b d + """ + + And the ways + | nodes | highway | + | ab | primary | + | cb | primary | + | db | primary | + + When I route I should get + | waypoints | route | turns | locations | + | a,c | ab,cb,cb | depart,turn left,arrive | a,b,c | diff --git a/features/support/data.js b/features/support/data.js index 53dc77932..b5cc95924 100644 --- a/features/support/data.js +++ b/features/support/data.js @@ -126,6 +126,20 @@ module.exports = function () { return fromNode; }; + // find a node based on an array containing lon/lat + this.findNodeByLocation = (node_location) => { + var searched_coordinate = new classes.Location(node_location[0],node_location[1]); + for (var node in this.nameNodeHash) + { + var node_coordinate = new classes.Location(this.nameNodeHash[node].lon,this.nameNodeHash[node].lat); + if (this.FuzzyMatch.matchCoordinate(searched_coordinate, node_coordinate, this.zoom)) + { + return node; + } + } + return '_'; + }; + this.findWayByName = (s) => { return this.nameWayHash[s.toString()] || this.nameWayHash[s.toString().split('').reverse().join('')]; }; diff --git a/features/support/data_classes.js b/features/support/data_classes.js index 2ea8d4e09..5aced6c3b 100644 --- a/features/support/data_classes.js +++ b/features/support/data_classes.js @@ -111,5 +111,12 @@ module.exports = { return this.match(got[0], util.format('%d ~0.0025%', want.lon)) && this.match(got[1], util.format('%d ~0.0025%', want.lat)); } + + matchCoordinate (got, want, zoom) { + if (got == null || want == null) return false; + return this.match(got.lon, util.format('%d +- %d', want.lon, 0.25*zoom)) && + this.match(got.lat, util.format('%d +- %d', want.lat, 0.25*zoom)); + } + } }; diff --git a/features/support/route.js b/features/support/route.js index be4cf97ac..a76b1618f 100644 --- a/features/support/route.js +++ b/features/support/route.js @@ -218,6 +218,14 @@ module.exports = function () { .join(','); }; + this.locations = (instructions) => { + return instructions.legs.reduce((m, v) => m.concat(v.steps), []) + .map(v => { + return this.findNodeByLocation(v.maneuver.location); + }) + .join(','); + }; + this.intersectionList = (instructions) => { return instructions.legs.reduce((m, v) => m.concat(v.steps), []) .map( v => { diff --git a/features/support/shared_steps.js b/features/support/shared_steps.js index 0252cd47b..6d04ce728 100644 --- a/features/support/shared_steps.js +++ b/features/support/shared_steps.js @@ -35,7 +35,7 @@ module.exports = function () { if (err) return cb(err); if (body && body.length) { let destinations, pronunciations, instructions, refs, bearings, turns, modes, times, - distances, summary, intersections, lanes; + distances, summary, intersections, lanes, locations; let json = JSON.parse(body); @@ -54,6 +54,7 @@ module.exports = function () { distances = this.distanceList(json.routes[0]); lanes = this.lanesList(json.routes[0]); summary = this.summary(json.routes[0]); + locations = this.locations(json.routes[0]); } if (headers.has('status')) { @@ -125,6 +126,10 @@ module.exports = function () { got.intersections = (intersections || '').trim(); } + if (headers.has('locations')){ + got.locations = (locations || '').trim(); + } + var putValue = (key, value) => { if (headers.has(key)) got[key] = instructions ? value : ''; }; diff --git a/include/engine/guidance/assemble_steps.hpp b/include/engine/guidance/assemble_steps.hpp index 1a034c4f6..d0e917a16 100644 --- a/include/engine/guidance/assemble_steps.hpp +++ b/include/engine/guidance/assemble_steps.hpp @@ -215,13 +215,6 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa BOOST_ASSERT(segment_index == number_of_segments - 1); bearings = detail::getArriveBearings(leg_geometry); - // This step has length zero, the only reason we need it is the target location - maneuver = {intersection.location, - bearings.first, - bearings.second, - extractor::guidance::TurnInstruction::NO_TURN(), - WaypointType::Arrive, - 0}; intersection = { target_node.location, @@ -232,6 +225,15 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa util::guidance::LaneTuple(), {}}; + // This step has length zero, the only reason we need it is the target location + maneuver = {intersection.location, + bearings.first, + bearings.second, + extractor::guidance::TurnInstruction::NO_TURN(), + WaypointType::Arrive, + 0}; + + BOOST_ASSERT(!leg_geometry.locations.empty()); steps.push_back(RouteStep{target_node.name_id, facade.GetNameForID(target_node.name_id), diff --git a/include/util/debug.hpp b/include/util/debug.hpp index 44b9b02db..1ae7f8569 100644 --- a/include/util/debug.hpp +++ b/include/util/debug.hpp @@ -26,6 +26,7 @@ inline void print(const engine::guidance::RouteStep &step) std::cout << static_cast(step.maneuver.instruction.type) << " " << static_cast(step.maneuver.instruction.direction_modifier) << " " << static_cast(step.maneuver.waypoint_type) << " " + << step.maneuver.location << " " << " Duration: " << step.duration << " Distance: " << step.distance << " Geometry: " << step.geometry_begin << " " << step.geometry_end << "\n\tIntersections: " << step.intersections.size() << " [";