@@ -126,15 +126,14 @@ prepared_lua_function_t::prepared_lua_function_t(lua_State *lua_state,
126126namespace {
127127
128128void push_osm_object_to_lua_stack (lua_State *lua_state,
129- osmium::OSMObject const &object,
130- bool with_attributes)
129+ osmium::OSMObject const &object)
131130{
132131 assert (lua_state);
133132
134133 /* *
135- * Table will always have at least 3 fields (id, type, tags). And 5 more if
136- * with_attributes is true (version, timestamp, changeset, uid, user). For
137- * ways there are 2 more (is_closed, nodes), for relations 1 more (members).
134+ * Table will always have at least 8 fields (id, type, tags, version,
135+ * timestamp, changeset, uid, user). For ways there are 2 more (is_closed,
136+ * nodes), for relations 1 more (members).
138137 */
139138 constexpr int const max_table_size = 10 ;
140139
@@ -145,23 +144,21 @@ void push_osm_object_to_lua_stack(lua_State *lua_state,
145144 luaX_add_table_str (lua_state, " type" ,
146145 osmium::item_type_to_name (object.type ()));
147146
148- if (with_attributes) {
149- if (object.version () != 0U ) {
150- luaX_add_table_int (lua_state, " version" , object.version ());
151- }
152- if (object.timestamp ().valid ()) {
153- luaX_add_table_int (lua_state, " timestamp" ,
154- object.timestamp ().seconds_since_epoch ());
155- }
156- if (object.changeset () != 0U ) {
157- luaX_add_table_int (lua_state, " changeset" , object.changeset ());
158- }
159- if (object.uid () != 0U ) {
160- luaX_add_table_int (lua_state, " uid" , object.uid ());
161- }
162- if (object.user ()[0 ] != ' \0 ' ) {
163- luaX_add_table_str (lua_state, " user" , object.user ());
164- }
147+ if (object.version () != 0U ) {
148+ luaX_add_table_int (lua_state, " version" , object.version ());
149+ }
150+ if (object.timestamp ().valid ()) {
151+ luaX_add_table_int (lua_state, " timestamp" ,
152+ object.timestamp ().seconds_since_epoch ());
153+ }
154+ if (object.changeset () != 0U ) {
155+ luaX_add_table_int (lua_state, " changeset" , object.changeset ());
156+ }
157+ if (object.uid () != 0U ) {
158+ luaX_add_table_int (lua_state, " uid" , object.uid ());
159+ }
160+ if (object.user ()[0 ] != ' \0 ' ) {
161+ luaX_add_table_str (lua_state, " user" , object.user ());
165162 }
166163
167164 if (object.type () == osmium::item_type::way) {
@@ -308,8 +305,10 @@ void output_flex_t::check_context_and_state(char const *name,
308305 char const *context, bool condition)
309306{
310307 if (condition) {
311- throw fmt_error (" The function {}() can only be called from the {}." ,
312- name, context);
308+ throw fmt_error (
309+ " The function {}() can only be called (directly or indirectly) "
310+ " from the process_[untagged]_{}() functions." ,
311+ name, context);
313312 }
314313
315314 if (lua_gettop (lua_state ()) > 1 ) {
@@ -320,7 +319,7 @@ void output_flex_t::check_context_and_state(char const *name,
320319int output_flex_t::app_get_bbox ()
321320{
322321 check_context_and_state (
323- " get_bbox" , " process_node /way/relation() functions " ,
322+ " get_bbox" , " node /way/relation" ,
324323 m_calling_context != calling_context::process_node &&
325324 m_calling_context != calling_context::process_way &&
326325 m_calling_context != calling_context::process_relation);
@@ -370,7 +369,7 @@ int output_flex_t::app_get_bbox()
370369
371370int output_flex_t::app_as_point ()
372371{
373- check_context_and_state (" as_point" , " process_node() function " ,
372+ check_context_and_state (" as_point" , " node " ,
374373 m_calling_context != calling_context::process_node);
375374
376375 auto *geom = create_lua_geometry_object (lua_state ());
@@ -381,7 +380,7 @@ int output_flex_t::app_as_point()
381380
382381int output_flex_t::app_as_linestring ()
383382{
384- check_context_and_state (" as_linestring" , " process_way() function " ,
383+ check_context_and_state (" as_linestring" , " way " ,
385384 m_calling_context != calling_context::process_way);
386385
387386 m_way_cache.add_nodes (middle ());
@@ -394,7 +393,7 @@ int output_flex_t::app_as_linestring()
394393
395394int output_flex_t::app_as_polygon ()
396395{
397- check_context_and_state (" as_polygon" , " process_way() function " ,
396+ check_context_and_state (" as_polygon" , " way " ,
398397 m_calling_context != calling_context::process_way);
399398
400399 m_way_cache.add_nodes (middle ());
@@ -408,7 +407,7 @@ int output_flex_t::app_as_polygon()
408407int output_flex_t::app_as_multipoint ()
409408{
410409 check_context_and_state (
411- " as_multipoint" , " process_node /relation() functions " ,
410+ " as_multipoint" , " node /relation" ,
412411 m_calling_context != calling_context::process_node &&
413412 m_calling_context != calling_context::process_relation);
414413
@@ -426,10 +425,10 @@ int output_flex_t::app_as_multipoint()
426425
427426int output_flex_t::app_as_multilinestring ()
428427{
429- check_context_and_state (
430- " as_multilinestring " , " process_way/relation() functions " ,
431- m_calling_context != calling_context::process_way &&
432- m_calling_context != calling_context::process_relation);
428+ check_context_and_state (" as_multilinestring " , " way/relation " ,
429+ m_calling_context != calling_context:: process_way &&
430+ m_calling_context !=
431+ calling_context::process_relation);
433432
434433 if (m_calling_context == calling_context::process_way) {
435434 m_way_cache.add_nodes (middle ());
@@ -450,10 +449,10 @@ int output_flex_t::app_as_multilinestring()
450449
451450int output_flex_t::app_as_multipolygon ()
452451{
453- check_context_and_state (
454- " as_multipolygon " , " process_way/relation() functions " ,
455- m_calling_context != calling_context::process_way &&
456- m_calling_context != calling_context::process_relation);
452+ check_context_and_state (" as_multipolygon " , " way/relation " ,
453+ m_calling_context != calling_context:: process_way &&
454+ m_calling_context !=
455+ calling_context::process_relation);
457456
458457 if (m_calling_context == calling_context::process_way) {
459458 m_way_cache.add_nodes (middle ());
@@ -476,9 +475,9 @@ int output_flex_t::app_as_multipolygon()
476475
477476int output_flex_t::app_as_geometrycollection ()
478477{
479- check_context_and_state (
480- " as_geometrycollection " , " process_relation() function " ,
481- m_calling_context != calling_context::process_relation);
478+ check_context_and_state (" as_geometrycollection " , " relation " ,
479+ m_calling_context !=
480+ calling_context::process_relation);
482481
483482 m_relation_cache.add_members (middle ());
484483
@@ -692,8 +691,7 @@ int output_flex_t::table_insert()
692691 lua_pushboolean (lua_state (), false );
693692 lua_pushstring (lua_state (), " null value in not null column." );
694693 lua_pushstring (lua_state (), e.column ().name ().c_str ());
695- push_osm_object_to_lua_stack (lua_state (), object,
696- get_options ()->extra_attributes );
694+ push_osm_object_to_lua_stack (lua_state (), object);
697695 table_connection.increment_not_null_error_counter ();
698696 return 4 ;
699697 }
@@ -820,9 +818,7 @@ void output_flex_t::call_lua_function(prepared_lua_function_t func,
820818 m_calling_context = func.context ();
821819
822820 lua_pushvalue (lua_state (), func.index ()); // the function to call
823- push_osm_object_to_lua_stack (
824- lua_state (), object,
825- get_options ()->extra_attributes ); // the single argument
821+ push_osm_object_to_lua_stack (lua_state (), object); // the single argument
826822
827823 luaX_set_context (lua_state (), this );
828824 if (luaX_pcall (lua_state (), 1 , func.nresults ())) {
@@ -1053,36 +1049,45 @@ void output_flex_t::wait()
10531049
10541050void output_flex_t::node_add (osmium::Node const &node)
10551051{
1056- if (!m_process_node) {
1052+ auto const &func =
1053+ node.tags ().empty () ? m_process_untagged_node : m_process_node;
1054+
1055+ if (!func) {
10571056 return ;
10581057 }
10591058
10601059 m_context_node = &node;
1061- get_mutex_and_call_lua_function (m_process_node , node);
1060+ get_mutex_and_call_lua_function (func , node);
10621061 m_context_node = nullptr ;
10631062}
10641063
10651064void output_flex_t::way_add (osmium::Way *way)
10661065{
10671066 assert (way);
10681067
1069- if (!m_process_way) {
1068+ auto const &func =
1069+ way->tags ().empty () ? m_process_untagged_way : m_process_way;
1070+
1071+ if (!func) {
10701072 return ;
10711073 }
10721074
10731075 m_way_cache.init (way);
1074- get_mutex_and_call_lua_function (m_process_way , m_way_cache.get ());
1076+ get_mutex_and_call_lua_function (func , m_way_cache.get ());
10751077}
10761078
10771079void output_flex_t::relation_add (osmium::Relation const &relation)
10781080{
1079- if (!m_process_relation) {
1081+ auto const &func = relation.tags ().empty () ? m_process_untagged_relation
1082+ : m_process_relation;
1083+
1084+ if (!func) {
10801085 return ;
10811086 }
10821087
10831088 m_relation_cache.init (relation);
10841089 select_relation_members ();
1085- get_mutex_and_call_lua_function (m_process_relation , relation);
1090+ get_mutex_and_call_lua_function (func , relation);
10861091}
10871092
10881093void output_flex_t::delete_from_table (table_connection_t *table_connection,
@@ -1177,6 +1182,9 @@ output_flex_t::output_flex_t(output_flex_t const *other,
11771182 m_area_buffer(1024 , osmium::memory::Buffer::auto_grow::yes),
11781183 m_process_node(other->m_process_node), m_process_way(other->m_process_way),
11791184 m_process_relation(other->m_process_relation),
1185+ m_process_untagged_node(other->m_process_untagged_node),
1186+ m_process_untagged_way(other->m_process_untagged_way),
1187+ m_process_untagged_relation(other->m_process_untagged_relation),
11801188 m_select_relation_members(other->m_select_relation_members),
11811189 m_after_nodes(other->m_after_nodes), m_after_ways(other->m_after_ways),
11821190 m_after_relations(other->m_after_relations)
@@ -1408,9 +1416,19 @@ void output_flex_t::init_lua(std::string const &filename,
14081416 lua_state (), calling_context::process_way, " process_way" };
14091417 m_process_relation = prepared_lua_function_t {
14101418 lua_state (), calling_context::process_relation, " process_relation" };
1419+
1420+ m_process_untagged_node = prepared_lua_function_t {
1421+ lua_state (), calling_context::process_node, " process_untagged_node" };
1422+ m_process_untagged_way = prepared_lua_function_t {
1423+ lua_state (), calling_context::process_way, " process_untagged_way" };
1424+ m_process_untagged_relation =
1425+ prepared_lua_function_t {lua_state (), calling_context::process_relation,
1426+ " process_untagged_relation" };
1427+
14111428 m_select_relation_members = prepared_lua_function_t {
14121429 lua_state (), calling_context::select_relation_members,
14131430 " select_relation_members" , 1 };
1431+
14141432 m_after_nodes = prepared_lua_function_t {lua_state (), calling_context::main,
14151433 " after_nodes" };
14161434 m_after_ways = prepared_lua_function_t {lua_state (), calling_context::main,
0 commit comments