Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle conditional access tags for date ranges #6984

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
- FIXED: Ensure required file check in osrm-routed is correctly enforced. [#6655](https://github.com/Project-OSRM/osrm-backend/pull/6655)
- FIXED: Correct HTTP docs to reflect summary output dependency on steps parameter. [#6655](https://github.com/Project-OSRM/osrm-backend/pull/6655)
- ADDED: Extract prerelease/build information from package semver [#6839](https://github.com/Project-OSRM/osrm-backend/pull/6839)
- ADDED: Handle conditional access tags for date ranges [#6984](https://github.com/Project-OSRM/osrm-backend/pull/6984)
- Profiles:
- FIXED: Bicycle and foot profiles now don't route on proposed ways [#6615](https://github.com/Project-OSRM/osrm-backend/pull/6615)
- Routing:
Expand Down
13 changes: 13 additions & 0 deletions features/car/access.feature
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,16 @@ Feature: Car - Restricted access
| primary | psv | |
| primary | no | |
| primary | customers | x |

Scenario: Car - Conditional restrictions
Then routability should be
| highway | motor_vehicle | motor_vehicle:conditional | bothw |
| primary | yes | | x |
| primary | yes | no @ 2002 Jan 7 - 2002 Feb 8 | x |
| primary | yes | no @ 2002 Jan 07 - 2002 Feb 08 | x |
| primary | yes | no @ 2090 Jan 7 - 2100 Feb 8 | x |
| primary | yes | no @ 2020 Jan 7 - 2050 Feb 8 | |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this test break in 24 years? 😉

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep 😄 I can extend the ranges so they don't break that soon, but I don't see any simple way to get completely rid of this problem.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this can be solved doing something similar to this. I'll try to do that.

| primary | yes | no @ 2020 Jan 07 - 2050 Feb 08 | |
| primary | yes | no @ (2020 Jan 7 - 2050 Feb 8) | |
| primary | yes | no @ foo - bar | x |
| primary | yes | foo | x |
80 changes: 80 additions & 0 deletions profiles/lib/conditional_access.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
-- Handle conditional access tags as described in the OSM wiki:
-- https://wiki.openstreetmap.org/wiki/Conditional_restrictions

-- Note that we only handle conditional tags for a date range,
-- meant to be used for temporary restrictions, typically due to
-- construction. We also require the date range to be at least a
-- week long



ConditionalAccess = {}


local function parse_conditional_access(way, key)
local conditional = way:get_value_by_key(key .. ':conditional')
if not conditional then
return nil
end

-- Examples of conditional tags:
-- "no @ (2018 May 22-2018 Oct 7)" or
-- "no @ 2018 Jun 01 - 2018 Jul 23"
local condition, time_range = conditional:match("([^@]+)@(.+)")
if not condition or not time_range then
return nil
end

local start_date_str, end_date_str = time_range:match("([^-]+)-(.+)")
if not start_date_str or not end_date_str then
return nil
end

local function parse_date(date_str)
local year, month, day = date_str:match("(%d+)%s+(%a+)%s+(%d+)")

local month_names = {
Jan = 1, Feb = 2, Mar = 3, Apr = 4, May = 5, Jun = 6,
Jul = 7, Aug = 8, Sep = 9, Oct = 10, Nov = 11, Dec = 12
}
month = month_names[month]
if not year or not month or not day then
return nil
end

local numericYear = tonumber(year)
local numericDay = tonumber(day)
if numericYear and numericDay then
return os.time({ year = numericYear, month = month, day = numericDay })
else
return nil
end
end

local start_date = parse_date(start_date_str)
local end_date = parse_date(end_date_str)
local current_date = os.time()

-- Require start and end date to be more than a week apart
if not start_date or not end_date or end_date - start_date < 60 * 60 * 24 * 7 then
return nil
end

if current_date >= start_date and current_date <= end_date then
return condition:match("%S+")
else
return nil
end
end

function ConditionalAccess.parse_by_set(way, keys)
for i, key in ipairs(keys) do
local conditional = parse_conditional_access(way, key)
if conditional then
return conditional
end
end
return nil
end

return ConditionalAccess
8 changes: 8 additions & 0 deletions profiles/lib/way_handlers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local set_classification = require("lib/guidance").set_classification
local get_destination = require("lib/destination").get_destination
local Tags = require('lib/tags')
local Measure = require("lib/measure")
local ConditionalAccess = require("lib/conditional_access")

WayHandlers = {}

Expand Down Expand Up @@ -243,6 +244,13 @@ function WayHandlers.access(profile,way,result,data)
data.forward_access, data.backward_access =
Tags.get_forward_backward_by_set(way,data,profile.access_tags_hierarchy)

-- check for conditional access (roads that are temporarily closed, etc.)
local conditional = ConditionalAccess.parse_by_set(way,profile.access_tags_hierarchy)
if conditional then
data.forward_access = conditional
data.backward_access = conditional
end

-- only allow a subset of roads to be treated as restricted
if profile.restricted_highway_whitelist[data.highway] then
if profile.restricted_access_tag_list[data.forward_access] then
Expand Down
Loading