diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index e4e2e6eb..edf12fca 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -142,6 +142,8 @@ To do that, you use these methods: * `Find(key)`: get the value for a tag, or the empty string if not present. For example, `Find("railway")` might return "rail" for a railway, "siding" for a siding, or "" if it isn't a railway at all. * `Holds(key)`: returns true if that key exists, false otherwise. +* `AllKeys()`: returns a table (array) containing all the OSM tag keys. +* `AllTags()`: returns a table containing all the OSM tags. * `Layer(layer_name, is_area)`: write this node/way to the named layer. This is how you put objects in your vector tile. is_area (true/false) specifies whether a way should be treated as an area, or just as a linestring. * `LayerAsCentroid(layer_name, algorithm, role, role...)`: write a single centroid point for this way to the named layer (useful for labels and POIs). Only the first argument is required. `algorithm` can be "polylabel" (default) or "centroid". The third arguments onwards specify relation roles: if you're processing a multipolygon-type relation (e.g. a boundary) and it has a "label" node member, then by adding "label" as an argument here, this will be used in preference to the calculated point. * `Attribute(key,value,minzoom)`: add an attribute to the most recently written layer. Argument `minzoom` is optional, use it if you do not want to write the attribute on lower zoom levels. diff --git a/include/osm_lua_processing.h b/include/osm_lua_processing.h index bdc63d4b..bfcb5d4e 100644 --- a/include/osm_lua_processing.h +++ b/include/osm_lua_processing.h @@ -113,6 +113,12 @@ class OsmLuaProcessing { // Get the ID of the current object std::string Id() const; + // Gets a table of all the keys of the OSM tags + kaguya::LuaTable AllKeys(kaguya::State& luaState); + + // Gets a table of all the OSM tags + kaguya::LuaTable AllTags(kaguya::State& luaState); + // Check if there's a value for a given key bool Holds(const std::string& key) const; diff --git a/src/osm_lua_processing.cpp b/src/osm_lua_processing.cpp index 073085a5..12b0323a 100644 --- a/src/osm_lua_processing.cpp +++ b/src/osm_lua_processing.cpp @@ -119,7 +119,43 @@ template<> struct kaguya::lua_type_traits { } }; +// Gets a table of all the keys of the OSM tags +kaguya::LuaTable getAllKeys(kaguya::State& luaState, const boost::container::flat_map* tags) { + kaguya::LuaTable tagsTable = luaState.newTable(); + int index = 1; // Lua is 1-based + for (const auto& kv: *tags) { + tagsTable[index++] = kv.first; + } + return tagsTable; +} + +// Gets a table of all the OSM tags +kaguya::LuaTable getAllTags(kaguya::State& luaState, const boost::container::flat_map* tags) { + kaguya::LuaTable tagsTable = luaState.newTable(); + for (const auto& kv: *tags) { + tagsTable[kv.first] = kv.second; + } + return tagsTable; +} + std::string rawId() { return osmLuaProcessing->Id(); } +kaguya::LuaTable rawAllKeys() { + if (osmLuaProcessing->isPostScanRelation) { + return osmLuaProcessing->AllKeys(*g_luaState); + } + + auto tags = osmLuaProcessing->currentTags->exportToBoostMap(); + + return getAllKeys(*g_luaState, &tags); +}kaguya::LuaTable rawAllTags() { + if (osmLuaProcessing->isPostScanRelation) { + return osmLuaProcessing->AllTags(*g_luaState); + } + + auto tags = osmLuaProcessing->currentTags->exportToBoostMap(); + + return getAllTags(*g_luaState, &tags); +} bool rawHolds(const KnownTagKey& key) { if (osmLuaProcessing->isPostScanRelation) { return osmLuaProcessing->Holds(key.stringValue); @@ -198,6 +234,8 @@ OsmLuaProcessing::OsmLuaProcessing( osmLuaProcessing = this; luaState["Id"] = &rawId; + luaState["AllKeys"] = &rawAllKeys; + luaState["AllTags"] = &rawAllTags; luaState["Holds"] = &rawHolds; luaState["Find"] = &rawFind; luaState["HasTags"] = &rawHasTags; @@ -302,6 +340,18 @@ string OsmLuaProcessing::Id() const { return to_string(originalOsmID); } +// Gets a table of all the keys of the OSM tags +kaguya::LuaTable OsmLuaProcessing::AllKeys(kaguya::State& luaState) { + // NOTE: this is only called in the PostScanRelation phase -- other phases are handled in rawAllKeys + return getAllKeys(luaState, currentPostScanTags); +} + +// Gets a table of all the OSM tags +kaguya::LuaTable OsmLuaProcessing::AllTags(kaguya::State& luaState) { + // NOTE: this is only called in the PostScanRelation phase -- other phases are handled in rawAllTags + return getAllTags(luaState, currentPostScanTags); +} + // Check if there's a value for a given key bool OsmLuaProcessing::Holds(const string& key) const { // NOTE: this is only called in the PostScanRelation phase -- other phases are handled in rawHolds