Libosmium  2.15.1
Fast and flexible C++ library for working with OpenStreetMap data
multipolygon_collector.hpp
Go to the documentation of this file.
1 #ifndef OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP
2 #define OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP
3 
4 /*
5 
6 This file is part of Osmium (https://osmcode.org/libosmium).
7 
8 Copyright 2013-2019 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 <osmium/area/stats.hpp>
37 #include <osmium/memory/buffer.hpp>
38 #include <osmium/osm/item_type.hpp>
39 #include <osmium/osm/location.hpp>
40 #include <osmium/osm/node_ref.hpp>
41 #include <osmium/osm/relation.hpp>
42 #include <osmium/osm/tag.hpp>
43 #include <osmium/osm/way.hpp>
45 
46 #include <algorithm>
47 #include <cstddef>
48 #include <cstring>
49 #include <vector>
50 
51 namespace osmium {
52 
53  namespace relations {
54  class RelationMeta;
55  } // namespace relations
56 
60  namespace area {
61 
76  template <typename TAssembler>
77  class MultipolygonCollector : public osmium::relations::Collector<MultipolygonCollector<TAssembler>, false, true, false> {
78 
80 
81  using assembler_config_type = typename TAssembler::config_type;
83 
85 
87 
88  enum {
89  initial_output_buffer_size = 1024ul * 1024ul
90  };
91 
92  enum {
93  max_buffer_size_for_flush = 100ul * 1024ul
94  };
95 
97  if (this->callback()) {
99  using std::swap;
100  swap(buffer, m_output_buffer);
101  this->callback()(std::move(buffer));
102  }
103  }
104 
108  }
109  }
110 
111  public:
112 
113  explicit MultipolygonCollector(const assembler_config_type& assembler_config) :
114  collector_type(),
115  m_assembler_config(assembler_config),
116  m_output_buffer(initial_output_buffer_size, osmium::memory::Buffer::auto_grow::yes) {
117  }
118 
119  const area_stats& stats() const noexcept {
120  return m_stats;
121  }
122 
129  bool keep_relation(const osmium::Relation& relation) const {
130  const char* type = relation.tags().get_value_by_key("type");
131 
132  // ignore relations without "type" tag
133  if (!type) {
134  return false;
135  }
136 
137  return (!std::strcmp(type, "multipolygon")) || (!std::strcmp(type, "boundary"));
138  }
139 
143  bool keep_member(const osmium::relations::RelationMeta& /*relation_meta*/, const osmium::RelationMember& member) const {
144  // We are only interested in members of type way.
145  return member.type() == osmium::item_type::way;
146  }
147 
155  // you need at least 4 nodes to make up a polygon
156  if (way.nodes().size() <= 3) {
157  return;
158  }
159  try {
160  if (!way.nodes().front().location() || !way.nodes().back().location()) {
161  throw osmium::invalid_location{"invalid location"};
162  }
163  if (way.ends_have_same_location()) {
164  // way is closed and has enough nodes, build simple multipolygon
165  TAssembler assembler{m_assembler_config};
166  assembler(way, m_output_buffer);
167  m_stats += assembler.stats();
169  }
170  } catch (const osmium::invalid_location&) {
171  // XXX ignore
172  }
173  }
174 
175  void complete_relation(osmium::relations::RelationMeta& relation_meta) {
176  const osmium::Relation& relation = this->get_relation(relation_meta);
177  const osmium::memory::Buffer& buffer = this->members_buffer();
178 
179  std::vector<const osmium::Way*> ways;
180  ways.reserve(relation.members().size());
181  for (const auto& member : relation.members()) {
182  if (member.ref() != 0) {
183  const size_t offset = this->get_offset(member.type(), member.ref());
184  ways.push_back(&buffer.get<const osmium::Way>(offset));
185  }
186  }
187 
188  try {
189  TAssembler assembler{m_assembler_config};
190  assembler(relation, ways, m_output_buffer);
191  m_stats += assembler.stats();
193  } catch (const osmium::invalid_location&) {
194  // XXX ignore
195  }
196  }
197 
198  void flush() {
200  }
201 
204 
205  using std::swap;
206  swap(buffer, m_output_buffer);
207 
208  return buffer;
209  }
210 
211  }; // class MultipolygonCollector
212 
213  } // namespace area
214 
215 } // namespace osmium
216 
217 #endif // OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP
const area_stats & stats() const noexcept
Definition: multipolygon_collector.hpp:119
osmium::memory::Buffer & members_buffer()
Definition: collector.hpp:483
void possibly_flush_output_buffer()
Definition: multipolygon_collector.hpp:105
bool keep_relation(const osmium::Relation &relation) const
Definition: multipolygon_collector.hpp:129
type
Definition: entity_bits.hpp:63
Definition: relation.hpp:168
MultipolygonCollector(const assembler_config_type &assembler_config)
Definition: multipolygon_collector.hpp:113
Definition: entity_bits.hpp:72
void swap(Buffer &lhs, Buffer &rhs)
Definition: buffer.hpp:885
size_t get_offset(osmium::item_type type, osmium::object_id_type id)
Definition: collector.hpp:513
Definition: way.hpp:72
std::size_t committed() const noexcept
Definition: buffer.hpp:356
void way_not_in_any_relation(const osmium::Way &way)
Definition: multipolygon_collector.hpp:154
Definition: relation.hpp:57
void flush()
Definition: multipolygon_collector.hpp:198
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
Definition: collector.hpp:97
T & get(const std::size_t offset) const
Definition: buffer.hpp:518
Definition: location.hpp:53
const assembler_config_type m_assembler_config
Definition: multipolygon_collector.hpp:82
osmium::memory::Buffer read()
Definition: multipolygon_collector.hpp:202
Definition: stats.hpp:49
void complete_relation(osmium::relations::RelationMeta &relation_meta)
Definition: multipolygon_collector.hpp:175
item_type type() const noexcept
Definition: relation.hpp:132
Definition: multipolygon_collector.hpp:77
osmium::memory::Buffer m_output_buffer
Definition: multipolygon_collector.hpp:84
typename TAssembler::config_type assembler_config_type
Definition: multipolygon_collector.hpp:81
Definition: buffer.hpp:97
bool keep_member(const osmium::relations::RelationMeta &, const osmium::RelationMember &member) const
Definition: multipolygon_collector.hpp:143
const osmium::Relation & get_relation(size_t offset) const
Definition: collector.hpp:300
area_stats m_stats
Definition: multipolygon_collector.hpp:86
void flush_output_buffer()
Definition: multipolygon_collector.hpp:96