@@ -16,15 +16,25 @@ enum : int
1616 MAX_ADMINLEVEL = 15
1717};
1818
19+ /* *
20+ * Returns the tag specific name, if applicable.
21+ *
22+ * OSM tags may contain name tags that refer to one of the other tags
23+ * in the tag set. For example, the name of a bridge is tagged as
24+ * bridge:name=Foo to not confuse it with the name of the highway
25+ * going over the bridge. This matcher checks if a tag is such a name tag
26+ * for the given tag key and returns the the name key without the prefix
27+ * if it matches.
28+ */
1929class DomainMatcher
2030{
2131public:
2232 DomainMatcher (char const *cls) : m_domain(cls), m_len(strlen(cls)) {}
2333
2434 char const *operator ()(osmium::Tag const &t) const noexcept
2535 {
26- if (strncmp (t.key (), m_domain, m_len) == 0 &&
27- strncmp (t.key () + m_len, " :name" , 5 ) == 0 &&
36+ if (std:: strncmp (t.key (), m_domain, m_len) == 0 &&
37+ std:: strncmp (t.key () + m_len, " :name" , 5 ) == 0 &&
2838 (t.key ()[m_len + 5 ] == ' \0 ' || t.key ()[m_len + 5 ] == ' :' )) {
2939 return t.key () + m_len + 6 ;
3040 }
@@ -418,14 +428,14 @@ void gazetteer_style_t::filter_main_tags(bool is_named,
418428
419429 if (flags & SF_MAIN_NAMED_KEY) {
420430 return !std::any_of (tags.begin (), tags.end (),
421- DomainMatcher ( std::get<0 >(t)) );
431+ DomainMatcher{ std::get<0 >(t)} );
422432 }
423433
424434 return false ;
425435 });
426436
427437 // any non-fallback mains left?
428- bool has_primary =
438+ bool const has_primary =
429439 std::any_of (m_main.begin (), mend, [](pmaintag_t const &t) {
430440 return !(std::get<2 >(t) & SF_MAIN_FALLBACK);
431441 });
@@ -444,122 +454,114 @@ void gazetteer_style_t::filter_main_tags(bool is_named,
444454 }
445455}
446456
447- bool gazetteer_style_t::copy_out (osmium::OSMObject const &o,
448- std::string const &geom, copy_mgr_t &buffer)
457+ void gazetteer_style_t::copy_out (osmium::OSMObject const &o,
458+ std::string const &geom,
459+ copy_mgr_t &buffer) const
449460{
450- for (auto const &main : m_main) {
451- copy_out_maintag (main, o, geom, buffer);
452- }
453-
454- return !m_main.empty ();
455- }
456-
457- void gazetteer_style_t::copy_out_maintag (pmaintag_t const &tag,
458- osmium::OSMObject const &o,
459- std::string const &geom,
460- copy_mgr_t &buffer)
461- {
462- buffer.new_line ();
463- // osm_id
464- buffer.add_column (o.id ());
465- // osm_type
466- char const osm_type[2 ] = {
467- (char )toupper (osmium::item_type_to_char (o.type ())), ' \0 ' };
468- buffer.add_column (osm_type);
469- // class
470- buffer.add_column (std::get<0 >(tag));
471- // type
472- buffer.add_column (std::get<1 >(tag));
473- // names
474- if (std::get<2 >(tag) & SF_MAIN_NAMED_KEY) {
475- DomainMatcher m (std::get<0 >(tag));
476- buffer.new_hash ();
477- for (auto const &t : o.tags ()) {
478- char const *k = m (t);
479- if (k) {
480- buffer.add_hash_elem (k, t.value ());
481- }
482- }
483- buffer.finish_hash ();
484- } else {
485- bool first = true ;
486- // operator will be ignored on anything but these classes
487- if (m_operator && (std::get<2 >(tag) & SF_MAIN_OPERATOR)) {
461+ for (auto const &tag : m_main) {
462+ buffer.prepare ();
463+ // osm_id
464+ buffer.add_column (o.id ());
465+ // osm_type
466+ char const osm_type[2 ] = {
467+ (char )toupper (osmium::item_type_to_char (o.type ())), ' \0 ' };
468+ buffer.add_column (osm_type);
469+ // class
470+ buffer.add_column (std::get<0 >(tag));
471+ // type
472+ buffer.add_column (std::get<1 >(tag));
473+ // names
474+ if (std::get<2 >(tag) & SF_MAIN_NAMED_KEY) {
475+ DomainMatcher m{std::get<0 >(tag)};
488476 buffer.new_hash ();
489- buffer.add_hash_elem (" operator" , m_operator);
490- first = false ;
491- }
492- for (auto const &entry : m_names) {
493- if (first) {
477+ for (auto const &t : o.tags ()) {
478+ char const *k = m (t);
479+ if (k) {
480+ buffer.add_hash_elem (k, t.value ());
481+ }
482+ }
483+ buffer.finish_hash ();
484+ } else {
485+ bool first = true ;
486+ // operator will be ignored on anything but these classes
487+ if (m_operator && (std::get<2 >(tag) & SF_MAIN_OPERATOR)) {
494488 buffer.new_hash ();
489+ buffer.add_hash_elem (" operator" , m_operator);
495490 first = false ;
496491 }
492+ for (auto const &entry : m_names) {
493+ if (first) {
494+ buffer.new_hash ();
495+ first = false ;
496+ }
497497
498- buffer.add_hash_elem (entry.first , entry.second );
499- }
498+ buffer.add_hash_elem (entry.first , entry.second );
499+ }
500500
501- if (first) {
501+ if (first) {
502+ buffer.add_null_column ();
503+ } else {
504+ buffer.finish_hash ();
505+ }
506+ }
507+ // admin_level
508+ buffer.add_column (m_admin_level);
509+ // address
510+ if (m_address.empty ()) {
502511 buffer.add_null_column ();
503512 } else {
504- buffer.finish_hash ();
505- }
506- }
507- // admin_level
508- buffer.add_column (m_admin_level);
509- // address
510- if (m_address.empty ()) {
511- buffer.add_null_column ();
512- } else {
513- buffer.new_hash ();
514- for (auto const &a : m_address) {
515- if (strcmp (a.first , " tiger:county" ) == 0 ) {
516- std::string term;
517- auto *end = strchr (a.second , ' ,' );
518- if (end) {
519- auto len = (std::string::size_type)(end - a.second );
520- term = std::string (a.second , len);
513+ buffer.new_hash ();
514+ for (auto const &a : m_address) {
515+ if (strcmp (a.first , " tiger:county" ) == 0 ) {
516+ std::string term;
517+ auto *end = strchr (a.second , ' ,' );
518+ if (end) {
519+ auto len = (std::string::size_type)(end - a.second );
520+ term = std::string (a.second , len);
521+ } else {
522+ term = a.second ;
523+ }
524+ term += " county" ;
525+ buffer.add_hash_elem (a.first , term);
521526 } else {
522- term = a.second ;
527+ buffer. add_hash_elem (a. first , a.second ) ;
523528 }
524- term += " county" ;
525- buffer.add_hash_elem (a.first , term);
526- } else {
527- buffer.add_hash_elem (a.first , a.second );
528529 }
530+ buffer.finish_hash ();
529531 }
530- buffer.finish_hash ();
531- }
532- // extra tags
533- if (m_extra.empty () && m_metadata_fields.none ()) {
534- buffer.add_null_column ();
535- } else {
536- buffer.new_hash ();
537- for (auto const &entry : m_extra) {
538- buffer.add_hash_elem (entry.first , entry.second );
539- }
540- if (m_metadata_fields.version () && o.version ()) {
541- buffer.add_hstore_num_noescape <osmium::object_version_type>(
542- " osm_version" , o.version ());
543- }
544- if (m_metadata_fields.uid () && o.uid ()) {
545- buffer.add_hstore_num_noescape <osmium::user_id_type>(" osm_uid" ,
546- o.uid ());
547- }
548- if (m_metadata_fields.user () && o.user () && *(o.user ()) != ' \0 ' ) {
549- buffer.add_hash_elem (" osm_user" , o.user ());
550- }
551- if (m_metadata_fields.changeset () && o.changeset ()) {
552- buffer.add_hstore_num_noescape <osmium::changeset_id_type>(
553- " osm_changeset" , o.changeset ());
554- }
555- if (m_metadata_fields.timestamp () && o.timestamp ()) {
556- std::string timestamp = o.timestamp ().to_iso ();
557- buffer.add_hash_elem_noescape (" osm_timestamp" , timestamp.c_str ());
532+ // extra tags
533+ if (m_extra.empty () && m_metadata_fields.none ()) {
534+ buffer.add_null_column ();
535+ } else {
536+ buffer.new_hash ();
537+ for (auto const &entry : m_extra) {
538+ buffer.add_hash_elem (entry.first , entry.second );
539+ }
540+ if (m_metadata_fields.version () && o.version ()) {
541+ buffer.add_hstore_num_noescape <osmium::object_version_type>(
542+ " osm_version" , o.version ());
543+ }
544+ if (m_metadata_fields.uid () && o.uid ()) {
545+ buffer.add_hstore_num_noescape <osmium::user_id_type>(" osm_uid" ,
546+ o.uid ());
547+ }
548+ if (m_metadata_fields.user () && o.user () && *(o.user ()) != ' \0 ' ) {
549+ buffer.add_hash_elem (" osm_user" , o.user ());
550+ }
551+ if (m_metadata_fields.changeset () && o.changeset ()) {
552+ buffer.add_hstore_num_noescape <osmium::changeset_id_type>(
553+ " osm_changeset" , o.changeset ());
554+ }
555+ if (m_metadata_fields.timestamp () && o.timestamp ()) {
556+ std::string timestamp = o.timestamp ().to_iso ();
557+ buffer.add_hash_elem_noescape (" osm_timestamp" ,
558+ timestamp.c_str ());
559+ }
560+ buffer.finish_hash ();
558561 }
559- buffer.finish_hash ();
560- }
561- // add the geometry - encoding it to hex along the way
562- buffer.add_hex_geom (geom);
562+ // add the geometry - encoding it to hex along the way
563+ buffer.add_hex_geom (geom);
563564
564- buffer.finish_line ();
565+ buffer.finish_line ();
566+ }
565567}
0 commit comments