From bbbbacb073fabe66cdae74beb5b073745bed85ca Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Fri, 9 Sep 2016 12:34:04 +0200 Subject: [PATCH] Reworks Restriction Whitelist / Blacklist, resolves #2833 Takes a stricter aproach for whitelisting / blacklisting restrictions: - uses `restriction=` - uses more specific `restriction:=` - uses `except=` to invert Where `type` is the type of transportation to restrict, e.g. `motorcar`. https://github.com/Project-OSRM/osrm-backend/issues/2833 --- CHANGELOG.md | 3 +- include/extractor/restriction_parser.hpp | 4 +- include/extractor/scripting_environment.hpp | 2 +- .../extractor/scripting_environment_lua.hpp | 2 +- profiles/bicycle.lua | 6 +-- profiles/car.lua | 6 +-- profiles/foot.lua | 6 +-- src/extractor/restriction_parser.cpp | 49 +++++++------------ src/extractor/scripting_environment_lua.cpp | 11 ++--- 9 files changed, 38 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f94f9a77..ede390c4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 5.5.0 - - Changes from 5.4.0 + Changes from 5.4.0 - 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 # 5.4.0 diff --git a/include/extractor/restriction_parser.hpp b/include/extractor/restriction_parser.hpp index c5eede2f8..732affc1f 100644 --- a/include/extractor/restriction_parser.hpp +++ b/include/extractor/restriction_parser.hpp @@ -29,7 +29,7 @@ class ScriptingEnvironment; * * While this class does not directly invoke any lua code _per relation_ it does * load configuration values from the profile, that are saved in variables. - * Namely ```use_turn_restrictions``` and ```get_exceptions```. + * Namely ```use_turn_restrictions``` and ```get_restrictions```. * * The restriction is represented by the osm id of the from way, the osm id of the * to way and the osm id of the via node. This representation must be post-processed @@ -47,7 +47,7 @@ class RestrictionParser private: bool ShouldIgnoreRestriction(const std::string &except_tag_string) const; - std::vector restriction_exceptions; + std::vector restrictions; bool use_turn_restrictions; }; } diff --git a/include/extractor/scripting_environment.hpp b/include/extractor/scripting_environment.hpp index a450b3154..d7f3bd4f9 100644 --- a/include/extractor/scripting_environment.hpp +++ b/include/extractor/scripting_environment.hpp @@ -51,7 +51,7 @@ class ScriptingEnvironment virtual const ProfileProperties &GetProfileProperties() = 0; virtual std::vector GetNameSuffixList() = 0; - virtual std::vector GetExceptions() = 0; + virtual std::vector GetRestrictions() = 0; virtual void SetupSources() = 0; virtual int32_t GetTurnPenalty(double angle) = 0; virtual void ProcessSegment(const osrm::util::Coordinate &source, diff --git a/include/extractor/scripting_environment_lua.hpp b/include/extractor/scripting_environment_lua.hpp index c55a4b67c..b82fafb8c 100644 --- a/include/extractor/scripting_environment_lua.hpp +++ b/include/extractor/scripting_environment_lua.hpp @@ -53,7 +53,7 @@ class LuaScriptingEnvironment final : public ScriptingEnvironment LuaScriptingContext &GetLuaContext(); std::vector GetNameSuffixList() override; - std::vector GetExceptions() override; + std::vector GetRestrictions() override; void SetupSources() override; int32_t GetTurnPenalty(double angle) override; void ProcessSegment(const osrm::util::Coordinate &source, diff --git a/profiles/bicycle.lua b/profiles/bicycle.lua index 7bcc65ef7..9e68365e8 100644 --- a/profiles/bicycle.lua +++ b/profiles/bicycle.lua @@ -12,7 +12,7 @@ access_tag_restricted = { ["destination"] = true, ["delivery"] = true } access_tags_hierarchy = { "bicycle", "vehicle", "access" } cycleway_tags = {["track"]=true,["lane"]=true,["opposite"]=true,["opposite_lane"]=true,["opposite_track"]=true,["share_busway"]=true,["sharrow"]=true,["shared"]=true } service_tag_restricted = { ["parking_aisle"] = true } -restriction_exception_tags = { "bicycle", "vehicle", "access" } +restrictions = { "bicycle" } unsafe_highway_list = { ["primary"] = true, ["secondary"] = true, ["tertiary"] = true, ["primary_link"] = true, ["secondary_link"] = true, ["tertiary_link"] = true} local default_speed = 15 @@ -121,8 +121,8 @@ local function parse_maxspeed(source) return n end -function get_exceptions(vector) - for i,v in ipairs(restriction_exception_tags) do +function get_restrictions(vector) + for i,v in ipairs(restrictions) do vector:Add(v) end end diff --git a/profiles/car.lua b/profiles/car.lua index 3fd872083..f56cf6c56 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -12,7 +12,7 @@ access_tag_restricted = { ["destination"] = true, ["delivery"] = true } access_tags_hierarchy = { "motorcar", "motor_vehicle", "vehicle", "access" } service_tag_restricted = { ["parking_aisle"] = true } service_tag_forbidden = { ["emergency_access"] = true } -restriction_exception_tags = { "motorcar", "motor_vehicle", "vehicle" } +restrictions = { "motorcar", "motor_vehicle", "vehicle" } -- A list of suffixes to suppress in name change instructions suffix_list = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "North", "South", "West", "East" } @@ -172,8 +172,8 @@ function get_name_suffix_list(vector) end end -function get_exceptions(vector) - for i,v in ipairs(restriction_exception_tags) do +function get_restrictions(vector) + for i,v in ipairs(restrictions) do vector:Add(v) end end diff --git a/profiles/foot.lua b/profiles/foot.lua index 25ed19fd1..cf9c8f5d8 100644 --- a/profiles/foot.lua +++ b/profiles/foot.lua @@ -10,7 +10,7 @@ access_tag_restricted = { ["destination"] = true, ["delivery"] = true } access_tags_hierarchy = { "foot", "access" } service_tag_restricted = { ["parking_aisle"] = true } ignore_in_grid = { ["ferry"] = true } -restriction_exception_tags = { "foot" } +restrictions = { "foot" } walking_speed = 5 @@ -71,8 +71,8 @@ properties.continue_straight_at_waypoint = false local fallback_names = true -function get_exceptions(vector) - for i,v in ipairs(restriction_exception_tags) do +function get_restrictions(vector) + for i,v in ipairs(restrictions) do vector:Add(v) end end diff --git a/src/extractor/restriction_parser.cpp b/src/extractor/restriction_parser.cpp index 23e176f9b..7c466a536 100644 --- a/src/extractor/restriction_parser.cpp +++ b/src/extractor/restriction_parser.cpp @@ -29,20 +29,19 @@ RestrictionParser::RestrictionParser(ScriptingEnvironment &scripting_environment { if (use_turn_restrictions) { - restriction_exceptions = scripting_environment.GetExceptions(); - const unsigned exception_count = restriction_exceptions.size(); - if (exception_count) + restrictions = scripting_environment.GetRestrictions(); + const unsigned count = restrictions.size(); + if (count > 0) { - util::SimpleLogger().Write() << "Found " << exception_count - << " exceptions to turn restrictions:"; - for (const std::string &str : restriction_exceptions) + util::SimpleLogger().Write() << "Found " << count << " turn restriction tags:"; + for (const std::string &str : restrictions) { util::SimpleLogger().Write() << " " << str; } } else { - util::SimpleLogger().Write() << "Found no exceptions to turn restrictions"; + util::SimpleLogger().Write() << "Found no turn restriction tags"; } } } @@ -51,8 +50,9 @@ RestrictionParser::RestrictionParser(ScriptingEnvironment &scripting_environment * Tries to parse a relation as a turn restriction. This can fail for a number of * reasons. The return type is a boost::optional. * - * Some restrictions can also be ignored: See the ```get_exceptions``` function - * in the corresponding profile. + * Some restrictions can also be ignored: See the ```get_restrictions``` function + * in the corresponding profile. We use it for both namespacing restrictions, as in + * restriction:motorcar as well as whitelisting if its in except:motorcar. */ boost::optional RestrictionParser::TryParse(const osmium::Relation &relation) const @@ -63,13 +63,17 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const return {}; } - osmium::tags::KeyPrefixFilter filter(false); + osmium::tags::KeyFilter filter(false); filter.add(true, "restriction"); + // Not only use restriction= but also e.g. restriction:motorcar= + for (const auto &namespaced : restrictions) + filter.add(true, "restriction:" + namespaced); + const osmium::TagList &tag_list = relation.tags(); - osmium::tags::KeyPrefixFilter::iterator fi_begin(filter, tag_list.begin(), tag_list.end()); - osmium::tags::KeyPrefixFilter::iterator fi_end(filter, tag_list.end(), tag_list.end()); + osmium::tags::KeyFilter::iterator fi_begin(filter, tag_list.begin(), tag_list.end()); + osmium::tags::KeyFilter::iterator fi_end(filter, tag_list.end(), tag_list.end()); // if it's not a restriction, continue; if (std::distance(fi_begin, fi_end) == 0) @@ -105,22 +109,6 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const { return {}; } - - // if the "restriction*" key is longer than 11 chars, it is a conditional exception (i.e. - // "restriction:") - if (key.size() > 11) - { - const auto ex_suffix = [&](const std::string &exception) { - return boost::algorithm::ends_with(key, exception); - }; - bool is_actually_restricted = - std::any_of(begin(restriction_exceptions), end(restriction_exceptions), ex_suffix); - - if (!is_actually_restricted) - { - return {}; - } - } } InputRestrictionContainer restriction_container(is_only_restriction); @@ -195,9 +183,8 @@ bool RestrictionParser::ShouldIgnoreRestriction(const std::string &except_tag_st return std::any_of( std::begin(exceptions), std::end(exceptions), [&](const std::string ¤t_string) { - return std::end(restriction_exceptions) != std::find(std::begin(restriction_exceptions), - std::end(restriction_exceptions), - current_string); + return std::end(restrictions) != + std::find(std::begin(restrictions), std::end(restrictions), current_string); }); } } diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index b0aadf97e..6452d775a 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -327,18 +327,17 @@ std::vector LuaScriptingEnvironment::GetNameSuffixList() return suffixes_vector; } -std::vector LuaScriptingEnvironment::GetExceptions() +std::vector LuaScriptingEnvironment::GetRestrictions() { auto &context = GetLuaContext(); BOOST_ASSERT(context.state != nullptr); - std::vector restriction_exceptions; - if (util::luaFunctionExists(context.state, "get_exceptions")) + std::vector restrictions; + if (util::luaFunctionExists(context.state, "get_restrictions")) { // get list of turn restriction exceptions - luabind::call_function( - context.state, "get_exceptions", boost::ref(restriction_exceptions)); + luabind::call_function(context.state, "get_restrictions", boost::ref(restrictions)); } - return restriction_exceptions; + return restrictions; } void LuaScriptingEnvironment::SetupSources()