44#include < iostream>
55#include < stdexcept>
66
7+ std::set<std::string> HierarchyItem::s_priority_types;
8+ std::set<std::string> HierarchyItem::s_skip_types;
9+
10+ static std::string allowed_type_chars = " abcdefghijklmnopqrstuvwxyz_-" ;
11+
712HierarchyItem::HierarchyItem (const pqxx::row &row)
813{
914 m_id = row[" place_id" ].as <hindex>(0 );
1015 m_linked_id = row[" linked_place_id" ].as <hindex>(0 );
1116 m_parent_id = row[" parent_place_id" ].as <hindex>(0 );
1217 m_country = row[" country_code" ].as <std::string>(" " );
13- m_class = row[" class" ].as <std::string>(" " );
14- m_type = row[" type" ].as <std::string>(" " );
18+ m_type = geocoder_type (row[" class" ].as <std::string>(" " ), row[" type" ].as <std::string>(" " ));
1519 m_housenumber = row[" housenumber" ].as <std::string>(" " );
1620 m_postcode = row[" postcode" ].as <std::string>(" " );
1721 m_latitude = row[" latitude" ].as <float >(0 );
1822 m_longitude = row[" longitude" ].as <float >(0 );
1923
20- m_name = parse_to_map (row[" name" ].as <std::string>(" " ));
21- m_extra = parse_to_map (row[" extra" ].as <std::string>(" " ));
24+ m_data_name = parse_to_map (row[" name" ].as <std::string>(" " ));
25+ m_data_extra = parse_to_map (row[" extra" ].as <std::string>(" " ));
26+
27+ m_name = get_with_def (m_data_name, " name" );
28+ m_name_extra.clear ();
29+ if (!m_housenumber.empty ())
30+ {
31+ m_name_extra = m_name;
32+ m_name = m_housenumber;
33+ }
34+
35+ if (m_name_extra.empty ())
36+ m_name_extra = get_with_def (m_data_extra, " brand" );
37+ }
38+
39+ bool HierarchyItem::keep () const
40+ {
41+ if (m_type.find_first_not_of (allowed_type_chars) != std::string::npos)
42+ {
43+ std::cout << " Dropping " << m_type << " \n " ;
44+ return false ;
45+ }
46+ if (s_skip_types.count (m_type) > 0 )
47+ return false ;
48+ return !m_name.empty () || s_priority_types.count (m_type) > 0 ;
2249}
2350
2451void HierarchyItem::add_child (std::shared_ptr<HierarchyItem> child)
2552{
2653 m_children.push_back (child);
54+ child->set_parent (m_id);
2755}
2856
2957void HierarchyItem::add_linked (std::shared_ptr<HierarchyItem> linked)
3058{
31- m_name.insert (linked->m_name .begin (), linked->m_name .end ());
32- m_extra.insert (linked->m_extra .begin (), linked->m_extra .end ());
33- // if (m_class != linked->m_class || m_type != linked->m_type)
34- // std::cout << "Mismatch between linked objects: " << m_id << ", " << m_class << ", " <<
35- // m_type
36- // << " -> " << linked->m_id << ", " << linked->m_class << ", " << linked->m_type
37- // << "\n";
59+ m_data_name.insert (linked->m_data_name .begin (), linked->m_data_name .end ());
60+ m_data_extra.insert (linked->m_data_extra .begin (), linked->m_data_extra .end ());
3861}
3962
40- void HierarchyItem::set_parent (hindex parent)
63+ void HierarchyItem::set_parent (hindex parent, bool force )
4164{
42- if (m_parent_id != parent && m_parent_id != 0 )
65+ if (!force && m_parent_id != parent && m_parent_id != 0 && parent != 0 )
4366 {
4467 std::cout << " New parent (" << parent << " ) for " << m_id << " does not match old one ("
4568 << m_parent_id << " )\n " ;
4669 throw std::runtime_error (" Mismatch between new and old parent" );
4770 }
4871 m_parent_id = parent;
49- for (auto c : m_children)
50- c->set_parent (m_id);
72+ // for (auto c : m_children)
73+ // c->set_parent(m_id, force);
74+ }
75+
76+ void HierarchyItem::cleanup_children ()
77+ {
78+ // as a result of this run, children that are supposed to be kept are staying in children
79+ // property. all disposed ones are still pointed to via Hierarchy map, but should not be accessed
80+ // while moving along hierarchy for indexing or writing it
81+ std::deque<std::shared_ptr<HierarchyItem> > children;
82+ for (auto item : m_children)
83+ {
84+ item->cleanup_children ();
85+ if (item->keep ())
86+ children.push_back (item);
87+ else
88+ children.insert (children.end (), item->m_children .begin (), item->m_children .end ());
89+ }
90+ m_children = children;
91+
92+ // set parent, forced
93+ for (auto item : m_children)
94+ item->set_parent (m_id, true );
5195}
5296
5397sqlid HierarchyItem::index (sqlid idx, sqlid parent)
5498{
99+ if (!keep ())
100+ throw std::runtime_error (" Trying to index a location that was not supposed to be kept" );
55101 m_my_index = idx;
56102 m_parent_index = parent;
57103 ++idx;
@@ -63,27 +109,20 @@ sqlid HierarchyItem::index(sqlid idx, sqlid parent)
63109
64110void HierarchyItem::write (sqlite3pp::database &db) const
65111{
66- // primary data
67- std::string name = get_with_def (m_name, " name" );
68- std::string name_en = get_with_def (m_name, " name:en" );
69- std::string phone = get_with_def (m_extra, " phone" );
70- std::string website = get_with_def (m_extra, " website" );
112+ if (!keep ())
113+ throw std::runtime_error (" Trying to write a location that was not supposed to be kept" );
71114
72- std::string name_extra;
73- if (!m_housenumber.empty ())
74- {
75- name_extra = name;
76- name = m_housenumber;
77- }
115+ // primary data
116+ std::string name_en = get_with_def (m_data_name, " name:en" );
117+ std::string phone = get_with_def (m_data_extra, " phone" );
118+ std::string website = get_with_def (m_data_extra, " website" );
78119
79- if (name_extra.empty ())
80- name_extra = get_with_def (m_extra, " brand" );
81120 {
82121 sqlite3pp::command cmd (db, " INSERT INTO object_primary_tmp (id, postgres_id, name, name_extra, "
83122 " name_en, phone, postal_code, website, parent, longitude, "
84123 " latitude) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" );
85- cmd.binder () << m_my_index << (int )m_id << name << name_extra << name_en << phone << m_postcode
86- << website << m_parent_index << m_longitude << m_latitude;
124+ cmd.binder () << m_my_index << (int )m_id << m_name << m_name_extra << name_en << phone
125+ << m_postcode << website << m_parent_index << m_longitude << m_latitude;
87126 if (cmd.execute () != SQLITE_OK)
88127 std::cerr << " WriteSQL : error inserting primary data for " << m_id << " , " << m_my_index
89128 << " \n " ;
@@ -95,7 +134,7 @@ void HierarchyItem::write(sqlite3pp::database &db) const
95134 // = "INSERT INTO object_type_tmp (prim_id, type) VALUES (?, \"" + type + "\")";
96135 = " INSERT INTO object_type_tmp (prim_id, type) VALUES (?, ?)" ;
97136 sqlite3pp::command cmd (db, command.c_str ());
98- cmd.binder () << m_my_index << geocoder_type (m_class, m_type) ;
137+ cmd.binder () << m_my_index << m_type;
99138 if (cmd.execute () != SQLITE_OK)
100139 std::cerr << " WriteSQL: error inserting type for " << m_id << " , " << m_my_index << " \n " ;
101140 }
@@ -120,7 +159,7 @@ void HierarchyItem::print_branch(unsigned int offset) const
120159 std::cout << std::string (offset, ' ' ) << " - " << m_id << " " ;
121160 if (!m_housenumber.empty ())
122161 std::cout << " house " << m_housenumber << " " ;
123- for (const auto &i : m_name )
162+ for (const auto &i : m_data_name )
124163 std::cout << i.first << " : " << i.second << " " ;
125164 std::cout << " (" << m_my_index << " " << m_last_child_index - m_my_index << " : " << m_parent_id
126165 << " , " << m_country << " )\n " ;
0 commit comments