Libosmium  2.16.0
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-2021 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
relation.hpp
osmium::area::MultipolygonCollector
Definition: multipolygon_collector.hpp:77
osmium::area::MultipolygonCollector::flush_output_buffer
void flush_output_buffer()
Definition: multipolygon_collector.hpp:96
osmium::area::MultipolygonCollector::MultipolygonCollector
MultipolygonCollector(const assembler_config_type &assembler_config)
Definition: multipolygon_collector.hpp:113
osmium::invalid_location
Definition: location.hpp:53
osmium::area::MultipolygonCollector::read
osmium::memory::Buffer read()
Definition: multipolygon_collector.hpp:202
osmium::RelationMember::type
item_type type() const noexcept
Definition: relation.hpp:132
osmium::area::MultipolygonCollector::initial_output_buffer_size
@ initial_output_buffer_size
Definition: multipolygon_collector.hpp:89
osmium::memory::Buffer::committed
std::size_t committed() const noexcept
Definition: buffer.hpp:356
tag.hpp
osmium::relations::Collector
Definition: collector.hpp:98
way.hpp
osmium::area::MultipolygonCollector::m_stats
area_stats m_stats
Definition: multipolygon_collector.hpp:86
collector.hpp
node_ref.hpp
osmium::memory::Buffer
Definition: buffer.hpp:97
osmium::relations::Collector< MultipolygonCollector< TAssembler >, false, true, false >::get_relation
const osmium::Relation & get_relation(size_t offset) const
Definition: collector.hpp:301
osmium
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
osmium::area::MultipolygonCollector::way_not_in_any_relation
void way_not_in_any_relation(const osmium::Way &way)
Definition: multipolygon_collector.hpp:154
osmium::osm_entity_bits::area
@ area
Definition: entity_bits.hpp:72
osmium::area::area_stats
Definition: stats.hpp:49
osmium::relations::Collector< MultipolygonCollector< TAssembler >, false, true, false >::members_buffer
osmium::memory::Buffer & members_buffer()
Definition: collector.hpp:484
osmium::area::MultipolygonCollector::m_assembler_config
const assembler_config_type m_assembler_config
Definition: multipolygon_collector.hpp:82
osmium::relations::Collector< MultipolygonCollector< TAssembler >, false, true, false >::get_offset
size_t get_offset(osmium::item_type type, osmium::object_id_type id)
Definition: collector.hpp:514
osmium::Way
Definition: way.hpp:72
osmium::memory::Buffer::get
T & get(const std::size_t offset) const
Definition: buffer.hpp:518
osmium::Relation
Definition: relation.hpp:168
osmium::area::MultipolygonCollector::flush
void flush()
Definition: multipolygon_collector.hpp:198
location.hpp
osmium::area::MultipolygonCollector::stats
const area_stats & stats() const noexcept
Definition: multipolygon_collector.hpp:119
osmium::RelationMember
Definition: relation.hpp:57
osmium::area::MultipolygonCollector::possibly_flush_output_buffer
void possibly_flush_output_buffer()
Definition: multipolygon_collector.hpp:105
osmium::relations::Collector< MultipolygonCollector< TAssembler >, false, true, false >::callback
callback_func_type callback()
Definition: collector.hpp:222
osmium::area::MultipolygonCollector::max_buffer_size_for_flush
@ max_buffer_size_for_flush
Definition: multipolygon_collector.hpp:93
osmium::memory::swap
void swap(Buffer &lhs, Buffer &rhs)
Definition: buffer.hpp:885
osmium::item_type::way
@ way
osmium::area::MultipolygonCollector::m_output_buffer
osmium::memory::Buffer m_output_buffer
Definition: multipolygon_collector.hpp:84
buffer.hpp
osmium::area::MultipolygonCollector::assembler_config_type
typename TAssembler::config_type assembler_config_type
Definition: multipolygon_collector.hpp:81
osmium::memory::Buffer::auto_grow::yes
@ yes
stats.hpp
item_type.hpp
osmium::area::MultipolygonCollector::keep_member
bool keep_member(const osmium::relations::RelationMeta &, const osmium::RelationMember &member) const
Definition: multipolygon_collector.hpp:143
osmium::area::MultipolygonCollector::complete_relation
void complete_relation(osmium::relations::RelationMeta &relation_meta)
Definition: multipolygon_collector.hpp:175
osmium::osm_entity_bits::type
type
Definition: entity_bits.hpp:63
osmium::area::MultipolygonCollector::keep_relation
bool keep_relation(const osmium::Relation &relation) const
Definition: multipolygon_collector.hpp:129