Libosmium  2.13.0
Fast and flexible C++ library for working with OpenStreetMap data
relations_manager.hpp
Go to the documentation of this file.
1 #ifndef OSMIUM_RELATIONS_RELATIONS_MANAGER_HPP
2 #define OSMIUM_RELATIONS_RELATIONS_MANAGER_HPP
3 
4 /*
5 
6 This file is part of Osmium (http://osmcode.org/libosmium).
7 
8 Copyright 2013-2017 Jochen Topf <jochen@topf.org> and others (see README).
9 
10 Boost Software License - Version 1.0 - August 17th, 2003
11 
12 Permission is hereby granted, free of charge, to any person or organization
13 obtaining a copy of the software and accompanying documentation covered by
14 this license (the "Software") to use, reproduce, display, distribute,
15 execute, and transmit the Software, and to prepare derivative works of the
16 Software, and to permit third-parties to whom the Software is furnished to
17 do so, all subject to the following:
18 
19 The copyright notices in the Software and this entire statement, including
20 the above license grant, this restriction and the following disclaimer,
21 must be included in all copies of the Software, in whole or in part, and
22 all derivative works of the Software, unless such copies or derivative
23 works are solely in the form of machine-executable object code generated by
24 a source language processor.
25 
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32 DEALINGS IN THE SOFTWARE.
33 
34 */
35 
36 #include <algorithm>
37 #include <cassert>
38 #include <cstddef>
39 #include <cstdint>
40 #include <cstring>
41 #include <stdexcept>
42 #include <type_traits>
43 #include <vector>
44 
45 #include <osmium/handler.hpp>
47 #include <osmium/memory/buffer.hpp>
49 #include <osmium/osm/item_type.hpp>
50 #include <osmium/osm/relation.hpp>
51 #include <osmium/osm/tag.hpp>
52 #include <osmium/osm/way.hpp>
57 #include <osmium/tags/taglist.hpp>
59 
60 namespace osmium {
61 
62  namespace relations {
63 
75 
76  // All relations and members we are interested in will be kept
77  // in here.
79 
82 
87 
90 
91  public:
92 
94  m_stash(),
95  m_relations_db(m_stash),
96  m_member_nodes_db(m_stash, m_relations_db),
97  m_member_ways_db(m_stash, m_relations_db),
98  m_member_relations_db(m_stash, m_relations_db),
99  m_output() {
100  }
101 
104  return m_relations_db;
105  }
106 
109  return m_member_nodes_db;
110  }
111 
114  return m_member_nodes_db;
115  }
116 
119  return m_member_ways_db;
120  }
121 
124  return m_member_ways_db;
125  }
126 
129  return m_member_relations_db;
130  }
131 
134  return m_member_relations_db;
135  }
136 
144  switch (type) {
146  return m_member_nodes_db;
148  return m_member_ways_db;
150  return m_member_relations_db;
151  default:
152  break;
153  }
154  throw std::logic_error{"Should not be here."};
155  }
156 
164  switch (type) {
166  return m_member_nodes_db;
168  return m_member_ways_db;
170  return m_member_relations_db;
171  default:
172  break;
173  }
174  throw std::logic_error{"Should not be here."};
175  }
176 
183  const osmium::OSMObject* get_member_object(const osmium::RelationMember& member) const noexcept {
184  if (member.ref() == 0) {
185  return nullptr;
186  }
187  return member_database(member.type()).get_object(member.ref());
188  }
189 
198  if (id == 0) {
199  return nullptr;
200  }
201  return member_nodes_database().get(id);
202  }
203 
212  if (id == 0) {
213  return nullptr;
214  }
215  return member_ways_database().get(id);
216  }
217 
226  if (id == 0) {
227  return nullptr;
228  }
229  return member_relations_database().get(id);
230  }
231 
238  m_member_nodes_db.prepare_for_lookup();
239  m_member_ways_db.prepare_for_lookup();
240  m_member_relations_db.prepare_for_lookup();
241  }
242 
247  return {
248  m_relations_db.used_memory(),
249  m_member_nodes_db.used_memory()
250  + m_member_ways_db.used_memory()
251  + m_member_relations_db.used_memory(),
252  m_stash.used_memory()
253  };
254  }
255 
258  return m_output.buffer();
259  }
260 
262  void set_callback(const std::function<void(osmium::memory::Buffer&&)>& callback) {
263  m_output.set_callback(callback);
264  }
265 
267  void flush_output() {
268  m_output.flush();
269  }
270 
272  void possibly_flush() {
273  m_output.possibly_flush();
274  }
275 
278  return m_output.read();
279  }
280 
281  }; // class RelationsManagerBase
282 
302  template <typename TManager, bool TNodes, bool TWays, bool TRelations, bool TCheckOrder = true>
304 
306 
308 
310 
311  static bool wanted_type(osmium::item_type type) noexcept {
312  return (TNodes && type == osmium::item_type::node) ||
313  (TWays && type == osmium::item_type::way) ||
314  (TRelations && type == osmium::item_type::relation);
315  }
316 
326  bool new_relation(const osmium::Relation& /*relation*/) const noexcept {
327  return true;
328  }
329 
340  bool new_member(const osmium::Relation& /*relation*/, const osmium::RelationMember& /*member*/, std::size_t /*n*/) const noexcept {
341  return true;
342  }
343 
350  void complete_relation(const osmium::Relation& /*relation*/) const noexcept {
351  }
352 
360  void before_node(const osmium::Node& /*node*/) const noexcept {
361  }
362 
370  void node_not_in_any_relation(const osmium::Node& /*node*/) const noexcept {
371  }
372 
380  void after_node(const osmium::Node& /*node*/) const noexcept {
381  }
382 
390  void before_way(const osmium::Way& /*way*/) const noexcept {
391  }
392 
400  void way_not_in_any_relation(const osmium::Way& /*way*/) const noexcept {
401  }
402 
410  void after_way(const osmium::Way& /*way*/) const noexcept {
411  }
412 
420  void before_relation(const osmium::Relation& /*relation*/) const noexcept {
421  }
422 
430  void relation_not_in_any_relation(const osmium::Relation& /*relation*/) const noexcept {
431  }
432 
440  void after_relation(const osmium::Relation& /*relation*/) const noexcept {
441  }
442 
443  TManager& derived() noexcept {
444  return *static_cast<TManager*>(this);
445  }
446 
448  derived().complete_relation(*rel_handle);
449  possibly_flush();
450 
451  for (const auto& member : rel_handle->members()) {
452  if (member.ref() != 0) {
453  member_database(member.type()).remove(member.ref(), rel_handle->id());
454  }
455  }
456 
457  rel_handle.remove();
458  }
459 
460  public:
461 
464  m_check_order_handler(),
465  m_handler_pass2(*this) {
466  }
467 
471  SecondPassHandler<RelationsManager>& handler(const std::function<void(osmium::memory::Buffer&&)>& callback = nullptr) {
472  set_callback(callback);
473  return m_handler_pass2;
474  }
475 
487  if (derived().new_relation(relation)) {
488  auto rel_handle = relations_database().add(relation);
489 
490  std::size_t n = 0;
491  for (auto& member : rel_handle->members()) {
492  if (wanted_type(member.type()) &&
493  derived().new_member(relation, member, n)) {
494  member_database(member.type()).track(rel_handle, member.ref(), n);
495  } else {
496  member.set_ref(0); // set member id to zero to indicate we are not interested
497  }
498  ++n;
499  }
500  }
501  }
502 
504  if (TNodes) {
505  m_check_order_handler.node(node);
506  derived().before_node(node);
507  const bool added = member_nodes_database().add(node, [this](RelationHandle& rel_handle) {
508  handle_complete_relation(rel_handle);
509  });
510  if (! added) {
511  derived().node_not_in_any_relation(node);
512  }
513  derived().after_node(node);
514  possibly_flush();
515  }
516  }
517 
518  void handle_way(const osmium::Way& way) {
519  if (TWays) {
520  m_check_order_handler.way(way);
521  derived().before_way(way);
522  const bool added = member_ways_database().add(way, [this](RelationHandle& rel_handle) {
523  handle_complete_relation(rel_handle);
524  });
525  if (! added) {
526  derived().way_not_in_any_relation(way);
527  }
528  derived().after_way(way);
529  possibly_flush();
530  }
531  }
532 
534  if (TRelations) {
535  m_check_order_handler.relation(relation);
536  derived().before_relation(relation);
537  const bool added = member_relations_database().add(relation, [this](RelationHandle& rel_handle) {
538  handle_complete_relation(rel_handle);
539  });
540  if (! added) {
541  derived().relation_not_in_any_relation(relation);
542  }
543  derived().after_relation(relation);
544  possibly_flush();
545  }
546  }
547 
556  template <typename TFunc>
557  void for_each_incomplete_relation(TFunc&& func) {
558  relations_database().for_each_relation(std::forward<TFunc>(func));
559  }
560 
561  }; // class RelationsManager
562 
563  } // namespace relations
564 
565 } // namespace osmium
566 
567 #endif // OSMIUM_RELATIONS_RELATIONS_MANAGER_HPP
void remove()
Definition: relations_database.hpp:274
std::size_t used_memory() const noexcept
Definition: members_database.hpp:186
void handle_node(const osmium::Node &node)
Definition: relations_manager.hpp:503
void set_callback(const callback_func_type &callback=nullptr) noexcept
Definition: callback_buffer.hpp:139
type
Definition: entity_bits.hpp:63
osmium::memory::Buffer read()
Return the contents of the output buffer.
Definition: relations_manager.hpp:277
void flush_output()
Flush the output buffer.
Definition: relations_manager.hpp:267
void way(const osmium::Way &) const noexcept
Definition: handler.hpp:81
RelationMemberList & members()
Get a reference to the member list.
Definition: relation.hpp:186
relations_manager_memory_usage used_memory() const noexcept
Definition: relations_manager.hpp:246
Definition: relations_manager.hpp:74
void node(const osmium::Node &) const noexcept
Definition: handler.hpp:78
osmium::memory::Buffer & buffer() noexcept
Access the output buffer.
Definition: relations_manager.hpp:257
void for_each_relation(TFunc &&func)
Definition: relations_database.hpp:323
const TObject * get(osmium::object_id_type id) const
Definition: members_database.hpp:394
bool add(const TObject &object, TFunc &&func)
Definition: members_database.hpp:357
item_type
Definition: item_type.hpp:43
Definition: relation.hpp:168
relations::MembersDatabase< osmium::Relation > m_member_relations_db
Definition: relations_manager.hpp:86
void handle_way(const osmium::Way &way)
Definition: relations_manager.hpp:518
osmium::memory::Buffer & buffer() noexcept
Definition: callback_buffer.hpp:128
Definition: handler.hpp:71
relations::MembersDatabase< osmium::Way > m_member_ways_db
Definition: relations_manager.hpp:85
std::size_t used_memory() const noexcept
Definition: item_stash.hpp:198
void possibly_flush()
Definition: callback_buffer.hpp:165
bool new_member(const osmium::Relation &, const osmium::RelationMember &, std::size_t) const noexcept
Definition: relations_manager.hpp:340
SecondPassHandler< RelationsManager > m_handler_pass2
Definition: relations_manager.hpp:309
void node_not_in_any_relation(const osmium::Node &) const noexcept
Definition: relations_manager.hpp:370
std::size_t used_memory() const noexcept
Definition: relations_database.hpp:144
TManager & derived() noexcept
Definition: relations_manager.hpp:443
Definition: way.hpp:72
Definition: manager_util.hpp:64
void before_way(const osmium::Way &) const noexcept
Definition: relations_manager.hpp:390
const osmium::Relation * get_member_relation(osmium::object_id_type id) const noexcept
Definition: relations_manager.hpp:225
SecondPassHandler< RelationsManager > & handler(const std::function< void(osmium::memory::Buffer &&)> &callback=nullptr)
Definition: relations_manager.hpp:471
Definition: item_stash.hpp:57
void way_not_in_any_relation(const osmium::Way &) const noexcept
Definition: relations_manager.hpp:400
const osmium::relations::MembersDatabase< osmium::Way > & member_ways_database() const noexcept
Access the internal database containing member ways.
Definition: relations_manager.hpp:123
typename std::conditional< true, osmium::handler::CheckOrder, osmium::handler::Handler >::type check_order_handler
Definition: relations_manager.hpp:305
osmium::ItemStash m_stash
Definition: relations_manager.hpp:78
Definition: relation.hpp:57
osmium::relations::MembersDatabase< osmium::Relation > & member_relations_database() noexcept
Access the internal database containing member relations.
Definition: relations_manager.hpp:128
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
void relation(const osmium::Relation &relation)
Definition: relations_manager.hpp:486
osmium::memory::Buffer read()
Definition: callback_buffer.hpp:176
RelationsManagerBase()
Definition: relations_manager.hpp:93
bool new_relation(const osmium::Relation &) const noexcept
Definition: relations_manager.hpp:326
void handle_complete_relation(RelationHandle &rel_handle)
Definition: relations_manager.hpp:447
void after_way(const osmium::Way &) const noexcept
Definition: relations_manager.hpp:410
osmium::relations::MembersDatabase< osmium::Node > & member_nodes_database() noexcept
Access the internal database containing member nodes.
Definition: relations_manager.hpp:108
int64_t object_id_type
Type for OSM object (node, way, or relation) IDs.
Definition: types.hpp:45
void possibly_flush()
Flush the output buffer if it is full.
Definition: relations_manager.hpp:272
relations::MembersDatabaseCommon & member_database(osmium::item_type type)
Definition: relations_manager.hpp:143
const osmium::relations::MembersDatabase< osmium::Node > & member_nodes_database() const noexcept
Access the internal database containing member nodes.
Definition: relations_manager.hpp:113
Definition: relations_database.hpp:208
const osmium::Way * get_member_way(osmium::object_id_type id) const noexcept
Definition: relations_manager.hpp:211
void prepare_for_lookup()
Definition: relations_manager.hpp:237
osmium::relations::RelationsDatabase & relations_database() noexcept
Access the internal RelationsDatabase.
Definition: relations_manager.hpp:103
Definition: relations_database.hpp:82
object_id_type id() const noexcept
Get ID of this object.
Definition: object.hpp:126
const relations::MembersDatabaseCommon & member_database(osmium::item_type type) const
Definition: relations_manager.hpp:163
void relation(const osmium::Relation &) const noexcept
Definition: handler.hpp:84
void flush()
Definition: callback_buffer.hpp:151
Definition: buffer.hpp:98
RelationHandle add(const osmium::Relation &relation)
Definition: relations_database.hpp:317
Definition: node.hpp:48
void before_node(const osmium::Node &) const noexcept
Definition: relations_manager.hpp:360
osmium::memory::CallbackBuffer m_output
Output buffer.
Definition: relations_manager.hpp:89
relations::MembersDatabase< osmium::Node > m_member_nodes_db
Databases of all members we are interested in.
Definition: relations_manager.hpp:84
const osmium::Node * get_member_node(osmium::object_id_type id) const noexcept
Definition: relations_manager.hpp:197
relations::RelationsDatabase m_relations_db
Database of all relations we are interested in.
Definition: relations_manager.hpp:81
RelationsManager()
Definition: relations_manager.hpp:462
static bool wanted_type(osmium::item_type type) noexcept
Definition: relations_manager.hpp:311
const osmium::OSMObject * get_member_object(const osmium::RelationMember &member) const noexcept
Definition: relations_manager.hpp:183
Definition: members_database.hpp:62
void after_node(const osmium::Node &) const noexcept
Definition: relations_manager.hpp:380
Definition: callback_buffer.hpp:70
Definition: relations_manager.hpp:303
void before_relation(const osmium::Relation &) const noexcept
Definition: relations_manager.hpp:420
check_order_handler m_check_order_handler
Definition: relations_manager.hpp:307
const osmium::relations::MembersDatabase< osmium::Relation > & member_relations_database() const noexcept
Access the internal database containing member relations.
Definition: relations_manager.hpp:133
void prepare_for_lookup()
Definition: members_database.hpp:258
void handle_relation(const osmium::Relation &relation)
Definition: relations_manager.hpp:533
void relation_not_in_any_relation(const osmium::Relation &) const noexcept
Definition: relations_manager.hpp:430
void for_each_incomplete_relation(TFunc &&func)
Definition: relations_manager.hpp:557
void after_relation(const osmium::Relation &) const noexcept
Definition: relations_manager.hpp:440
void complete_relation(const osmium::Relation &) const noexcept
Definition: relations_manager.hpp:350
void set_callback(const std::function< void(osmium::memory::Buffer &&)> &callback)
Set the callback called when the output buffer is full.
Definition: relations_manager.hpp:262
osmium::relations::MembersDatabase< osmium::Way > & member_ways_database() noexcept
Access the internal database containing member ways.
Definition: relations_manager.hpp:118
Definition: object.hpp:64