Expose driving_side as a property on RouteStep
This commit is contained in:
		
							parent
							
								
									5b79640b44
								
							
						
					
					
						commit
						5b58445535
					
				| @ -1,10 +1,14 @@ | |||||||
| # UNRELEASED | # UNRELEASED | ||||||
| 
 |   - Changes from 5.13 | ||||||
|   - Changes from 5.13: |     - API: | ||||||
|  |       - new RouteStep property `driving_side` that has either "left" or "right" for that step | ||||||
|  |     - Misc: | ||||||
|  |       - Bundles a rough (please improve!) driving-side GeoJSON file for use with `osrm-extract --location-dependent-data data/driving_side.geojson` | ||||||
|     - Profile: |     - Profile: | ||||||
|       - Remove dependency on turn types and turn modifier in the process_turn function in the `car.lua` profile. Guidance instruction types are not used to influence turn penalty anymore so this will break backward compatibility between profile version 3 and 4. |       - Remove dependency on turn types and turn modifier in the process_turn function in the `car.lua` profile. Guidance instruction types are not used to influence turn penalty anymore so this will break backward compatibility between profile version 3 and 4. | ||||||
|     - Bugfixes: |     - Bugfixes: | ||||||
|       - Fixed #4670: Fix bug where merge instructions got the wrong direction modifier |       - Fixed #4670: Fix bug where merge instructions got the wrong direction modifier | ||||||
|  |       - Properly use the `profile.properties.left_hand_driving` property, there was a typo that meant it had no effect | ||||||
| 
 | 
 | ||||||
| # 5.13.0 | # 5.13.0 | ||||||
|   - Changes from 5.12: |   - Changes from 5.12: | ||||||
|  | |||||||
							
								
								
									
										1748
									
								
								data/driving_side.geojson
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1748
									
								
								data/driving_side.geojson
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -594,6 +594,7 @@ step. | |||||||
| - `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. | ||||||
| - `rotary_pronunciation`: The pronunciation hint of the rotary name. Optionally included, if the step is a rotary and a rotary pronunciation is available. | - `rotary_pronunciation`: The pronunciation hint of the rotary name. Optionally included, if the step is a rotary and a rotary pronunciation is available. | ||||||
|  | - `driving_side`: The legal driving side at the location for this step.  Either `left` or `right`. | ||||||
| 
 | 
 | ||||||
| #### Example | #### Example | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ Feature: Testbot - side bias | |||||||
|     Scenario: Left-hand bias |     Scenario: Left-hand bias | ||||||
|         Given the profile file "car" initialized with |         Given the profile file "car" initialized with | ||||||
|         """ |         """ | ||||||
|         profile.left_hand_driving = true |         profile.properties.left_hand_driving = true | ||||||
|         profile.turn_bias = 1.075 |         profile.turn_bias = 1.075 | ||||||
|         """ |         """ | ||||||
|         And the node map |         And the node map | ||||||
| @ -20,14 +20,14 @@ Feature: Testbot - side bias | |||||||
|             | bd    | |             | bd    | | ||||||
| 
 | 
 | ||||||
|         When I route I should get |         When I route I should get | ||||||
|             | from | to | route    | time       | |             | from | to | route    | time       | driving_side   | | ||||||
|             | d    | a  | bd,ab,ab | 24s +-1    | |             | d    | a  | bd,ab,ab | 24s +-1    | left,left,left | | ||||||
|             | d    | c  | bd,bc,bc | 27s +-1    | |             | d    | c  | bd,bc,bc | 27s +-1    | left,left,left | | ||||||
| 
 | 
 | ||||||
|     Scenario: Right-hand bias |     Scenario: Right-hand bias | ||||||
|         Given the profile file "car" initialized with |         Given the profile file "car" initialized with | ||||||
|         """ |         """ | ||||||
|         profile.left_hand_driving = true |         profile.properties.left_hand_driving = true | ||||||
|         profile.turn_bias = 1 / 1.075 |         profile.turn_bias = 1 / 1.075 | ||||||
|         """ |         """ | ||||||
|         And the node map |         And the node map | ||||||
| @ -43,14 +43,14 @@ Feature: Testbot - side bias | |||||||
|             | bd    | |             | bd    | | ||||||
| 
 | 
 | ||||||
|         When I route I should get |         When I route I should get | ||||||
|             | from | to | route    | time    | #                                   | |             | from | to | route    | time    | driving_side   | #                                   | | ||||||
|             | d    | a  | bd,ab,ab | 27s +-1 | should be inverse of left hand bias | |             | d    | a  | bd,ab,ab | 27s +-1 | left,left,left | should be inverse of left hand bias | | ||||||
|             | d    | c  | bd,bc,bc | 24s +-1 |                                     | |             | d    | c  | bd,bc,bc | 24s +-1 | left,left,left |                                     | | ||||||
| 
 | 
 | ||||||
|     Scenario: Roundabout exit counting for left sided driving |     Scenario: Roundabout exit counting for left sided driving | ||||||
|         Given the profile file "testbot" initialized with |         Given the profile file "car" initialized with | ||||||
|         """ |         """ | ||||||
|         profile.left_hand_driving = true |         profile.properties.left_hand_driving = true | ||||||
|         """ |         """ | ||||||
|         And a grid size of 10 meters |         And a grid size of 10 meters | ||||||
|         And the node map |         And the node map | ||||||
| @ -70,10 +70,10 @@ Feature: Testbot - side bias | |||||||
|             | bcegb  | roundabout | |             | bcegb  | roundabout | | ||||||
| 
 | 
 | ||||||
|         When I route I should get |         When I route I should get | ||||||
|            | waypoints | route    | turns                                         | |            | waypoints | route    | driving_side   | turns                                         | | ||||||
|            | a,d       | ab,cd,cd | depart,roundabout turn left exit-1,arrive     | |            | a,d       | ab,cd,cd | left,left,left | depart,roundabout turn left exit-1,arrive     | | ||||||
|            | a,f       | ab,ef,ef | depart,roundabout turn straight exit-2,arrive | |            | a,f       | ab,ef,ef | left,left,left | depart,roundabout turn straight exit-2,arrive | | ||||||
|            | a,h       | ab,gh,gh | depart,roundabout turn right exit-3,arrive    | |            | a,h       | ab,gh,gh | left,left,left | depart,roundabout turn right exit-3,arrive    | | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     Scenario: Left-hand bias via location-dependent tags |     Scenario: Left-hand bias via location-dependent tags | ||||||
| @ -92,9 +92,9 @@ Feature: Testbot - side bias | |||||||
|         And the extract extra arguments "--location-dependent-data test/data/regions/null-island.geojson" |         And the extract extra arguments "--location-dependent-data test/data/regions/null-island.geojson" | ||||||
| 
 | 
 | ||||||
|         When I route I should get |         When I route I should get | ||||||
|             | from | to | route    | time       | |             | from | to | route    | driving_side   | time       | | ||||||
|             | d    | a  | bd,ab,ab | 24s +-1    | |             | d    | a  | bd,ab,ab | left,left,left | 24s +-1    | | ||||||
|             | d    | c  | bd,bc,bc | 27s +-1    | |             | d    | c  | bd,bc,bc | left,left,left | 27s +-1    | | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     Scenario: Left-hand bias via OSM tags |     Scenario: Left-hand bias via OSM tags | ||||||
| @ -113,6 +113,6 @@ Feature: Testbot - side bias | |||||||
|         And the extract extra arguments "--location-dependent-data test/data/regions/null-island.geojson" |         And the extract extra arguments "--location-dependent-data test/data/regions/null-island.geojson" | ||||||
| 
 | 
 | ||||||
|         When I route I should get |         When I route I should get | ||||||
|             | from | to | route    | time       | |             | from | to | route    | driving_side      | time       | | ||||||
|             | d    | a  | bd,ab,ab | 27s +-1    | |             | d    | a  | bd,ab,ab | right,right,right | 27s +-1    | | ||||||
|             | d    | c  | bd,bc,bc | 24s +-1    | |             | d    | c  | bd,bc,bc | right,right,right | 24s +-1    | | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ Feature: Basic Roundabout | |||||||
|         Given a grid size of 10 meters |         Given a grid size of 10 meters | ||||||
|         Given the profile file "car" initialized with |         Given the profile file "car" initialized with | ||||||
|             """ |             """ | ||||||
|             profile.left_hand_driving = true |             profile.properties.left_hand_driving = true | ||||||
|             """ |             """ | ||||||
| 
 | 
 | ||||||
|     Scenario: Roundabout exit counting for left sided driving |     Scenario: Roundabout exit counting for left sided driving | ||||||
|  | |||||||
| @ -267,6 +267,10 @@ module.exports = function () { | |||||||
|         return this.extractInstructionList(instructions, s => s.mode); |         return this.extractInstructionList(instructions, s => s.mode); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     this.drivingSideList = (instructions) => { | ||||||
|  |         return this.extractInstructionList(instructions, s => s.driving_side); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     this.classesList = (instructions) => { |     this.classesList = (instructions) => { | ||||||
|         return this.extractInstructionList(instructions, s => '[' + s.intersections.map(i => '(' + (i.classes ? i.classes.join(',') : '') + ')').join(',') + ']'); |         return this.extractInstructionList(instructions, s => '[' + s.intersections.map(i => '(' + (i.classes ? i.classes.join(',') : '') + ')').join(',') + ']'); | ||||||
|     }; |     }; | ||||||
|  | |||||||
| @ -35,7 +35,8 @@ module.exports = function () { | |||||||
|                     if (err) return cb(err); |                     if (err) return cb(err); | ||||||
|                     if (body && body.length) { |                     if (body && body.length) { | ||||||
|                         let destinations, exits, pronunciations, instructions, refs, bearings, turns, modes, times, classes, |                         let destinations, exits, pronunciations, instructions, refs, bearings, turns, modes, times, classes, | ||||||
|                             distances, summary, intersections, lanes, locations, annotation, weight_name, weights, approaches; |                             distances, summary, intersections, lanes, locations, annotation, weight_name, weights, approaches, | ||||||
|  |                             driving_sides; | ||||||
| 
 | 
 | ||||||
|                         let json = JSON.parse(body); |                         let json = JSON.parse(body); | ||||||
| 
 | 
 | ||||||
| @ -53,6 +54,7 @@ module.exports = function () { | |||||||
|                             turns = this.turnList(json.routes[0]); |                             turns = this.turnList(json.routes[0]); | ||||||
|                             intersections = this.intersectionList(json.routes[0]); |                             intersections = this.intersectionList(json.routes[0]); | ||||||
|                             modes = this.modeList(json.routes[0]); |                             modes = this.modeList(json.routes[0]); | ||||||
|  |                             driving_sides = this.drivingSideList(json.routes[0]); | ||||||
|                             classes = this.classesList(json.routes[0]); |                             classes = this.classesList(json.routes[0]); | ||||||
|                             times = this.timeList(json.routes[0]); |                             times = this.timeList(json.routes[0]); | ||||||
|                             distances = this.distanceList(json.routes[0]); |                             distances = this.distanceList(json.routes[0]); | ||||||
| @ -186,6 +188,10 @@ module.exports = function () { | |||||||
|                         putValue('weight', weight); |                         putValue('weight', weight); | ||||||
|                         putValue('approach', approaches); |                         putValue('approach', approaches); | ||||||
| 
 | 
 | ||||||
|  |                         if (driving_sides) { | ||||||
|  |                             putValue('driving_side', driving_sides); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|                         for (var key in row) { |                         for (var key in row) { | ||||||
|                             if (this.FuzzyMatch.match(got[key], row[key])) { |                             if (this.FuzzyMatch.match(got[key], row[key])) { | ||||||
|                                 got[key] = row[key]; |                                 got[key] = row[key]; | ||||||
|  | |||||||
| @ -141,7 +141,8 @@ 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}, | ||||||
|  |                                           path_point.is_left_hand_driving}); | ||||||
| 
 | 
 | ||||||
|                 if (leg_data_index + 1 < leg_data.size()) |                 if (leg_data_index + 1 < leg_data.size()) | ||||||
|                 { |                 { | ||||||
| @ -219,7 +220,8 @@ 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}, | ||||||
|  |                                   facade.IsLeftHandDriving(target_node_id)}); | ||||||
|     } |     } | ||||||
|     // 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 | ||||||
| @ -261,7 +263,8 @@ 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}, | ||||||
|  |                                   facade.IsLeftHandDriving(source_node_id)}); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     BOOST_ASSERT(segment_index == number_of_segments - 1); |     BOOST_ASSERT(segment_index == number_of_segments - 1); | ||||||
| @ -301,7 +304,8 @@ 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}, | ||||||
|  |                               facade.IsLeftHandDriving(source_node_id)}); | ||||||
| 
 | 
 | ||||||
|     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); | ||||||
|  | |||||||
| @ -76,6 +76,7 @@ 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; | ||||||
|  |     bool is_left_hand_driving; | ||||||
| 
 | 
 | ||||||
|     // 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).
 | ||||||
| @ -129,6 +130,7 @@ inline void RouteStep::Invalidate() | |||||||
|     geometry_end = 0; |     geometry_end = 0; | ||||||
|     intersections.clear(); |     intersections.clear(); | ||||||
|     intersections.push_back(getInvalidIntersection()); |     intersections.push_back(getInvalidIntersection()); | ||||||
|  |     is_left_hand_driving = false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Elongate by another step in front
 | // Elongate by another step in front
 | ||||||
|  | |||||||
| @ -57,6 +57,9 @@ struct PathData | |||||||
|     util::guidance::TurnBearing pre_turn_bearing; |     util::guidance::TurnBearing pre_turn_bearing; | ||||||
|     // bearing (as seen from the intersection) post-turn
 |     // bearing (as seen from the intersection) post-turn
 | ||||||
|     util::guidance::TurnBearing post_turn_bearing; |     util::guidance::TurnBearing post_turn_bearing; | ||||||
|  | 
 | ||||||
|  |     // Driving side of the turn
 | ||||||
|  |     bool is_left_hand_driving; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct InternalRouteResult | struct InternalRouteResult | ||||||
|  | |||||||
| @ -185,6 +185,8 @@ void annotatePath(const FacadeT &facade, | |||||||
|                               : 0); |                               : 0); | ||||||
|         const std::size_t end_index = weight_vector.size(); |         const std::size_t end_index = weight_vector.size(); | ||||||
| 
 | 
 | ||||||
|  |         bool is_left_hand_driving = facade.IsLeftHandDriving(node_id); | ||||||
|  | 
 | ||||||
|         BOOST_ASSERT(start_index >= 0); |         BOOST_ASSERT(start_index >= 0); | ||||||
|         BOOST_ASSERT(start_index < end_index); |         BOOST_ASSERT(start_index < end_index); | ||||||
|         for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx) |         for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx) | ||||||
| @ -202,7 +204,8 @@ void annotatePath(const FacadeT &facade, | |||||||
|                                              EMPTY_ENTRY_CLASS, |                                              EMPTY_ENTRY_CLASS, | ||||||
|                                              datasource_vector[segment_idx], |                                              datasource_vector[segment_idx], | ||||||
|                                              util::guidance::TurnBearing(0), |                                              util::guidance::TurnBearing(0), | ||||||
|                                              util::guidance::TurnBearing(0)}); |                                              util::guidance::TurnBearing(0), | ||||||
|  |                                              is_left_hand_driving}); | ||||||
|         } |         } | ||||||
|         BOOST_ASSERT(unpacked_path.size() > 0); |         BOOST_ASSERT(unpacked_path.size() > 0); | ||||||
|         if (facade.HasLaneData(turn_id)) |         if (facade.HasLaneData(turn_id)) | ||||||
| @ -254,6 +257,7 @@ void annotatePath(const FacadeT &facade, | |||||||
|     // t: fwd_segment 3
 |     // t: fwd_segment 3
 | ||||||
|     // -> (U, v), (v, w), (w, x)
 |     // -> (U, v), (v, w), (w, x)
 | ||||||
|     // note that (x, t) is _not_ included but needs to be added later.
 |     // note that (x, t) is _not_ included but needs to be added later.
 | ||||||
|  |     bool is_target_left_hand_driving = facade.IsLeftHandDriving(target_node_id); | ||||||
|     for (std::size_t segment_idx = start_index; segment_idx != end_index; |     for (std::size_t segment_idx = start_index; segment_idx != end_index; | ||||||
|          (start_index < end_index ? ++segment_idx : --segment_idx)) |          (start_index < end_index ? ++segment_idx : --segment_idx)) | ||||||
|     { |     { | ||||||
| @ -273,7 +277,8 @@ void annotatePath(const FacadeT &facade, | |||||||
|                      EMPTY_ENTRY_CLASS, |                      EMPTY_ENTRY_CLASS, | ||||||
|                      datasource_vector[segment_idx], |                      datasource_vector[segment_idx], | ||||||
|                      util::guidance::TurnBearing(0), |                      util::guidance::TurnBearing(0), | ||||||
|                      util::guidance::TurnBearing(0)}); |                      util::guidance::TurnBearing(0), | ||||||
|  |                      is_target_left_hand_driving}); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (unpacked_path.size() > 0) |     if (unpacked_path.size() > 0) | ||||||
|  | |||||||
| @ -563,7 +563,7 @@ function WayHandlers.driving_side(profile, way, result, data) | |||||||
|    elseif driving_side == 'right' then |    elseif driving_side == 'right' then | ||||||
|       result.is_left_hand_driving = false |       result.is_left_hand_driving = false | ||||||
|    else |    else | ||||||
|       result.is_left_hand_driving = profile.left_hand_driving |       result.is_left_hand_driving = profile.properties.left_hand_driving | ||||||
|    end |    end | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -195,6 +195,7 @@ util::json::Object makeRouteStep(guidance::RouteStep step, util::json::Value geo | |||||||
|     route_step.values["mode"] = extractor::travelModeToString(std::move(step.mode)); |     route_step.values["mode"] = extractor::travelModeToString(std::move(step.mode)); | ||||||
|     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); | ||||||
|  |     route_step.values["driving_side"] = step.is_left_hand_driving ? "left" : "right"; | ||||||
| 
 | 
 | ||||||
|     util::json::Array intersections; |     util::json::Array intersections; | ||||||
|     intersections.values.reserve(step.intersections.size()); |     intersections.values.reserve(step.intersections.size()); | ||||||
|  | |||||||
| @ -64,6 +64,7 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture) | |||||||
|                                                   {"geometry", "yw_jGupkl@??"}, |                                                   {"geometry", "yw_jGupkl@??"}, | ||||||
|                                                   {"name", "Boulevard du Larvotto"}, |                                                   {"name", "Boulevard du Larvotto"}, | ||||||
|                                                   {"mode", "driving"}, |                                                   {"mode", "driving"}, | ||||||
|  |                                                   {"driving_side", "right"}, | ||||||
|                                                   {"maneuver", |                                                   {"maneuver", | ||||||
|                                                    json::Object{{ |                                                    json::Object{{ | ||||||
|                                                        {"location", location}, |                                                        {"location", location}, | ||||||
| @ -84,6 +85,7 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture) | |||||||
|                                                  {"geometry", "yw_jGupkl@"}, |                                                  {"geometry", "yw_jGupkl@"}, | ||||||
|                                                  {"name", "Boulevard du Larvotto"}, |                                                  {"name", "Boulevard du Larvotto"}, | ||||||
|                                                  {"mode", "driving"}, |                                                  {"mode", "driving"}, | ||||||
|  |                                                  {"driving_side", "right"}, | ||||||
|                                                  {"maneuver", |                                                  {"maneuver", | ||||||
|                                                   json::Object{{{"location", location}, |                                                   json::Object{{{"location", location}, | ||||||
|                                                                 {"bearing_before", 58}, |                                                                 {"bearing_before", 58}, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user