diff --git a/features/car/barrier.feature b/features/car/barrier.feature index 19fdb1290fb..3f32206023e 100644 --- a/features/car/barrier.feature +++ b/features/car/barrier.feature @@ -45,3 +45,11 @@ Feature: Car - Barriers | bollard | | | | bollard | rising | x | | bollard | removable | | + + Scenario: Car - Height restrictions + Then routability should be + | node/barrier | node/maxheight | bothw | + | height_restrictor | | x | + | height_restrictor | 1 | | + | height_restrictor | 3 | x | + | height_restrictor | default | x | diff --git a/features/options/extract/lua.feature b/features/options/extract/lua.feature index 750fbb8af18..c238cde615d 100644 --- a/features/options/extract/lua.feature +++ b/features/options/extract/lua.feature @@ -129,8 +129,12 @@ Feature: osrm-extract lua ways:get_nodes() """ functions = require('testbot') + functions.process_node = function(profile, node, result, relations) + print ('node ' .. tostring(node:get_location_tag('answer'))) + end + functions.process_way = function(profile, way, result, relations) - print ('answer ' .. tostring(way:get_location_tag('answer'))) + print ('way ' .. tostring(way:get_location_tag('answer'))) result.forward_mode = mode.driving result.forward_speed = 1 end @@ -148,4 +152,5 @@ Feature: osrm-extract lua ways:get_nodes() When I run "osrm-extract --profile {profile_file} {osm_file} --location-dependent-data test/data/regions/null-island.geojson" Then it should exit successfully - And stdout should contain "answer 42" + And stdout should contain "node 42" + And stdout should contain "way 42" diff --git a/profiles/car.lua b/profiles/car.lua index 38cd794c53f..161a6466bae 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -9,6 +9,7 @@ Relations = require("lib/relations") find_access_tag = require("lib/access").find_access_tag limit = require("lib/maxspeed").limit Utils = require("lib/utils") +Measure = require("lib/measure") function setup() return { @@ -54,7 +55,8 @@ function setup() 'gate', 'lift_gate', 'no', - 'entrance' + 'entrance', + 'height_restrictor' }, access_tag_whitelist = Set { @@ -320,11 +322,18 @@ function process_node(profile, node, result, relations) else local barrier = node:get_value_by_key("barrier") if barrier then + -- check height restriction barriers + local restricted_by_height = false + if barrier == 'height_restrictor' then + local maxheight = Measure.get_max_height(node:get_value_by_key("maxheight"), node) + restricted_by_height = maxheight and maxheight < profile.vehicle_height + end + -- make an exception for rising bollard barriers local bollard = node:get_value_by_key("bollard") local rising_bollard = bollard and "rising" == bollard - if not profile.barrier_whitelist[barrier] and not rising_bollard then + if not profile.barrier_whitelist[barrier] and not rising_bollard or restricted_by_height then result.barrier = true end end diff --git a/profiles/lib/measure.lua b/profiles/lib/measure.lua index d0804a6a76b..b433fbe9b09 100644 --- a/profiles/lib/measure.lua +++ b/profiles/lib/measure.lua @@ -62,11 +62,11 @@ local height_non_numerical_values = Set { "default", "none", "no-sign", "unsigne --- Get maxheight of specified way in meters. If there are no --- max height, then return nil -function Measure.get_max_height(raw_value,way) +function Measure.get_max_height(raw_value, element) if raw_value then if height_non_numerical_values[raw_value] then - if way then - return way:get_location_tag('maxheight') or default_maxheight + if element then + return element:get_location_tag('maxheight') or default_maxheight else return default_maxheight end diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 885b47e61b8..e4513d41138 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -218,6 +218,22 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) "valid", &osmium::Location::valid); + auto get_location_tag = [](auto &context, const auto &location, const char *key) { + if (context.location_dependent_data.empty()) + return sol::object(sol::nil); + + const LocationDependentData::point_t point{location.lon(), location.lat()}; + if (!boost::geometry::equals(context.last_location_point, point)) + { + context.last_location_point = point; + context.last_location_indexes = + context.location_dependent_data.GetPropertyIndexes(point); + } + + auto value = context.location_dependent_data.FindByKey(context.last_location_indexes, key); + return boost::apply_visitor(to_lua_object(context.state), value); + }; + context.state.new_usertype( "Way", "get_value_by_key", @@ -229,37 +245,29 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) "get_nodes", [](const osmium::Way &way) { return sol::as_table(way.nodes()); }, "get_location_tag", - [&context](const osmium::Way &way, const char *key) { - if (context.location_dependent_data.empty()) - return sol::object(sol::nil); + [&context, &get_location_tag](const osmium::Way &way, const char *key) { // HEURISTIC: use a single node (last) of the way to localize the way // For more complicated scenarios a proper merging of multiple tags // at one or many locations must be provided const auto &nodes = way.nodes(); const auto &location = nodes.back().location(); - const LocationDependentData::point_t point{location.lon(), location.lat()}; - - if (!boost::geometry::equals(context.last_location_point, point)) - { - context.last_location_point = point; - context.last_location_indexes = - context.location_dependent_data.GetPropertyIndexes(point); - } - - auto value = - context.location_dependent_data.FindByKey(context.last_location_indexes, key); - return boost::apply_visitor(to_lua_object(context.state), value); + return get_location_tag(context, location, key); }); - context.state.new_usertype("Node", - "location", - &osmium::Node::location, - "get_value_by_key", - &get_value_by_key, - "id", - &osmium::Node::id, - "version", - &osmium::Node::version); + context.state.new_usertype( + "Node", + "location", + &osmium::Node::location, + "get_value_by_key", + &get_value_by_key, + "id", + &osmium::Node::id, + "version", + &osmium::Node::version, + "get_location_tag", + [&context, &get_location_tag](const osmium::Node &node, const char *key) { + return get_location_tag(context, node.location(), key); + }); context.state.new_usertype("ResultNode", "traffic_lights",