Change location data method to way:get_location_tags(key)

This commit is contained in:
Michael Krasnyk
2017-09-22 16:14:55 +02:00
parent 0f498d13f5
commit 095b345713
6 changed files with 89 additions and 98 deletions
+15 -7
View File
@@ -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;
}
+9 -22
View File
@@ -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>(