diff --git a/CHANGELOG.md b/CHANGELOG.md index 5df2c71da..ea3961466 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Profiles - `restrictions` is now used for namespaced restrictions and restriction exceptions (e.g. `restriction:motorcar=` as well as `except=motorcar`) - replaced lhs/rhs profiles by using test defined profiles + - Handle `oneway=alternating` (routed over with penalty) separately from `oneway=reversible` (not routed over due to time dependence) - Guidance - Notifications are now exposed more prominently, announcing turns onto a ferry/pushing your bike more prominently - Trip Plugin diff --git a/features/car/oneway.feature b/features/car/oneway.feature index c9d0d4077..26e6f08e6 100644 --- a/features/car/oneway.feature +++ b/features/car/oneway.feature @@ -85,3 +85,12 @@ Feature: Car - Oneway streets When I route I should get | from | to | route | | a | c | ab,bc,bc | + + + # Reversible oneways (low frequency) vs alternating oneways (high frequency). + # See: https://github.com/Project-OSRM/osrm-backend/issues/2837 + Scenario: Car - Route over alternating but not reversible oneways + Then routability should be + | highway | oneway | forw | backw | + | primary | reversible | | | + | primary | alternating | x | x | diff --git a/features/car/speed.feature b/features/car/speed.feature index a81baeb85..08104af41 100644 --- a/features/car/speed.feature +++ b/features/car/speed.feature @@ -22,3 +22,16 @@ Feature: Car - speeds | residential | no | 31 km/h | | living_street | no | 18 km/h | | service | no | 23 km/h | + + # Alternating oneways have to take average waiting time into account. + Scenario: Car - scaled speeds for oneway=alternating + Then routability should be + | highway | oneway | junction | bothw | # | + | tertiary | | | 43 km/h | | + | tertiary | alternating | | 20 km/h +- 5 | | + | motorway | | | 82 km/h | implied oneway | + | motorway | alternating | | 30 km/h +- 5 | implied oneway | + | motorway | reversible | | | unroutable | + | primary | | roundabout | 63 km/h | implied oneway | + | primary | alternating | roundabout | 25 km/h +- 5 | implied oneway | + | primary | reversible | roundabout | | unroutable | diff --git a/profiles/car.lua b/profiles/car.lua index f56cf6c56..d97239f16 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -308,7 +308,9 @@ function way_function (way, result) return end - -- check if oneway tag is unsupported + -- Reversible oneways change direction with low frequency (think twice a day): + -- do not route over these at all at the moment because of time dependence. + -- Note: alternating (high frequency) oneways are handled below with penalty. local oneway = way:get_value_by_key("oneway") if oneway and "reversible" == oneway then return @@ -584,6 +586,18 @@ function way_function (way, result) result.backward_speed = math.min(penalized_speed, scaled_speed) end + -- Handle high frequency reversible oneways (think traffic signal controlled, changing direction every 15 minutes). + -- Scaling speed to take average waiting time into account plus some more for start / stop. + if oneway and "alternating" == oneway then + local scaling_factor = 0.4 + if result.forward_speed ~= math.huge then + result.forward_speed = result.forward_speed * scaling_factor + end + if result.backward_speed ~= math.huge then + result.backward_speed = result.backward_speed * scaling_factor + end + end + -- only allow this road as start point if it not a ferry result.is_startpoint = result.forward_mode == mode.driving or result.backward_mode == mode.driving end diff --git a/taginfo.json b/taginfo.json index ed64317c3..b03a8eb17 100644 --- a/taginfo.json +++ b/taginfo.json @@ -44,10 +44,16 @@ "value": "-1", "object_types": [ "way" ] }, + { + "key": "oneway", + "value": "alternating", + "description": "high frequency reversible oneways are routed over taking the waiting period into account", + "object_types": [ "way" ] + }, { "key": "oneway", "value": "reversible", - "description": "is marked as non-routable because of time-dependence", + "description": "low frequency reversible oneways are marked as non-routable because of time-dependence", "object_types": [ "way" ] }, {