@@ -42,6 +42,7 @@ void gazetteer_style_t::clear()
4242 m_main.clear ();
4343 m_names.clear ();
4444 m_extra.clear ();
45+ m_metadata.clear ();
4546 m_address.clear ();
4647 m_operator = nullptr ;
4748 m_admin_level = MAX_ADMINLEVEL;
@@ -72,6 +73,11 @@ void gazetteer_style_t::load_style(std::string const &filename)
7273 }
7374}
7475
76+ void gazetteer_style_t::set_metadata (const bool enabled)
77+ {
78+ m_metadata_enabled = enabled;
79+ }
80+
7581gazetteer_style_t ::flag_t gazetteer_style_t::parse_flags (std::string const &str)
7682{
7783 flag_t out = 0 ;
@@ -349,6 +355,45 @@ void gazetteer_style_t::process_tags(osmium::OSMObject const &o)
349355 } else if (postcode_fallback && postcode) {
350356 m_main.emplace_back (" place" , " postcode" , SF_MAIN | SF_MAIN_FALLBACK);
351357 }
358+
359+ // add metadata fields as tags if enabled
360+ if (m_metadata_enabled) {
361+ if (o.version ()) {
362+ add_metadata_field_num<osmium::object_version_type>(" osm_version" , o.version ());
363+ }
364+ if (o.uid ()) {
365+ add_metadata_field_num<osmium::user_id_type>(" osm_uid" , o.uid ());
366+ }
367+
368+ if (o.user () && *(o.user ()) != ' \0 ' ) {
369+ std::string username = o.user ();
370+ add_metadata_field (" osm_user" , std::move (username));
371+ }
372+
373+ if (o.changeset ()) {
374+ add_metadata_field_num<osmium::changeset_id_type>(" osm_changeset" , o.changeset ());
375+ }
376+
377+ if (o.timestamp ()) {
378+ add_metadata_field (" osm_timestamp" , std::move (o.timestamp ().to_iso ()));
379+ }
380+ }
381+ }
382+
383+ void gazetteer_style_t::add_metadata_field (const std::string&& field, const std::string&& value) {
384+ // We have to work with std::string, not char* because metadata fields converted to char*
385+ // would require an allocation on heap and a cleanup at the end.
386+ flag_t flag = find_flag (field.c_str (), value.c_str ());
387+ if (flag & SF_EXTRA) {
388+ m_metadata.emplace_back (std::move (field), std::move (value));
389+ }
390+ }
391+
392+ template <typename T>
393+ void gazetteer_style_t::add_metadata_field_num (const std::string&& field, const T value) {
394+ // This method is not linked to from outside this class. Therefore, it can stay in the source file.
395+ std::string value_str = std::to_string (value);
396+ add_metadata_field (std::move (field), std::move (value_str));
352397}
353398
354399void gazetteer_style_t::copy_out (osmium::OSMObject const &o,
@@ -456,13 +501,16 @@ bool gazetteer_style_t::copy_out_maintag(pmaintag_t const &tag,
456501 buffer.finish_hash ();
457502 }
458503 // extra tags
459- if (m_extra.empty ()) {
504+ if (m_extra.empty () && m_metadata. empty () ) {
460505 buffer.add_null_column ();
461506 } else {
462507 buffer.new_hash ();
463508 for (auto const &entry : m_extra) {
464509 buffer.add_hash_elem (entry.first , entry.second );
465510 }
511+ for (auto const &entry : m_metadata) {
512+ buffer.add_hash_elem (entry.first , entry.second );
513+ }
466514 buffer.finish_hash ();
467515 }
468516 // add the geometry - encoding it to hex along the way
0 commit comments