@@ -156,6 +156,54 @@ static char const *decode_to_delimiter(char const *src, std::string *dst)
156156}
157157
158158namespace {
159+
160+ /* *
161+ * Go through tags returned from a middle table, get the attributes from the
162+ * "osm_*" tags and add them to the builder.
163+ */
164+ template <typename T>
165+ void pgsql_get_attr_from_tags (char const *string, T *builder)
166+ {
167+ if (*string++ != ' {' ) {
168+ return ;
169+ }
170+
171+ std::string key;
172+ std::string val;
173+ std::string user;
174+ while (*string != ' }' ) {
175+ string = decode_to_delimiter (string, &key);
176+ // String points to the comma */
177+ ++string;
178+ string = decode_to_delimiter (string, &val);
179+
180+ if (key == " osm_version" ) {
181+ builder->set_version (val.c_str ());
182+ } else if (key == " osm_timestamp" ) {
183+ builder->set_timestamp (osmium::Timestamp{val});
184+ } else if (key == " osm_changeset" ) {
185+ builder->set_changeset (val.c_str ());
186+ } else if (key == " osm_uid" ) {
187+ builder->set_uid (val.c_str ());
188+ } else if (key == " osm_user" ) {
189+ user = val;
190+ }
191+
192+ // String points to the comma or closing '}' */
193+ if (*string == ' ,' ) {
194+ ++string;
195+ }
196+ }
197+
198+ // Must be done at the end, because after that call the builder might
199+ // become invalid due to buffer resizing.
200+ builder->set_user (user);
201+ }
202+
203+ /* *
204+ * Go through tags returned from a middle table, get all tags except the
205+ * pseudo-tags containing attributes and add them to the builder.
206+ */
159207template <typename T>
160208void pgsql_parse_tags (char const *string, osmium::memory::Buffer *buffer,
161209 T *obuilder)
@@ -173,7 +221,12 @@ void pgsql_parse_tags(char const *string, osmium::memory::Buffer *buffer,
173221 // String points to the comma */
174222 ++string;
175223 string = decode_to_delimiter (string, &val);
176- builder.add_tag (key, val);
224+
225+ if (key != " osm_version" && key != " osm_timestamp" &&
226+ key != " osm_changeset" && key != " osm_uid" && key != " osm_user" ) {
227+ builder.add_tag (key, val);
228+ }
229+
177230 // String points to the comma or closing '}' */
178231 if (*string == ' ,' ) {
179232 ++string;
@@ -443,6 +496,20 @@ void middle_pgsql_t::way_set(osmium::Way const &way)
443496 m_db_copy.finish_line ();
444497}
445498
499+ /* *
500+ * Build way in buffer from database results.
501+ */
502+ static void build_way (osmid_t id, pg_result_t const &res, int res_num,
503+ int offset, osmium::memory::Buffer *buffer)
504+ {
505+ osmium::builder::WayBuilder builder{*buffer};
506+ builder.set_id (id);
507+
508+ pgsql_get_attr_from_tags (res.get_value (res_num, offset + 1 ), &builder);
509+ pgsql_parse_nodes (res.get_value (res_num, offset + 0 ), buffer, &builder);
510+ pgsql_parse_tags (res.get_value (res_num, offset + 1 ), buffer, &builder);
511+ }
512+
446513bool middle_query_pgsql_t::way_get (osmid_t id,
447514 osmium::memory::Buffer *buffer) const
448515{
@@ -454,13 +521,7 @@ bool middle_query_pgsql_t::way_get(osmid_t id,
454521 return false ;
455522 }
456523
457- {
458- osmium::builder::WayBuilder builder{*buffer};
459- builder.set_id (id);
460-
461- pgsql_parse_nodes (res.get_value (0 , 0 ), buffer, &builder);
462- pgsql_parse_tags (res.get_value (0 , 1 ), buffer, &builder);
463- }
524+ build_way (id, res, 0 , 0 , buffer);
464525
465526 buffer->commit ();
466527
@@ -506,12 +567,7 @@ middle_query_pgsql_t::rel_members_get(osmium::Relation const &rel,
506567 // back to the list of ways given by the caller
507568 for (int j = 0 ; j < res.num_tuples (); ++j) {
508569 if (member.ref () == wayidspg[static_cast <std::size_t >(j)]) {
509- osmium::builder::WayBuilder builder{*buffer};
510- builder.set_id (member.ref ());
511-
512- pgsql_parse_nodes (res.get_value (j, 1 ), buffer, &builder);
513- pgsql_parse_tags (res.get_value (j, 2 ), buffer, &builder);
514-
570+ build_way (member.ref (), res, j, 1 , buffer);
515571 ++members_found;
516572 break ;
517573 }
@@ -588,6 +644,7 @@ bool middle_query_pgsql_t::relation_get(osmid_t id,
588644 osmium::builder::RelationBuilder builder{*buffer};
589645 builder.set_id (id);
590646
647+ pgsql_get_attr_from_tags (res.get_value (0 , 1 ), &builder);
591648 pgsql_parse_members (res.get_value (0 , 0 ), buffer, &builder);
592649 pgsql_parse_tags (res.get_value (0 , 1 ), buffer, &builder);
593650 }
0 commit comments