From f8f50dfa9a5d646e2133681e7a4a43a15a0170ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Masvie=20Brekk=C3=A5?= Date: Mon, 8 Jul 2024 15:41:07 +0200 Subject: [PATCH 1/7] Handle conditional access tags for time ranges --- profiles/lib/access_conditional.lua | 79 +++++++++++++++++++++++++++++ profiles/lib/way_handlers.lua | 8 +++ 2 files changed, 87 insertions(+) create mode 100644 profiles/lib/access_conditional.lua diff --git a/profiles/lib/access_conditional.lua b/profiles/lib/access_conditional.lua new file mode 100644 index 00000000000..08ae3094c33 --- /dev/null +++ b/profiles/lib/access_conditional.lua @@ -0,0 +1,79 @@ +-- 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 diff --git a/profiles/lib/way_handlers.lua b/profiles/lib/way_handlers.lua index b1341023509..e6fa2d6104c 100644 --- a/profiles/lib/way_handlers.lua +++ b/profiles/lib/way_handlers.lua @@ -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/access_conditional") WayHandlers = {} @@ -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 From 7bd6e87e7b4ff7dbdcea342abefbe6bf60f990bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Masvie=20Brekk=C3=A5?= Date: Tue, 9 Jul 2024 16:29:42 +0200 Subject: [PATCH 2/7] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4ba8226934..fcbbbbb36ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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: From 063dc2015fb9a5cf2af5cd90e61e6f75519e5b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Masvie=20Brekk=C3=A5?= Date: Tue, 9 Jul 2024 16:31:13 +0200 Subject: [PATCH 3/7] Add a few test cases --- features/car/access.feature | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/features/car/access.feature b/features/car/access.feature index 0bebd2589e0..4e3685f7259 100644 --- a/features/car/access.feature +++ b/features/car/access.feature @@ -305,3 +305,13 @@ Feature: Car - Restricted access | primary | psv | | | primary | no | | | primary | customers | x | + + Scenario: Car - Conditional restrictions + Then routability should be + | highway | motor_vehicle:conditional | bothw | + | primary | | x | + | primary | no @ 2002 Jan 7 - 2002 Feb 8 | | + | primary | no @ 2002 Jan 07 - 2002 Feb 08 | | + | primary | no @ 2020 Jan 7 - 2050 Feb 8 | x | + | primary | no @ foo - bar | x | + | primary | foo | x | From 323e58467b235eb126de3fc0aa3266f4eb934b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Masvie=20Brekk=C3=A5?= Date: Fri, 12 Jul 2024 10:09:34 +0200 Subject: [PATCH 4/7] Fix tests --- features/car/access.feature | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/features/car/access.feature b/features/car/access.feature index 4e3685f7259..d40af45fb05 100644 --- a/features/car/access.feature +++ b/features/car/access.feature @@ -308,10 +308,13 @@ Feature: Car - Restricted access Scenario: Car - Conditional restrictions Then routability should be - | highway | motor_vehicle:conditional | bothw | - | primary | | x | - | primary | no @ 2002 Jan 7 - 2002 Feb 8 | | - | primary | no @ 2002 Jan 07 - 2002 Feb 08 | | - | primary | no @ 2020 Jan 7 - 2050 Feb 8 | x | - | primary | no @ foo - bar | x | - | primary | foo | x | + | 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 | | + | 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 | \ No newline at end of file From a55b27fdd381d3f661e1ee20d29026d024c5832c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Masvie=20Brekk=C3=A5?= Date: Fri, 12 Jul 2024 10:16:19 +0200 Subject: [PATCH 5/7] Add newline at end of file --- features/car/access.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/car/access.feature b/features/car/access.feature index d40af45fb05..4d7f278f469 100644 --- a/features/car/access.feature +++ b/features/car/access.feature @@ -317,4 +317,4 @@ Feature: Car - Restricted access | 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 | \ No newline at end of file + | primary | yes | foo | x | From bf2ca0a4ee51b0c993039eda4b9e641c5fb5032e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Masvie=20Brekk=C3=A5?= Date: Sat, 13 Jul 2024 16:25:04 +0200 Subject: [PATCH 6/7] Rename access_conditional to conditional_access --- profiles/lib/{access_conditional.lua => conditional_access.lua} | 0 profiles/lib/way_handlers.lua | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename profiles/lib/{access_conditional.lua => conditional_access.lua} (100%) diff --git a/profiles/lib/access_conditional.lua b/profiles/lib/conditional_access.lua similarity index 100% rename from profiles/lib/access_conditional.lua rename to profiles/lib/conditional_access.lua diff --git a/profiles/lib/way_handlers.lua b/profiles/lib/way_handlers.lua index e6fa2d6104c..5b982d41106 100644 --- a/profiles/lib/way_handlers.lua +++ b/profiles/lib/way_handlers.lua @@ -9,7 +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/access_conditional") +local ConditionalAccess = require("lib/conditional_access") WayHandlers = {} From 8bcb9c22985a7bfdebd38ed8eb776ca764e717fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Masvie=20Brekk=C3=A5?= Date: Sat, 13 Jul 2024 16:34:11 +0200 Subject: [PATCH 7/7] Improve readability of example conditional tags --- profiles/lib/conditional_access.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/profiles/lib/conditional_access.lua b/profiles/lib/conditional_access.lua index 08ae3094c33..6a857c54f77 100644 --- a/profiles/lib/conditional_access.lua +++ b/profiles/lib/conditional_access.lua @@ -17,8 +17,9 @@ local function parse_conditional_access(way, key) return nil end - -- Examples of conditional tags: "no @ (2018 May 22-2018 Oct 7) - -- or "no @ 2018 Jun 01-2018 Jul 23" + -- 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