Reworks Restriction Whitelist / Blacklist, resolves #2833
Takes a stricter aproach for whitelisting / blacklisting restrictions: - uses `restriction=` - uses more specific `restriction:<type>=` - uses `except=<type>` to invert Where `type` is the type of transportation to restrict, e.g. `motorcar`. https://github.com/Project-OSRM/osrm-backend/issues/2833
This commit is contained in:
parent
e7b2f85a20
commit
bbbbacb073
@ -1,6 +1,7 @@
|
|||||||
# 5.5.0
|
# 5.5.0
|
||||||
- Changes from 5.4.0
|
Changes from 5.4.0
|
||||||
- Profiles
|
- 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
|
- replaced lhs/rhs profiles by using test defined profiles
|
||||||
|
|
||||||
# 5.4.0
|
# 5.4.0
|
||||||
|
@ -29,7 +29,7 @@ class ScriptingEnvironment;
|
|||||||
*
|
*
|
||||||
* While this class does not directly invoke any lua code _per relation_ it does
|
* 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.
|
* 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
|
* 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
|
* to way and the osm id of the via node. This representation must be post-processed
|
||||||
@ -47,7 +47,7 @@ class RestrictionParser
|
|||||||
private:
|
private:
|
||||||
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
|
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
|
||||||
|
|
||||||
std::vector<std::string> restriction_exceptions;
|
std::vector<std::string> restrictions;
|
||||||
bool use_turn_restrictions;
|
bool use_turn_restrictions;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ class ScriptingEnvironment
|
|||||||
virtual const ProfileProperties &GetProfileProperties() = 0;
|
virtual const ProfileProperties &GetProfileProperties() = 0;
|
||||||
|
|
||||||
virtual std::vector<std::string> GetNameSuffixList() = 0;
|
virtual std::vector<std::string> GetNameSuffixList() = 0;
|
||||||
virtual std::vector<std::string> GetExceptions() = 0;
|
virtual std::vector<std::string> GetRestrictions() = 0;
|
||||||
virtual void SetupSources() = 0;
|
virtual void SetupSources() = 0;
|
||||||
virtual int32_t GetTurnPenalty(double angle) = 0;
|
virtual int32_t GetTurnPenalty(double angle) = 0;
|
||||||
virtual void ProcessSegment(const osrm::util::Coordinate &source,
|
virtual void ProcessSegment(const osrm::util::Coordinate &source,
|
||||||
|
@ -53,7 +53,7 @@ class LuaScriptingEnvironment final : public ScriptingEnvironment
|
|||||||
LuaScriptingContext &GetLuaContext();
|
LuaScriptingContext &GetLuaContext();
|
||||||
|
|
||||||
std::vector<std::string> GetNameSuffixList() override;
|
std::vector<std::string> GetNameSuffixList() override;
|
||||||
std::vector<std::string> GetExceptions() override;
|
std::vector<std::string> GetRestrictions() override;
|
||||||
void SetupSources() override;
|
void SetupSources() override;
|
||||||
int32_t GetTurnPenalty(double angle) override;
|
int32_t GetTurnPenalty(double angle) override;
|
||||||
void ProcessSegment(const osrm::util::Coordinate &source,
|
void ProcessSegment(const osrm::util::Coordinate &source,
|
||||||
|
@ -12,7 +12,7 @@ access_tag_restricted = { ["destination"] = true, ["delivery"] = true }
|
|||||||
access_tags_hierarchy = { "bicycle", "vehicle", "access" }
|
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 }
|
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 }
|
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}
|
unsafe_highway_list = { ["primary"] = true, ["secondary"] = true, ["tertiary"] = true, ["primary_link"] = true, ["secondary_link"] = true, ["tertiary_link"] = true}
|
||||||
|
|
||||||
local default_speed = 15
|
local default_speed = 15
|
||||||
@ -121,8 +121,8 @@ local function parse_maxspeed(source)
|
|||||||
return n
|
return n
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_exceptions(vector)
|
function get_restrictions(vector)
|
||||||
for i,v in ipairs(restriction_exception_tags) do
|
for i,v in ipairs(restrictions) do
|
||||||
vector:Add(v)
|
vector:Add(v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -12,7 +12,7 @@ access_tag_restricted = { ["destination"] = true, ["delivery"] = true }
|
|||||||
access_tags_hierarchy = { "motorcar", "motor_vehicle", "vehicle", "access" }
|
access_tags_hierarchy = { "motorcar", "motor_vehicle", "vehicle", "access" }
|
||||||
service_tag_restricted = { ["parking_aisle"] = true }
|
service_tag_restricted = { ["parking_aisle"] = true }
|
||||||
service_tag_forbidden = { ["emergency_access"] = 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
|
-- A list of suffixes to suppress in name change instructions
|
||||||
suffix_list = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "North", "South", "West", "East" }
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_exceptions(vector)
|
function get_restrictions(vector)
|
||||||
for i,v in ipairs(restriction_exception_tags) do
|
for i,v in ipairs(restrictions) do
|
||||||
vector:Add(v)
|
vector:Add(v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -10,7 +10,7 @@ access_tag_restricted = { ["destination"] = true, ["delivery"] = true }
|
|||||||
access_tags_hierarchy = { "foot", "access" }
|
access_tags_hierarchy = { "foot", "access" }
|
||||||
service_tag_restricted = { ["parking_aisle"] = true }
|
service_tag_restricted = { ["parking_aisle"] = true }
|
||||||
ignore_in_grid = { ["ferry"] = true }
|
ignore_in_grid = { ["ferry"] = true }
|
||||||
restriction_exception_tags = { "foot" }
|
restrictions = { "foot" }
|
||||||
|
|
||||||
walking_speed = 5
|
walking_speed = 5
|
||||||
|
|
||||||
@ -71,8 +71,8 @@ properties.continue_straight_at_waypoint = false
|
|||||||
|
|
||||||
local fallback_names = true
|
local fallback_names = true
|
||||||
|
|
||||||
function get_exceptions(vector)
|
function get_restrictions(vector)
|
||||||
for i,v in ipairs(restriction_exception_tags) do
|
for i,v in ipairs(restrictions) do
|
||||||
vector:Add(v)
|
vector:Add(v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -29,20 +29,19 @@ RestrictionParser::RestrictionParser(ScriptingEnvironment &scripting_environment
|
|||||||
{
|
{
|
||||||
if (use_turn_restrictions)
|
if (use_turn_restrictions)
|
||||||
{
|
{
|
||||||
restriction_exceptions = scripting_environment.GetExceptions();
|
restrictions = scripting_environment.GetRestrictions();
|
||||||
const unsigned exception_count = restriction_exceptions.size();
|
const unsigned count = restrictions.size();
|
||||||
if (exception_count)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
util::SimpleLogger().Write() << "Found " << exception_count
|
util::SimpleLogger().Write() << "Found " << count << " turn restriction tags:";
|
||||||
<< " exceptions to turn restrictions:";
|
for (const std::string &str : restrictions)
|
||||||
for (const std::string &str : restriction_exceptions)
|
|
||||||
{
|
{
|
||||||
util::SimpleLogger().Write() << " " << str;
|
util::SimpleLogger().Write() << " " << str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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
|
* Tries to parse a relation as a turn restriction. This can fail for a number of
|
||||||
* reasons. The return type is a boost::optional<T>.
|
* reasons. The return type is a boost::optional<T>.
|
||||||
*
|
*
|
||||||
* Some restrictions can also be ignored: See the ```get_exceptions``` function
|
* Some restrictions can also be ignored: See the ```get_restrictions``` function
|
||||||
* in the corresponding profile.
|
* 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<InputRestrictionContainer>
|
boost::optional<InputRestrictionContainer>
|
||||||
RestrictionParser::TryParse(const osmium::Relation &relation) const
|
RestrictionParser::TryParse(const osmium::Relation &relation) const
|
||||||
@ -63,13 +63,17 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
osmium::tags::KeyPrefixFilter filter(false);
|
osmium::tags::KeyFilter filter(false);
|
||||||
filter.add(true, "restriction");
|
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();
|
const osmium::TagList &tag_list = relation.tags();
|
||||||
|
|
||||||
osmium::tags::KeyPrefixFilter::iterator fi_begin(filter, tag_list.begin(), tag_list.end());
|
osmium::tags::KeyFilter::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_end(filter, tag_list.end(), tag_list.end());
|
||||||
|
|
||||||
// if it's not a restriction, continue;
|
// if it's not a restriction, continue;
|
||||||
if (std::distance(fi_begin, fi_end) == 0)
|
if (std::distance(fi_begin, fi_end) == 0)
|
||||||
@ -105,22 +109,6 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
|
|||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the "restriction*" key is longer than 11 chars, it is a conditional exception (i.e.
|
|
||||||
// "restriction:<transportation_type>")
|
|
||||||
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);
|
InputRestrictionContainer restriction_container(is_only_restriction);
|
||||||
@ -195,9 +183,8 @@ bool RestrictionParser::ShouldIgnoreRestriction(const std::string &except_tag_st
|
|||||||
|
|
||||||
return std::any_of(
|
return std::any_of(
|
||||||
std::begin(exceptions), std::end(exceptions), [&](const std::string ¤t_string) {
|
std::begin(exceptions), std::end(exceptions), [&](const std::string ¤t_string) {
|
||||||
return std::end(restriction_exceptions) != std::find(std::begin(restriction_exceptions),
|
return std::end(restrictions) !=
|
||||||
std::end(restriction_exceptions),
|
std::find(std::begin(restrictions), std::end(restrictions), current_string);
|
||||||
current_string);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,18 +327,17 @@ std::vector<std::string> LuaScriptingEnvironment::GetNameSuffixList()
|
|||||||
return suffixes_vector;
|
return suffixes_vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> LuaScriptingEnvironment::GetExceptions()
|
std::vector<std::string> LuaScriptingEnvironment::GetRestrictions()
|
||||||
{
|
{
|
||||||
auto &context = GetLuaContext();
|
auto &context = GetLuaContext();
|
||||||
BOOST_ASSERT(context.state != nullptr);
|
BOOST_ASSERT(context.state != nullptr);
|
||||||
std::vector<std::string> restriction_exceptions;
|
std::vector<std::string> restrictions;
|
||||||
if (util::luaFunctionExists(context.state, "get_exceptions"))
|
if (util::luaFunctionExists(context.state, "get_restrictions"))
|
||||||
{
|
{
|
||||||
// get list of turn restriction exceptions
|
// get list of turn restriction exceptions
|
||||||
luabind::call_function<void>(
|
luabind::call_function<void>(context.state, "get_restrictions", boost::ref(restrictions));
|
||||||
context.state, "get_exceptions", boost::ref(restriction_exceptions));
|
|
||||||
}
|
}
|
||||||
return restriction_exceptions;
|
return restrictions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaScriptingEnvironment::SetupSources()
|
void LuaScriptingEnvironment::SetupSources()
|
||||||
|
Loading…
Reference in New Issue
Block a user