diff --git a/features/car/access.feature b/features/car/access.feature index 15eb18aad30..6aec23da770 100644 --- a/features/car/access.feature +++ b/features/car/access.feature @@ -130,6 +130,15 @@ Feature: Car - Restricted access | delivery | x | | some_tag | x | | destination | x | + | permit | x | + | residents | x | + | foot | | + | restricted | | + | military | | + | official | | + | emergency_vehicle | | + | unknown | x | + | agricultural;forestry | | Scenario: Car - Access tags on nodes @@ -149,6 +158,39 @@ Feature: Car - Restricted access | bus | | | delivery | x | | some_tag | x | + | permit | x | + | residents | x | + | foot | | + | restricted | | + | military | | + | official | | + | emergency_vehicle | | + | unknown | x | + | agricultural;forestry | | + + Scenario: Car - Motorcar access tags on ways + Then routability should be + | motorcar | bothw | + | yes | x | + | permissive | x | + | designated | x | + | no | | + | private | x | + | agricultural | | + | forestry | | + | psv | | + | delivery | x | + | destination | x | + | permit | x | + | customers | x | + | residents | x | + | foot | | + | restricted | | + | military | | + | official | | + | emergency_vehicle | | + | unknown | x | + | agricultural;forestry | | Scenario: Car - Access tags on both node and way Then routability should be @@ -275,7 +317,25 @@ Feature: Car - Restricted access | primary | | no | destination | | x | | | primary | destination;agricultural | destination | | x | x | | | footway | | | destination | | | temporary #3373 | - | track | destination;agricultural | destination | | | x | temporary #3373 | + | track | destination;agricultural | destination | | | | temporary #3373 | + + Scenario: Car - Semicolon-separated access tags are split and resolved individually + Then routability should be + | highway | access | motorcar | bothw | # | + | primary | agricultural;forestry | | | access: both blacklisted | + | primary | destination;agricultural | | x | access: restricted wins over blacklisted | + | primary | yes;agricultural | | x | access: whitelisted wins over blacklisted | + | primary | yes;no | | x | access: whitelisted wins over blacklisted | + | primary | permissive;forestry | | x | access: whitelisted wins over blacklisted | + | primary | destination;delivery | | x | access: both restricted | + | primary | | agricultural;forestry | | motorcar: both blacklisted | + | primary | | destination;agricultural | x | motorcar: restricted wins over blacklisted | + | primary | | yes;agricultural | x | motorcar: whitelisted wins over blacklisted | + | primary | | yes;no | x | motorcar: whitelisted wins over blacklisted | + | primary | | permissive;forestry | x | motorcar: whitelisted wins over blacklisted | + | primary | | destination;delivery | x | motorcar: both restricted | + | primary | forestry;permissive | | x | access: whitelisted wins over blacklisted | + | primary | | forestry;permissive | x | motorcar: whitelisted wins over blacklisted | Scenario: Car - Don't route over steps even if marked as accessible Then routability should be @@ -305,14 +365,21 @@ Feature: Car - Restricted access Scenario: Car - Access blacklist Then routability should be - | highway | access | bothw | - | primary | | x | - | primary | emergency | | - | primary | forestry | | - | primary | agricultural | | - | primary | psv | | - | primary | no | | - | primary | customers | x | + | highway | access | bothw | + | primary | | x | + | primary | emergency | | + | primary | forestry | | + | primary | agricultural | | + | primary | agricultural;forestry| | + | primary | psv | | + | primary | no | | + | primary | foot | | + | primary | restricted | | + | primary | military | | + | primary | official | | + | primary | customers | x | + | primary | permit | x | + | primary | residents | x | Scenario: Car - Winter/ice roads with restricted access Then routability should be @@ -322,10 +389,12 @@ Feature: Car - Restricted access | winter_road| private | x | | winter_road| delivery | x | | winter_road| destination | x | + | winter_road| permit | x | | winter_road| no | | | ice_road | | x | | ice_road | yes | x | | ice_road | private | x | | ice_road | delivery | x | | ice_road | destination | x | + | ice_road | permit | x | | ice_road | no | | diff --git a/profiles/car.lua b/profiles/car.lua index 5efa2d1f1ea..441dcc824a6 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -8,6 +8,7 @@ Handlers = require("lib/way_handlers") Relations = require("lib/relations") Obstacles = require("lib/obstacles") find_access_tag = require("lib/access").find_access_tag +resolve_access = require("lib/access").resolve_access limit = require("lib/maxspeed").limit Utils = require("lib/utils") Measure = require("lib/measure") @@ -85,7 +86,8 @@ function setup() 'vehicle', 'permissive', 'designated', - 'hov' + 'hov', + 'unknown' }, access_tag_blacklist = Set { @@ -98,10 +100,17 @@ function setup() 'share_taxi', -- sub class of psv 'minibus', -- sub class of psv 'bus', -- sub class of psv + 'foot', + 'emergency_vehicle', + 'restricted', + 'military', + 'official', 'customers', 'private', 'delivery', - 'destination' + 'destination', + 'permit', + 'residents' }, -- tags disallow access to in combination with highway=service @@ -114,6 +123,8 @@ function setup() 'delivery', 'destination', 'customers', + 'permit', + 'residents', }, access_tags_hierarchy = Sequence { @@ -362,7 +373,7 @@ end function process_node(profile, node, result, relations) -- parse access and barrier tags - local access = find_access_tag(node, profile.access_tags_hierarchy) + local access = resolve_access(find_access_tag(node, profile.access_tags_hierarchy), profile) if access then if profile.access_tag_blacklist[access] and not profile.restricted_access_tag_list[access] then obstacle_map:add(node, Obstacle.new(obstacle_type.barrier)) diff --git a/profiles/lib/access.lua b/profiles/lib/access.lua index 678bd5c4b98..1538a791bcc 100644 --- a/profiles/lib/access.lua +++ b/profiles/lib/access.lua @@ -12,4 +12,30 @@ function Access.find_access_tag(source,access_tags_hierarchy) return nil end +function Access.classify_access(value, profile) + if profile.access_tag_whitelist[value] then return 3 end + if profile.restricted_access_tag_list[value] then return 2 end + if profile.access_tag_blacklist[value] then return 1 end + return 0 +end + +function Access.resolve_access(value, profile) + if not value then return nil end + if not value:find(';') then return value end + + local best = nil + local best_priority = -1 + + for part in value:gmatch('[^;]+') do + local trimmed = part:match('^%s*(.-)%s*$') + local priority = Access.classify_access(trimmed, profile) + if priority > best_priority then + best = trimmed + best_priority = priority + end + end + + return best or value +end + return Access diff --git a/profiles/lib/way_handlers.lua b/profiles/lib/way_handlers.lua index 4f07e25257d..769f9832c66 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 resolve_access = require("lib/access").resolve_access WayHandlers = {} @@ -260,6 +261,9 @@ 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) + data.forward_access = resolve_access(data.forward_access, profile) + data.backward_access = resolve_access(data.backward_access, profile) + -- 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 diff --git a/taginfo.json b/taginfo.json index d167106026c..7a837b49a41 100644 --- a/taginfo.json +++ b/taginfo.json @@ -157,6 +157,12 @@ {"key": "access", "value": "minibus"}, {"key": "access", "value": "bus"}, {"key": "access", "value": "delivery"}, + {"key": "access", "value": "permit"}, + {"key": "access", "value": "residents"}, + {"key": "access", "value": "foot"}, + {"key": "access", "value": "restricted"}, + {"key": "access", "value": "military"}, + {"key": "access", "value": "official"}, {"key": "maxheight", "object_types": ["node", "way"]}, {"key": "maxspeed", "value": "none"}, {"key": "maxspeed", "value": "urban"},