Access to location dependent data in Lua via way:get_location_tags()

This commit is contained in:
Michael Krasnyk 2017-09-22 14:03:12 +02:00
parent 2059f7234a
commit 0f498d13f5
8 changed files with 58 additions and 68 deletions

View File

@ -37,7 +37,8 @@ Feature: osrm-extract lua ways:get_nodes()
""" """
functions = require('testbot') functions = require('testbot')
function way_function(profile, way, result, relations, location_data) function way_function(profile, way, result, relations)
location_data = way:get_location_tags()
assert(location_data) assert(location_data)
for k, v in pairs(location_data) do print (k .. ' ' .. tostring(v)) end for k, v in pairs(location_data) do print (k .. ' ' .. tostring(v)) end
result.forward_mode = mode.driving result.forward_mode = mode.driving
@ -67,7 +68,8 @@ Feature: osrm-extract lua ways:get_nodes()
""" """
functions = require('testbot') functions = require('testbot')
function way_function(profile, way, result, relations, location_data) function way_function(profile, way, result, relations)
location_data = way:get_location_tags()
assert(location_data) assert(location_data)
print('ISO3166-1 ' .. (location_data['ISO3166-1'] or 'none')) print('ISO3166-1 ' .. (location_data['ISO3166-1'] or 'none'))
result.forward_mode = mode.driving result.forward_mode = mode.driving
@ -101,7 +103,8 @@ Feature: osrm-extract lua ways:get_nodes()
""" """
functions = require('testbot') functions = require('testbot')
function way_function(profile, way, result, relations, location_data) function way_function(profile, way, result, relations)
location_data = way:get_location_tags()
assert(location_data) assert(location_data)
for k, v in pairs(location_data) do print (k .. ' ' .. tostring(v)) end for k, v in pairs(location_data) do print (k .. ' ' .. tostring(v)) end
result.forward_mode = mode.driving result.forward_mode = mode.driving

View File

@ -40,8 +40,6 @@ struct LocationDependentData
properties_t operator()(const point_t &point) const; properties_t operator()(const point_t &point) const;
properties_t operator()(const osmium::Way &way) const;
private: private:
void loadLocationDependentData(const boost::filesystem::path &file_path); void loadLocationDependentData(const boost::filesystem::path &file_path);

View File

@ -303,7 +303,7 @@ function process_node(profile, node, result)
end end
end end
function process_way(profile, way, result, relations, location_data) function process_way(profile, way, result, relations)
-- the intial filtering of ways based on presence of tags -- the intial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways -- affects processing times significantly, because all ways
-- have to be checked. -- have to be checked.
@ -387,8 +387,7 @@ function process_way(profile, way, result, relations, location_data)
WayHandlers.weights WayHandlers.weights
} }
print (profile, way, result, data, handlers, relations, location_data) WayHandlers.run(profile, way, result, data, handlers, relations)
WayHandlers.run(profile, way, result, data, handlers, relations, location_data)
end end
function process_turn(profile, turn) function process_turn(profile, turn)

View File

@ -552,16 +552,19 @@ function WayHandlers.blocked_ways(profile,way,result,data)
end end
end end
function WayHandlers.driving_side(profile, way, result, data, relations, location_data) function WayHandlers.driving_side(profile, way, result, data)
local driving_side = way:get_value_by_key("driving_side") local driving_side = way:get_value_by_key("driving_side")
if driving_side == 'left' then if driving_side == 'left' then
result.is_left_hand_driving = true result.is_left_hand_driving = true
elseif driving_side == 'right' then elseif driving_side == 'right' then
result.is_left_hand_driving = false result.is_left_hand_driving = false
elseif location_data then else
location_data = way:get_location_tags()
if location_data and location_data['driving_side'] then
result.is_left_hand_driving = location_data['driving_side'] == 'left' result.is_left_hand_driving = location_data['driving_side'] == 'left'
elseif profile.left_hand_driving then else
result.is_left_hand_driving = true result.is_left_hand_driving = profile.left_hand_driving
end
end end
end end
@ -580,13 +583,13 @@ end
-- WayHandlers.run(handlers,way,result,data,profile) -- WayHandlers.run(handlers,way,result,data,profile)
-- --
-- Each method in the list will be called on the WayHandlers object. -- Each method in the list will be called on the WayHandlers object.
-- All handlers must accept the parameteres (profile, way, result, data[, location_data]) and return false -- All handlers must accept the parameteres (profile, way, result, data, relations) and return false
-- if the handler chain should be aborted. -- if the handler chain should be aborted.
-- To ensure the correct order of method calls, use a Sequence of handler names. -- To ensure the correct order of method calls, use a Sequence of handler names.
function WayHandlers.run(profile, way, result, data, handlers, relatons, location_data) function WayHandlers.run(profile, way, result, data, handlers, relations)
for i,handler in ipairs(handlers) do for i,handler in ipairs(handlers) do
if handler(profile, way, result, data, relatons, location_data) == false then if handler(profile, way, result, data, relations) == false then
return false return false
end end
end end

View File

@ -265,20 +265,5 @@ LocationDependentData::properties_t LocationDependentData::operator()(const poin
return result; return result;
} }
LocationDependentData::properties_t LocationDependentData::operator()(const osmium::Way &way) const
{
// 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();
// TODO: the next call requires an OSM file preprocessed with a command
// osmium add-locations-to-ways --keep-untagged-nodes
const auto &location = nodes.back().location();
const point_t point(location.lon(), location.lat());
return operator()(point);
}
} }
} }

View File

@ -42,6 +42,8 @@ namespace osrm
namespace extractor namespace extractor
{ {
namespace
{
template <class T> template <class T>
auto get_value_by_key(T const &object, const char *key) -> decltype(object.get_value_by_key(key)) auto get_value_by_key(T const &object, const char *key) -> decltype(object.get_value_by_key(key))
{ {
@ -80,6 +82,28 @@ template <class T> double lonToDouble(T const &object)
return static_cast<double>(util::toFloating(object.lon)); return static_cast<double>(util::toFloating(object.lon));
} }
// boost::variant visitor that inserts a key-value pair in a Lua table
struct table_setter : public boost::static_visitor<>
{
table_setter(sol::table &table, const std::string &key) : table(table), key(key) {}
template <typename T> void operator()(const T &value) const { table.set(key, value); }
void operator()(const boost::blank &) const { /* ignore */}
sol::table &table;
const std::string &key;
};
// Converts a properties map into a Lua table
sol::table toLua(sol::state &state, const LocationDependentData::properties_t &properties)
{
auto table = sol::table(state, sol::create);
std::for_each(properties.begin(), properties.end(), [&table](const auto &property) {
boost::apply_visitor(table_setter(table, property.first), property.second);
});
return table;
}
}
Sol2ScriptingEnvironment::Sol2ScriptingEnvironment( Sol2ScriptingEnvironment::Sol2ScriptingEnvironment(
const std::string &file_name, const std::string &file_name,
const std::vector<boost::filesystem::path> &location_dependent_data_paths) const std::vector<boost::filesystem::path> &location_dependent_data_paths)
@ -285,10 +309,20 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
&get_value_by_key<osmium::Way>, &get_value_by_key<osmium::Way>,
"id", "id",
&osmium::Way::id, &osmium::Way::id,
"version",
&osmium::Way::version,
"get_nodes", "get_nodes",
[](const osmium::Way &way) { return sol::as_table(way.nodes()); }, [](const osmium::Way &way) { return sol::as_table(way.nodes()); },
"version", "get_location_tags",
&osmium::Way::version); [&context](const osmium::Way &way) {
// 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();
return toLua(context.state,
context.location_dependent_data({location.lon(), location.lat()}));
});
context.state.new_usertype<osmium::RelationMember>( context.state.new_usertype<osmium::RelationMember>(
"RelationMember", "RelationMember",
@ -978,30 +1012,6 @@ void LuaScriptingContext::ProcessNode(const osmium::Node &node,
} }
} }
namespace
{
// boost::variant visitor that inserts a key-value pair in a Lua table
struct table_setter : public boost::static_visitor<>
{
table_setter(sol::table &table, const std::string &key) : table(table), key(key) {}
template <typename T> void operator()(const T &value) const { table.set(key, value); }
void operator()(const boost::blank &) const { /* ignore */}
sol::table &table;
const std::string &key;
};
// Converts a properties map into a Lua table
sol::table toLua(sol::state &state, const LocationDependentData::properties_t properties)
{
auto table = sol::table(state, sol::create);
std::for_each(properties.begin(), properties.end(), [&table](const auto &property) {
boost::apply_visitor(table_setter(table, property.first), property.second);
});
return table;
}
}
void LuaScriptingContext::ProcessWay(const osmium::Way &way, void LuaScriptingContext::ProcessWay(const osmium::Way &way,
ExtractionWay &result, ExtractionWay &result,
const ExtractionRelationContainer::RelationList &relations) const ExtractionRelationContainer::RelationList &relations)
@ -1011,15 +1021,7 @@ void LuaScriptingContext::ProcessWay(const osmium::Way &way,
switch (api_version) switch (api_version)
{ {
case 3: case 3:
if (location_dependent_data.empty())
{
way_function(profile_table, way, result, relations); way_function(profile_table, way, result, relations);
}
else
{
way_function(
profile_table, way, result, relations, toLua(state, location_dependent_data(way)));
}
break; break;
case 2: case 2:
way_function(profile_table, way, result); way_function(profile_table, way, result);