From 5f598da76de28c60b063b2b71ca30b78c2fc233e Mon Sep 17 00:00:00 2001 From: Michael Krasnyk Date: Mon, 12 Feb 2018 09:02:20 +0100 Subject: [PATCH] Add OSM node barrier=height_restrictor handling --- CHANGELOG.md | 3 +- features/car/barrier.feature | 8 +++ features/options/extract/lua.feature | 9 +++- profiles/car.lua | 13 ++++- profiles/lib/measure.lua | 6 +-- src/extractor/scripting_environment_lua.cpp | 56 ++++++++++++--------- taginfo.json | 1 + 7 files changed, 64 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6431ec3e28..c2a41da3c94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ - Profile: - FIXED: `highway=service` will now be used for restricted access, `access=private` is still disabled for snapping. - ADDED #4775: Exposes more information to the turn function, now being able to set turn weights with highway and access information of the turn as well as other roads at the intersection [#4775](https://github.com/Project-OSRM/osrm-backend/issues/4775) - - FIXED: #4763: Add support for non-numerical units in car profile for maxheight [#4763](https://github.com/Project-OSRM/osrm-backend/issues/4763) + - FIXED #4763: Add support for non-numerical units in car profile for maxheight [#4763](https://github.com/Project-OSRM/osrm-backend/issues/4763) + - ADDED #4872: Handling of `barrier=height_restrictor` nodes [#4872](https://github.com/Project-OSRM/osrm-backend/pull/4872) # 5.15.1 - Changes from 5.15.0: 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", diff --git a/taginfo.json b/taginfo.json index 4608fd9a28f..3796bc67a60 100644 --- a/taginfo.json +++ b/taginfo.json @@ -139,6 +139,7 @@ {"key": "access", "value": "emergency"}, {"key": "access", "value": "psv"}, {"key": "access", "value": "delivery"}, + {"key": "maxheight", "object_types": ["node", "way"]}, {"key": "maxspeed", "value": "none"}, {"key": "maxspeed", "value": "urban"}, {"key": "maxspeed", "value": "rural"},