@@ -126,15 +126,14 @@ prepared_lua_function_t::prepared_lua_function_t(lua_State *lua_state,
126
126
namespace {
127
127
128
128
void push_osm_object_to_lua_stack (lua_State *lua_state,
129
- osmium::OSMObject const &object,
130
- bool with_attributes)
129
+ osmium::OSMObject const &object)
131
130
{
132
131
assert (lua_state);
133
132
134
133
/* *
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).
138
137
*/
139
138
constexpr int const max_table_size = 10 ;
140
139
@@ -145,23 +144,21 @@ void push_osm_object_to_lua_stack(lua_State *lua_state,
145
144
luaX_add_table_str (lua_state, " type" ,
146
145
osmium::item_type_to_name (object.type ()));
147
146
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 ());
165
162
}
166
163
167
164
if (object.type () == osmium::item_type::way) {
@@ -308,8 +305,10 @@ void output_flex_t::check_context_and_state(char const *name,
308
305
char const *context, bool condition)
309
306
{
310
307
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);
313
312
}
314
313
315
314
if (lua_gettop (lua_state ()) > 1 ) {
@@ -320,7 +319,7 @@ void output_flex_t::check_context_and_state(char const *name,
320
319
int output_flex_t::app_get_bbox ()
321
320
{
322
321
check_context_and_state (
323
- " get_bbox" , " process_node /way/relation() functions " ,
322
+ " get_bbox" , " node /way/relation" ,
324
323
m_calling_context != calling_context::process_node &&
325
324
m_calling_context != calling_context::process_way &&
326
325
m_calling_context != calling_context::process_relation);
@@ -370,7 +369,7 @@ int output_flex_t::app_get_bbox()
370
369
371
370
int output_flex_t::app_as_point ()
372
371
{
373
- check_context_and_state (" as_point" , " process_node() function " ,
372
+ check_context_and_state (" as_point" , " node " ,
374
373
m_calling_context != calling_context::process_node);
375
374
376
375
auto *geom = create_lua_geometry_object (lua_state ());
@@ -381,7 +380,7 @@ int output_flex_t::app_as_point()
381
380
382
381
int output_flex_t::app_as_linestring ()
383
382
{
384
- check_context_and_state (" as_linestring" , " process_way() function " ,
383
+ check_context_and_state (" as_linestring" , " way " ,
385
384
m_calling_context != calling_context::process_way);
386
385
387
386
m_way_cache.add_nodes (middle ());
@@ -394,7 +393,7 @@ int output_flex_t::app_as_linestring()
394
393
395
394
int output_flex_t::app_as_polygon ()
396
395
{
397
- check_context_and_state (" as_polygon" , " process_way() function " ,
396
+ check_context_and_state (" as_polygon" , " way " ,
398
397
m_calling_context != calling_context::process_way);
399
398
400
399
m_way_cache.add_nodes (middle ());
@@ -408,7 +407,7 @@ int output_flex_t::app_as_polygon()
408
407
int output_flex_t::app_as_multipoint ()
409
408
{
410
409
check_context_and_state (
411
- " as_multipoint" , " process_node /relation() functions " ,
410
+ " as_multipoint" , " node /relation" ,
412
411
m_calling_context != calling_context::process_node &&
413
412
m_calling_context != calling_context::process_relation);
414
413
@@ -426,10 +425,10 @@ int output_flex_t::app_as_multipoint()
426
425
427
426
int output_flex_t::app_as_multilinestring ()
428
427
{
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);
433
432
434
433
if (m_calling_context == calling_context::process_way) {
435
434
m_way_cache.add_nodes (middle ());
@@ -450,10 +449,10 @@ int output_flex_t::app_as_multilinestring()
450
449
451
450
int output_flex_t::app_as_multipolygon ()
452
451
{
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);
457
456
458
457
if (m_calling_context == calling_context::process_way) {
459
458
m_way_cache.add_nodes (middle ());
@@ -476,9 +475,9 @@ int output_flex_t::app_as_multipolygon()
476
475
477
476
int output_flex_t::app_as_geometrycollection ()
478
477
{
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);
482
481
483
482
m_relation_cache.add_members (middle ());
484
483
@@ -692,8 +691,7 @@ int output_flex_t::table_insert()
692
691
lua_pushboolean (lua_state (), false );
693
692
lua_pushstring (lua_state (), " null value in not null column." );
694
693
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);
697
695
table_connection.increment_not_null_error_counter ();
698
696
return 4 ;
699
697
}
@@ -820,9 +818,7 @@ void output_flex_t::call_lua_function(prepared_lua_function_t func,
820
818
m_calling_context = func.context ();
821
819
822
820
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
826
822
827
823
luaX_set_context (lua_state (), this );
828
824
if (luaX_pcall (lua_state (), 1 , func.nresults ())) {
@@ -1053,36 +1049,45 @@ void output_flex_t::wait()
1053
1049
1054
1050
void output_flex_t::node_add (osmium::Node const &node)
1055
1051
{
1056
- if (!m_process_node) {
1052
+ auto const &func =
1053
+ node.tags ().empty () ? m_process_untagged_node : m_process_node;
1054
+
1055
+ if (!func) {
1057
1056
return ;
1058
1057
}
1059
1058
1060
1059
m_context_node = &node;
1061
- get_mutex_and_call_lua_function (m_process_node , node);
1060
+ get_mutex_and_call_lua_function (func , node);
1062
1061
m_context_node = nullptr ;
1063
1062
}
1064
1063
1065
1064
void output_flex_t::way_add (osmium::Way *way)
1066
1065
{
1067
1066
assert (way);
1068
1067
1069
- if (!m_process_way) {
1068
+ auto const &func =
1069
+ way->tags ().empty () ? m_process_untagged_way : m_process_way;
1070
+
1071
+ if (!func) {
1070
1072
return ;
1071
1073
}
1072
1074
1073
1075
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 ());
1075
1077
}
1076
1078
1077
1079
void output_flex_t::relation_add (osmium::Relation const &relation)
1078
1080
{
1079
- if (!m_process_relation) {
1081
+ auto const &func = relation.tags ().empty () ? m_process_untagged_relation
1082
+ : m_process_relation;
1083
+
1084
+ if (!func) {
1080
1085
return ;
1081
1086
}
1082
1087
1083
1088
m_relation_cache.init (relation);
1084
1089
select_relation_members ();
1085
- get_mutex_and_call_lua_function (m_process_relation , relation);
1090
+ get_mutex_and_call_lua_function (func , relation);
1086
1091
}
1087
1092
1088
1093
void 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,
1177
1182
m_area_buffer(1024 , osmium::memory::Buffer::auto_grow::yes),
1178
1183
m_process_node(other->m_process_node), m_process_way(other->m_process_way),
1179
1184
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),
1180
1188
m_select_relation_members(other->m_select_relation_members),
1181
1189
m_after_nodes(other->m_after_nodes), m_after_ways(other->m_after_ways),
1182
1190
m_after_relations(other->m_after_relations)
@@ -1408,9 +1416,19 @@ void output_flex_t::init_lua(std::string const &filename,
1408
1416
lua_state (), calling_context::process_way, " process_way" };
1409
1417
m_process_relation = prepared_lua_function_t {
1410
1418
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
+
1411
1428
m_select_relation_members = prepared_lua_function_t {
1412
1429
lua_state (), calling_context::select_relation_members,
1413
1430
" select_relation_members" , 1 };
1431
+
1414
1432
m_after_nodes = prepared_lua_function_t {lua_state (), calling_context::main,
1415
1433
" after_nodes" };
1416
1434
m_after_ways = prepared_lua_function_t {lua_state (), calling_context::main,
0 commit comments