Add local left_hand_driving flag in API version 2

This commit is contained in:
Michael Krasnyk 2017-08-15 16:53:27 +02:00
parent af3f0a4782
commit de942155bf
11 changed files with 96 additions and 39 deletions

View File

@ -5,7 +5,7 @@ Feature: Testbot - side bias
Given the profile file "car" initialized with Given the profile file "car" initialized with
""" """
profile.left_hand_driving = true profile.left_hand_driving = true
profile.turn_bias = 1/1.075 profile.turn_bias = 1.075
""" """
Given the node map Given the node map
""" """
@ -28,7 +28,7 @@ Feature: Testbot - side bias
Given the profile file "car" initialized with Given the profile file "car" initialized with
""" """
profile.left_hand_driving = true profile.left_hand_driving = true
profile.turn_bias = 1.075 profile.turn_bias = 1 / 1.075
""" """
And the node map And the node map
""" """
@ -47,3 +47,31 @@ Feature: Testbot - side bias
| d | a | bd,ab,ab | 27s +-1 | | d | a | bd,ab,ab | 27s +-1 |
# should be inverse of left hand bias # should be inverse of left hand bias
| d | c | bd,bc,bc | 24s +-1 | | d | c | bd,bc,bc | 24s +-1 |
Scenario: Roundabout exit counting for left sided driving
Given the profile file "testbot" initialized with
"""
profile.left_hand_driving = true
"""
And a grid size of 10 meters
And the node map
"""
a
b
h g c d
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | roundabout |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout turn left exit-1,arrive |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive |
| a,h | ab,gh,gh | depart,roundabout turn right exit-3,arrive |

View File

@ -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.properties.left_hand_driving = true profile.left_hand_driving = true
""" """
Scenario: Roundabout exit counting for left sided driving Scenario: Roundabout exit counting for left sided driving

View File

@ -941,7 +941,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
bool IsLeftHandDriving() const override final bool IsLeftHandDriving() const override final
{ {
return m_profile_properties->left_hand_driving; return m_profile_properties->left_hand_driving; // TODO: remove
} }
}; };

View File

@ -14,19 +14,28 @@ namespace extractor
struct ExtractionTurn struct ExtractionTurn
{ {
ExtractionTurn(const guidance::ConnectedRoad &turn, bool has_traffic_light) ExtractionTurn(const guidance::ConnectedRoad &turn,
bool has_traffic_light,
bool source_restricted,
bool target_restricted,
bool is_left_hand_driving)
: angle(180. - turn.angle), turn_type(turn.instruction.type), : angle(180. - turn.angle), turn_type(turn.instruction.type),
direction_modifier(turn.instruction.direction_modifier), direction_modifier(turn.instruction.direction_modifier),
has_traffic_light(has_traffic_light), weight(0.), duration(0.), source_restricted(false), has_traffic_light(has_traffic_light), source_restricted(source_restricted),
target_restricted(false) target_restricted(target_restricted), is_left_hand_driving(is_left_hand_driving),
weight(0.), duration(0.)
{ {
} }
ExtractionTurn(const bool has_traffic_light = false) ExtractionTurn(bool has_traffic_light,
bool source_restricted,
bool target_restricted,
bool is_left_hand_driving)
: angle(0), turn_type(guidance::TurnType::NoTurn), : angle(0), turn_type(guidance::TurnType::NoTurn),
direction_modifier(guidance::DirectionModifier::Straight), direction_modifier(guidance::DirectionModifier::Straight),
has_traffic_light(has_traffic_light), weight(0.), duration(0.), source_restricted(false), has_traffic_light(has_traffic_light), source_restricted(source_restricted),
target_restricted(false) target_restricted(target_restricted), is_left_hand_driving(is_left_hand_driving),
weight(0.), duration(0.)
{ {
} }
@ -34,10 +43,12 @@ struct ExtractionTurn
const guidance::TurnType::Enum turn_type; const guidance::TurnType::Enum turn_type;
const guidance::DirectionModifier::Enum direction_modifier; const guidance::DirectionModifier::Enum direction_modifier;
const bool has_traffic_light; const bool has_traffic_light;
const bool source_restricted;
const bool target_restricted;
const bool is_left_hand_driving;
double weight; double weight;
double duration; double duration;
bool source_restricted;
bool target_restricted;
}; };
} }
} }

View File

@ -124,7 +124,7 @@ struct ProfileProperties
bool continue_straight_at_waypoint; bool continue_straight_at_waypoint;
//! flag used for restriction parser (e.g. used for the walk profile) //! flag used for restriction parser (e.g. used for the walk profile)
bool use_turn_restrictions; bool use_turn_restrictions;
bool left_hand_driving; bool left_hand_driving; // DEPRECATED: property value is local to edges from API version 2
bool fallback_to_duration; bool fallback_to_duration;
//! stores the name of the weight (e.g. 'duration', 'distance', 'safety') //! stores the name of the weight (e.g. 'duration', 'distance', 'safety')
char weight_name[MAX_WEIGHT_NAME_LENGTH + 1]; char weight_name[MAX_WEIGHT_NAME_LENGTH + 1];

View File

@ -9,11 +9,9 @@ find_access_tag = require("lib/access").find_access_tag
limit = require("lib/maxspeed").limit limit = require("lib/maxspeed").limit
function setup() function setup()
local use_left_hand_driving = false
return { return {
properties = { properties = {
max_speed_for_map_matching = 180/3.6, -- 180kmph -> m/s max_speed_for_map_matching = 180/3.6, -- 180kmph -> m/s
left_hand_driving = use_left_hand_driving,
-- For routing based on duration, but weighted for preferring certain roads -- For routing based on duration, but weighted for preferring certain roads
weight_name = 'routability', weight_name = 'routability',
-- For shortest duration without penalties for accessibility -- For shortest duration without penalties for accessibility
@ -27,16 +25,14 @@ function setup()
traffic_light_penalty = 2, traffic_light_penalty = 2,
}, },
left_hand_driving = false,
default_mode = mode.driving, default_mode = mode.driving,
default_speed = 10, default_speed = 10,
oneway_handling = true, oneway_handling = true,
side_road_multiplier = 0.8, side_road_multiplier = 0.8,
turn_penalty = 7.5, turn_penalty = 7.5,
speed_reduction = 0.8, speed_reduction = 0.8,
turn_bias = 1.075,
-- Note: this biases right-side driving.
-- Should be inverted for left-driving countries.
turn_bias = use_left_hand_driving and 1/1.075 or 1.075,
-- a list of suffixes to suppress in name change instructions -- a list of suffixes to suppress in name change instructions
suffix_list = { suffix_list = {
@ -307,7 +303,7 @@ function process_node(profile, node, result)
end end
end end
function process_way(profile, way, result) function process_way(profile, way, result, location_data)
-- the intial filtering of ways based on presence of tags -- the intial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways -- affects processing times significantly, because all ways
-- have to be checked. -- have to be checked.
@ -382,6 +378,7 @@ function process_way(profile, way, result)
-- handle various other flags -- handle various other flags
WayHandlers.roundabouts, WayHandlers.roundabouts,
WayHandlers.startpoint, WayHandlers.startpoint,
WayHandlers.driving_side,
-- set name, ref and pronunciation -- set name, ref and pronunciation
WayHandlers.names, WayHandlers.names,
@ -390,7 +387,7 @@ function process_way(profile, way, result)
WayHandlers.weights WayHandlers.weights
} }
WayHandlers.run(profile,way,result,data,handlers) WayHandlers.run(profile, way, result, data, handlers, location_data)
end end
function process_turn(profile, turn) function process_turn(profile, turn)
@ -398,7 +395,7 @@ function process_turn(profile, turn)
-- over the space of 0-180 degrees. Values here were chosen by fitting -- over the space of 0-180 degrees. Values here were chosen by fitting
-- the function to some turn penalty samples from real driving. -- the function to some turn penalty samples from real driving.
local turn_penalty = profile.turn_penalty local turn_penalty = profile.turn_penalty
local turn_bias = profile.turn_bias local turn_bias = turn.is_left_hand_driving and 1. / profile.turn_bias or profile.turn_bias
if turn.has_traffic_light then if turn.has_traffic_light then
turn.duration = profile.properties.traffic_light_penalty turn.duration = profile.properties.traffic_light_penalty

View File

@ -552,6 +552,20 @@ function WayHandlers.blocked_ways(profile,way,result,data)
end end
end end
function WayHandlers.driving_side(profile, way, result, data, location_data)
local driving_side = way:get_value_by_key("driving_side")
if driving_side == 'left' then
result.is_left_hand_driving = true
elseif driving_side == 'right' then
result.is_left_hand_driving = false
elseif location_data then
result.is_left_hand_driving = location_data['driving_side'] == 'left'
elseif profile.left_hand_driving then
result.is_left_hand_driving = true
end
end
-- Call a sequence of handlers, aborting in case a handler returns false. Example: -- Call a sequence of handlers, aborting in case a handler returns false. Example:
-- --
-- handlers = Sequence { -- handlers = Sequence {
@ -566,13 +580,13 @@ end
-- WayHandlers.run(handlers,way,result,data,profile) -- WayHandlers.run(handlers,way,result,data,profile)
-- --
-- Each method in the list will be called on the WayHandlers object. -- Each method in the list will be called on the WayHandlers object.
-- All handlers must accept the parameteres (profile,way,result,data) and return false -- All handlers must accept the parameteres (profile, way, result, data[, location_data]) and return false
-- if the handler chain should be aborted. -- if the handler chain should be aborted.
-- To ensure the correct order of method calls, use a Sequence of handler names. -- To ensure the correct order of method calls, use a Sequence of handler names.
function WayHandlers.run(profile,way,result,data,handlers) function WayHandlers.run(profile, way, result, data, handlers, location_data)
for i,handler in ipairs(handlers) do for i,handler in ipairs(handlers) do
if handler(profile,way,result,data) == false then if handler(profile, way, result, data, location_data) == false then
return false return false
end end
end end

View File

@ -578,9 +578,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
// compute weight and duration penalties // compute weight and duration penalties
auto is_traffic_light = m_traffic_lights.count(node_at_center_of_intersection); auto is_traffic_light = m_traffic_lights.count(node_at_center_of_intersection);
ExtractionTurn extracted_turn(turn, is_traffic_light); ExtractionTurn extracted_turn(turn,
extracted_turn.source_restricted = edge_data1.restricted; is_traffic_light,
extracted_turn.target_restricted = edge_data2.restricted; edge_data1.restricted,
edge_data2.restricted,
edge_data1.is_left_hand_driving);
scripting_environment.ProcessTurn(extracted_turn); scripting_environment.ProcessTurn(extracted_turn);
// turn penalties are limited to [-2^15, 2^15) which roughly // turn penalties are limited to [-2^15, 2^15) which roughly

View File

@ -205,16 +205,16 @@ void GraphCompressor::Compress(
boost::optional<EdgeWeight> node_weight_penalty = boost::none; boost::optional<EdgeWeight> node_weight_penalty = boost::none;
if (has_node_penalty) if (has_node_penalty)
{ {
// generate an artifical turn for the turn penalty generation
ExtractionTurn extraction_turn(true);
extraction_turn.source_restricted = fwd_edge_data1.restricted;
extraction_turn.target_restricted = fwd_edge_data2.restricted;
// we cannot handle this as node penalty, if it depends on turn direction // we cannot handle this as node penalty, if it depends on turn direction
if (extraction_turn.source_restricted != extraction_turn.target_restricted) if (fwd_edge_data1.restricted != fwd_edge_data2.restricted)
continue; continue;
// generate an artifical turn for the turn penalty generation
ExtractionTurn extraction_turn(true,
fwd_edge_data1.restricted,
fwd_edge_data2.restricted,
fwd_edge_data1.is_left_hand_driving);
scripting_environment.ProcessTurn(extraction_turn); scripting_environment.ProcessTurn(extraction_turn);
node_duration_penalty = extraction_turn.duration * 10; node_duration_penalty = extraction_turn.duration * 10;
node_weight_penalty = extraction_turn.weight * weight_multiplier; node_weight_penalty = extraction_turn.weight * weight_multiplier;

View File

@ -74,7 +74,7 @@ detail::RoundaboutFlags RoundaboutHandler::getRoundaboutFlags(
bool can_enter_roundabout = false; bool can_enter_roundabout = false;
bool can_exit_roundabout_separately = false; bool can_exit_roundabout_separately = false;
const bool lhs = profile_properties.left_hand_driving; const bool lhs = in_edge_data.is_left_hand_driving;
const int step = lhs ? -1 : 1; const int step = lhs ? -1 : 1;
for (std::size_t cnt = 0, idx = lhs ? intersection.size() - 1 : 0; cnt < intersection.size(); for (std::size_t cnt = 0, idx = lhs ? intersection.size() - 1 : 0; cnt < intersection.size();
++cnt, idx += step) ++cnt, idx += step)
@ -433,8 +433,9 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
Intersection intersection) const Intersection intersection) const
{ {
NodeID node_at_center_of_intersection = node_based_graph.GetTarget(via_eid); NodeID node_at_center_of_intersection = node_based_graph.GetTarget(via_eid);
const auto &in_edge_data = node_based_graph.GetEdgeData(via_eid);
const bool lhs = profile_properties.left_hand_driving; const bool lhs = in_edge_data.is_left_hand_driving;
const int step = lhs ? -1 : 1; const int step = lhs ? -1 : 1;
if (on_roundabout) if (on_roundabout)

View File

@ -237,7 +237,7 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"interpolate", "interpolate",
&RasterContainer::GetRasterInterpolateFromSource); &RasterContainer::GetRasterInterpolateFromSource);
context.state.new_usertype<ProfileProperties>( auto registration_ProfileProperties = context.state.new_usertype<ProfileProperties>(
"ProfileProperties", "ProfileProperties",
"traffic_signal_penalty", "traffic_signal_penalty",
sol::property(&ProfileProperties::GetTrafficSignalPenalty, sol::property(&ProfileProperties::GetTrafficSignalPenalty,
@ -446,7 +446,9 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"source_restricted", "source_restricted",
&ExtractionTurn::source_restricted, &ExtractionTurn::source_restricted,
"target_restricted", "target_restricted",
&ExtractionTurn::target_restricted); &ExtractionTurn::target_restricted,
"is_left_hand_driving",
&ExtractionTurn::is_left_hand_driving);
// Keep in mind .location is available only if .pbf is preprocessed to set the location with the // Keep in mind .location is available only if .pbf is preprocessed to set the location with the
// ref using osmium command "osmium add-locations-to-ways" // ref using osmium command "osmium add-locations-to-ways"
@ -580,6 +582,7 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
if (use_turn_restrictions != sol::nullopt) if (use_turn_restrictions != sol::nullopt)
context.properties.use_turn_restrictions = use_turn_restrictions.value(); context.properties.use_turn_restrictions = use_turn_restrictions.value();
// DEPRECATED: global left_hand_driving will be removed in the next profile API
sol::optional<bool> left_hand_driving = properties["left_hand_driving"]; sol::optional<bool> left_hand_driving = properties["left_hand_driving"];
if (left_hand_driving != sol::nullopt) if (left_hand_driving != sol::nullopt)
context.properties.left_hand_driving = left_hand_driving.value(); context.properties.left_hand_driving = left_hand_driving.value();
@ -992,6 +995,7 @@ void LuaScriptingContext::ProcessWay(const osmium::Way &way,
case 1: case 1:
case 0: case 0:
way_function(way, result); way_function(way, result);
result.is_left_hand_driving = properties.left_hand_driving;
break; break;
} }
} }