1#ifndef OSMIUM_AREA_ASSEMBLER_LEGACY_HPP
2#define OSMIUM_AREA_ASSEMBLER_LEGACY_HPP
37#include <osmium/area/detail/basic_assembler_with_tags.hpp>
38#include <osmium/area/detail/proto_ring.hpp>
39#include <osmium/area/detail/segment_list.hpp>
76 std::map<std::string, std::size_t> counter;
78 for (
const auto& tag : way->tags()) {
79 std::string kv{tag.key()};
81 kv.append(tag.value());
86 const std::size_t num_ways = ways.size();
87 for (
const auto& t_c : counter) {
89 std::cerr <<
" tag " << t_c.first <<
" is used " << t_c.second <<
" times in " << num_ways <<
" ways\n";
91 if (t_c.second == num_ways) {
92 const std::size_t len = std::strlen(t_c.first.c_str());
93 tl_builder.
add_tag(t_c.first.c_str(), t_c.first.c_str() + len + 1);
102 add(
false,
"created_by");
103 add(
false,
"source");
105 add(
false,
"test:id");
106 add(
false,
"test:section");
117 const auto count = std::count_if(relation.tags().cbegin(), relation.tags().cend(), std::cref(
filter()));
120 std::cerr <<
" found " << count <<
" tags on relation (without ignored ones)\n";
125 std::cerr <<
" use tags from relation\n";
128 if (config().keep_type_tag) {
131 copy_tags_without_type(builder, relation.tags());
134 ++stats().no_tags_on_relation;
136 std::cerr <<
" use tags from outer ways\n";
138 std::set<const osmium::Way*> ways;
139 for (
const auto& ring : rings()) {
140 if (ring.is_outer()) {
144 if (ways.size() == 1) {
146 std::cerr <<
" only one outer way\n";
148 builder.
add_item((*ways.cbegin())->tags());
151 std::cerr <<
" multiple outer ways, get common tags\n";
163 const bool area_okay = create_rings();
164 if (area_okay || config().create_empty_areas) {
165 builder.add_item(way.tags());
168 add_rings_to_area(builder);
172 config().problem_reporter->report_way(way);
175 return area_okay || config().create_empty_areas;
179 set_num_members(members.size());
183 const bool area_okay = create_rings();
184 if (area_okay || config().create_empty_areas) {
188 add_rings_to_area(builder);
193 config().problem_reporter->report_way(*way);
197 return area_okay || config().create_empty_areas;
203 detail::BasicAssemblerWithTags(config) {
214 if (!config().create_way_polygons) {
218 if (way.tags().has_tag(
"area",
"no")) {
222 if (config().problem_reporter) {
224 config().problem_reporter->set_nodes(way.nodes().size());
228 if (way.nodes().size() < 2) {
229 ++stats().short_ways;
233 if (!way.ends_have_same_id()) {
234 ++stats().duplicate_nodes;
235 if (config().problem_reporter) {
236 config().problem_reporter->report_duplicate_node(way.nodes().front().ref(), way.nodes().back().ref(), way.nodes().front().location());
241 stats().invalid_locations = segment_list().extract_segments_from_way(config().problem_reporter,
242 stats().duplicate_nodes,
244 if (!config().ignore_invalid_locations && stats().invalid_locations > 0) {
248 if (config().debug_level > 0) {
249 std::cerr <<
"\nAssembling way " << way.id() <<
" containing " << segment_list().size() <<
" nodes\n";
258 out_buffer.rollback();
262 std::cerr <<
"Done: " << stats() <<
"\n";
276 assert(relation.members().size() >= members.size());
278 if (config().problem_reporter) {
282 if (relation.members().empty()) {
283 ++stats().no_way_in_mp_relation;
287 ++stats().from_relations;
288 stats().invalid_locations = segment_list().extract_segments_from_ways(config().problem_reporter,
289 stats().duplicate_nodes,
290 stats().duplicate_ways,
293 if (!config().ignore_invalid_locations && stats().invalid_locations > 0) {
296 stats().member_ways = members.size();
298 if (stats().member_ways == 1) {
299 ++stats().single_way_in_mp_relation;
302 if (config().debug_level > 0) {
303 std::cerr <<
"\nAssembling relation " << relation.id() <<
" containing " << members.size() <<
" way members with " << segment_list().size() <<
" nodes\n";
306 const std::size_t area_offset = out_buffer.committed();
310 bool okay =
create_area(out_buffer, relation, members);
312 if ((config().create_new_style_polygons && stats().no_tags_on_relation == 0) ||
313 (config().create_old_style_polygons && stats().no_tags_on_relation != 0)) {
316 out_buffer.rollback();
319 out_buffer.rollback();
328 std::vector<const osmium::Way*> ways_that_should_be_areas;
329 if (stats().wrong_role == 0) {
331 if (!std::strcmp(member.
role(),
"inner")) {
332 if (!way.nodes().empty() && way.is_closed() && !way.tags().empty()) {
333 const auto d = std::count_if(way.tags().cbegin(), way.tags().cend(), std::cref(filter()));
335 const osmium::tags::KeyFilter::iterator way_fi_begin(std::cref(filter()), way.tags().cbegin(), way.tags().cend());
336 const osmium::tags::KeyFilter::iterator way_fi_end(std::cref(filter()), way.tags().cend(), way.tags().cend());
337 const osmium::tags::KeyFilter::iterator area_fi_begin(std::cref(filter()), area_tags.cbegin(), area_tags.cend());
338 const osmium::tags::KeyFilter::iterator area_fi_end(std::cref(filter()), area_tags.cend(), area_tags.cend());
339#ifdef __cpp_lib_robust_nonmodifying_seq_ops
340 if (!std::equal(way_fi_begin, way_fi_end, area_fi_begin, area_fi_end)) {
342 if (d != std::distance(area_fi_begin, area_fi_end) || !std::equal(way_fi_begin, way_fi_end, area_fi_begin)) {
344 ways_that_should_be_areas.push_back(&way);
346 ++stats().inner_with_same_tags;
347 if (config().problem_reporter) {
348 config().problem_reporter->report_inner_with_same_tags(way);
358 std::cerr <<
"Done: " << stats() <<
"\n";
362 for (
const osmium::Way* way : ways_that_should_be_areas) {
364 if (!assembler(*way, out_buffer)) {
367 stats() += assembler.stats();
Definition: relation.hpp:56
const char * role() const noexcept
Definition: relation.hpp:133
Definition: relation.hpp:161
Definition: assembler_legacy.hpp:73
static const MPFilter & filter() noexcept
Definition: assembler_legacy.hpp:111
bool create_area(osmium::memory::Buffer &out_buffer, const osmium::Way &way)
Definition: assembler_legacy.hpp:159
bool operator()(const osmium::Relation &relation, const std::vector< const osmium::Way * > &members, osmium::memory::Buffer &out_buffer)
Definition: assembler_legacy.hpp:275
AssemblerLegacy(const config_type &config)
Definition: assembler_legacy.hpp:202
bool operator()(const osmium::Way &way, osmium::memory::Buffer &out_buffer)
Definition: assembler_legacy.hpp:213
bool create_area(osmium::memory::Buffer &out_buffer, const osmium::Relation &relation, const std::vector< const osmium::Way * > &members)
Definition: assembler_legacy.hpp:178
void add_common_tags(osmium::builder::TagListBuilder &tl_builder, std::set< const osmium::Way * > &ways) const
Definition: assembler_legacy.hpp:75
void add_tags_to_area(osmium::builder::AreaBuilder &builder, const osmium::Relation &relation)
Definition: assembler_legacy.hpp:116
Definition: osm_object_builder.hpp:567
void initialize_from_object(const osmium::OSMObject &source)
Definition: osm_object_builder.hpp:584
void add_item(const osmium::memory::Item &item)
Definition: builder.hpp:206
Definition: osm_object_builder.hpp:72
void add_tag(const char *key, const char *value)
Definition: osm_object_builder.hpp:102
@ area
Definition: entity_bits.hpp:72
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
Definition: assembler_legacy.hpp:98
MPFilter()
Definition: assembler_legacy.hpp:100