Change location data method to way:get_location_tags(key)
This commit is contained in:
parent
0f498d13f5
commit
095b345713
@ -38,9 +38,9 @@ Feature: osrm-extract lua ways:get_nodes()
|
||||
functions = require('testbot')
|
||||
|
||||
function way_function(profile, way, result, relations)
|
||||
location_data = way:get_location_tags()
|
||||
assert(location_data)
|
||||
for k, v in pairs(location_data) do print (k .. ' ' .. tostring(v)) end
|
||||
for _, key in ipairs({'answer', 'boolean', 'object', 'array'}) do
|
||||
print (key .. ' ' .. tostring(way:get_location_tag(key)))
|
||||
end
|
||||
result.forward_mode = mode.driving
|
||||
result.forward_speed = 1
|
||||
end
|
||||
@ -60,7 +60,9 @@ 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 not contain "array"
|
||||
And stdout should contain "boolean true"
|
||||
And stdout should contain "array nil"
|
||||
And stdout should contain "object nil"
|
||||
|
||||
|
||||
Scenario: osrm-extract location-dependent data with multi-polygons
|
||||
@ -69,9 +71,7 @@ Feature: osrm-extract lua ways:get_nodes()
|
||||
functions = require('testbot')
|
||||
|
||||
function way_function(profile, way, result, relations)
|
||||
location_data = way:get_location_tags()
|
||||
assert(location_data)
|
||||
print('ISO3166-1 ' .. (location_data['ISO3166-1'] or 'none'))
|
||||
print('ISO3166-1 ' .. (way:get_location_tag('ISO3166-1') or 'none'))
|
||||
result.forward_mode = mode.driving
|
||||
result.forward_speed = 1
|
||||
end
|
||||
@ -104,9 +104,7 @@ Feature: osrm-extract lua ways:get_nodes()
|
||||
functions = require('testbot')
|
||||
|
||||
function way_function(profile, way, result, relations)
|
||||
location_data = way:get_location_tags()
|
||||
assert(location_data)
|
||||
for k, v in pairs(location_data) do print (k .. ' ' .. tostring(v)) end
|
||||
print ('answer ' .. tostring(way:get_location_tag('answer')))
|
||||
result.forward_mode = mode.driving
|
||||
result.forward_speed = 1
|
||||
end
|
||||
@ -126,4 +124,3 @@ 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 not contain "array"
|
||||
|
@ -38,7 +38,7 @@ struct LocationDependentData
|
||||
|
||||
bool empty() const { return rtree.empty(); }
|
||||
|
||||
properties_t operator()(const point_t &point) const;
|
||||
property_t operator()(const point_t &point, const char *key) const;
|
||||
|
||||
private:
|
||||
void loadLocationDependentData(const boost::filesystem::path &file_path);
|
||||
|
@ -553,18 +553,17 @@ function WayHandlers.blocked_ways(profile,way,result,data)
|
||||
end
|
||||
|
||||
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 == nil then
|
||||
driving_side = way:get_location_tag('driving_side')
|
||||
end
|
||||
|
||||
if driving_side == 'left' then
|
||||
result.is_left_hand_driving = true
|
||||
elseif driving_side == 'right' then
|
||||
result.is_left_hand_driving = false
|
||||
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'
|
||||
else
|
||||
result.is_left_hand_driving = profile.left_hand_driving
|
||||
end
|
||||
result.is_left_hand_driving = profile.left_hand_driving
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -195,17 +195,25 @@ void LocationDependentData::loadLocationDependentData(const boost::filesystem::p
|
||||
<< polygons.size() << " GeoJSON polygons";
|
||||
}
|
||||
|
||||
LocationDependentData::properties_t LocationDependentData::operator()(const point_t &point) const
|
||||
LocationDependentData::property_t LocationDependentData::operator()(const point_t &point,
|
||||
const char *key) const
|
||||
{
|
||||
properties_t result;
|
||||
property_t result;
|
||||
|
||||
auto merger = [this, &result](const rtree_t::value_type &rtree_entry) {
|
||||
const auto &polygon_properties = properties[polygons[rtree_entry.second].second];
|
||||
result.insert(polygon_properties.begin(), polygon_properties.end());
|
||||
auto setter = [this, &result, &key](const rtree_t::value_type &rtree_entry) {
|
||||
const auto properties_index = polygons[rtree_entry.second].second;
|
||||
const auto &polygon_properties = properties[properties_index];
|
||||
const auto it = polygon_properties.find(key);
|
||||
if (it != polygon_properties.end())
|
||||
{
|
||||
result = it->second;
|
||||
}
|
||||
};
|
||||
|
||||
// Search the R-tree and collect a Lua table of tags that correspond to the location
|
||||
rtree.query(boost::geometry::index::intersects(point) &&
|
||||
rtree.query(boost::geometry::index::satisfies(
|
||||
[&result](const rtree_t::value_type &) { return result.which() == 0; }) &&
|
||||
boost::geometry::index::intersects(point) &&
|
||||
boost::geometry::index::satisfies([this, &point](const rtree_t::value_type &v) {
|
||||
|
||||
// Simple point-in-polygon algorithm adapted from
|
||||
@ -261,7 +269,7 @@ LocationDependentData::properties_t LocationDependentData::operator()(const poin
|
||||
|
||||
return inside;
|
||||
}),
|
||||
boost::make_function_output_iterator(std::ref(merger)));
|
||||
boost::make_function_output_iterator(std::ref(setter)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -82,26 +82,13 @@ template <class T> double lonToDouble(T const &object)
|
||||
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<>
|
||||
struct to_lua_object : public boost::static_visitor<sol::object>
|
||||
{
|
||||
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;
|
||||
to_lua_object(sol::state &state) : state(state) {}
|
||||
template <typename T> auto operator()(T &v) const { return sol::make_object(state, v); }
|
||||
auto operator()(boost::blank &) const { return sol::nil; }
|
||||
sol::state &state;
|
||||
};
|
||||
|
||||
// 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(
|
||||
@ -313,15 +300,15 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
&osmium::Way::version,
|
||||
"get_nodes",
|
||||
[](const osmium::Way &way) { return sol::as_table(way.nodes()); },
|
||||
"get_location_tags",
|
||||
[&context](const osmium::Way &way) {
|
||||
"get_location_tag",
|
||||
[&context](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();
|
||||
return toLua(context.state,
|
||||
context.location_dependent_data({location.lon(), location.lat()}));
|
||||
auto value = context.location_dependent_data({location.lon(), location.lat()}, key);
|
||||
return boost::apply_visitor(to_lua_object(context.state), value);
|
||||
});
|
||||
|
||||
context.state.new_usertype<osmium::RelationMember>(
|
||||
|
@ -50,15 +50,15 @@ BOOST_AUTO_TEST_CASE(polygon_tests)
|
||||
]})json");
|
||||
|
||||
LocationDependentData data(fixture.temporary_file);
|
||||
BOOST_CHECK(data(point_t(0, 0)).empty());
|
||||
BOOST_CHECK(!data(point_t(1, 1)).empty());
|
||||
BOOST_CHECK(!data(point_t(0, 1)).empty());
|
||||
BOOST_CHECK(!data(point_t(0.5, -0.5)).empty());
|
||||
BOOST_CHECK(!data(point_t(0, -3)).empty());
|
||||
BOOST_CHECK(!data(point_t(-0.75, 0.75)).empty());
|
||||
BOOST_CHECK(!data(point_t(-2, 6)).empty());
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(2, 0))["answer"]), 42.);
|
||||
BOOST_CHECK_EQUAL(boost::get<bool>(data(point_t(1, 7))["answer"]), true);
|
||||
BOOST_CHECK_EQUAL(data(point_t(0, 0), "answer").which(), 0);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(1, 1), "answer")), 42);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(0, 1), "answer")), 42);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(0.5, -0.5), "answer")), 42);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(0, -3), "answer")), 42);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(-0.75, 0.75), "answer")), 42);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(2, 0), "answer")), 42.);
|
||||
BOOST_CHECK_EQUAL(boost::get<bool>(data(point_t(1, 7), "answer")), true);
|
||||
BOOST_CHECK_EQUAL(boost::get<bool>(data(point_t(-2, 6), "answer")), true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(multy_polygon_tests)
|
||||
@ -80,11 +80,11 @@ BOOST_AUTO_TEST_CASE(multy_polygon_tests)
|
||||
]})json");
|
||||
|
||||
LocationDependentData data(fixture.temporary_file);
|
||||
BOOST_CHECK(data(point_t(0, 2)).empty());
|
||||
BOOST_CHECK(data(point_t(0, -3)).empty());
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(0, 0))["answer"]), 42.);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(5, 0))["answer"]), 42.);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(-5, 0))["answer"]), 42.);
|
||||
BOOST_CHECK_EQUAL(data(point_t(0, 2), "answer").which(), 0);
|
||||
BOOST_CHECK_EQUAL(data(point_t(0, -3), "answer").which(), 0);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(0, 0), "answer")), 42.);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(5, 0), "answer")), 42.);
|
||||
BOOST_CHECK_EQUAL(boost::get<double>(data(point_t(-5, 0), "answer")), 42.);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(polygon_merging_tests)
|
||||
@ -110,19 +110,19 @@ BOOST_AUTO_TEST_CASE(polygon_merging_tests)
|
||||
]})json");
|
||||
|
||||
LocationDependentData data(fixture.temporary_file);
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(-3, 3))["answer"]), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(-3, 1))["answer"]), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(-3, -3))["answer"]), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(0, 3))["answer"]), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(1, 0))["answer"]), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(2, -3))["answer"]), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(3, 0))["answer"]), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(4, 3))["answer"]), "b");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(6, 1))["answer"]), "b");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(7, 0))["answer"]), "b");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(8, 3))["answer"]), "c");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(8, -1))["answer"]), "c");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(8, -3))["answer"]), "c");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(-3, 3), "answer")), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(-3, 1), "answer")), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(-3, -3), "answer")), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(0, 3), "answer")), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(1, 0), "answer")), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(2, -3), "answer")), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(3, 0), "answer")), "a");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(4, 3), "answer")), "b");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(6, 1), "answer")), "b");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(7, 0), "answer")), "b");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(8, 3), "answer")), "c");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(8, -1), "answer")), "c");
|
||||
BOOST_CHECK_EQUAL(boost::get<std::string>(data(point_t(8, -3), "answer")), "c");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(staircase_polygon)
|
||||
@ -140,31 +140,31 @@ BOOST_AUTO_TEST_CASE(staircase_polygon)
|
||||
LocationDependentData data(fixture.temporary_file);
|
||||
|
||||
// all corners
|
||||
BOOST_CHECK(!data(point_t(0, 0)).empty());
|
||||
BOOST_CHECK(!data(point_t(0, 1)).empty());
|
||||
BOOST_CHECK(!data(point_t(1, 1)).empty());
|
||||
BOOST_CHECK(!data(point_t(1, 2)).empty());
|
||||
BOOST_CHECK(!data(point_t(2, 2)).empty());
|
||||
BOOST_CHECK(!data(point_t(2, 3)).empty());
|
||||
BOOST_CHECK(!data(point_t(3, 3)).empty());
|
||||
BOOST_CHECK(!data(point_t(3, 0)).empty());
|
||||
BOOST_CHECK_NE(data(point_t(0, 0), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(0, 1), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(1, 1), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(1, 2), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(2, 2), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(2, 3), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(3, 3), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(3, 0), "answer").which(), 0);
|
||||
|
||||
// at x = 1
|
||||
BOOST_CHECK(data(point_t(1, -0.5)).empty());
|
||||
BOOST_CHECK(!data(point_t(1, 0)).empty());
|
||||
BOOST_CHECK(!data(point_t(1, 0.5)).empty());
|
||||
BOOST_CHECK(!data(point_t(1, 1.5)).empty());
|
||||
BOOST_CHECK(data(point_t(1, 2.5)).empty());
|
||||
BOOST_CHECK(data(point_t(3.5, 2)).empty());
|
||||
// // at x = 1
|
||||
BOOST_CHECK_EQUAL(data(point_t(1, -0.5), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(1, 0), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(1, 0.5), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(1, 1.5), "answer").which(), 0);
|
||||
BOOST_CHECK_EQUAL(data(point_t(1, 2.5), "answer").which(), 0);
|
||||
BOOST_CHECK_EQUAL(data(point_t(3.5, 2), "answer").which(), 0);
|
||||
|
||||
// at y = 2
|
||||
BOOST_CHECK(data(point_t(0.5, 2)).empty());
|
||||
BOOST_CHECK(!data(point_t(1, 2)).empty());
|
||||
BOOST_CHECK(!data(point_t(1.5, 2)).empty());
|
||||
BOOST_CHECK(!data(point_t(2, 2)).empty());
|
||||
BOOST_CHECK(!data(point_t(2.5, 2)).empty());
|
||||
BOOST_CHECK(!data(point_t(3, 2)).empty());
|
||||
BOOST_CHECK(data(point_t(3.5, 2)).empty());
|
||||
// // at y = 2
|
||||
BOOST_CHECK_EQUAL(data(point_t(0.5, 2), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(1, 2), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(1.5, 2), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(2, 2), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(2.5, 2), "answer").which(), 0);
|
||||
BOOST_CHECK_NE(data(point_t(3, 2), "answer").which(), 0);
|
||||
BOOST_CHECK_EQUAL(data(point_t(3.5, 2), "answer").which(), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
Loading…
Reference in New Issue
Block a user