/** * Tell the Collector that you are interested in this relation * and want it kept until all members have been assembled and * it is handed back to you. * * The relation is copied and stored in a buffer inside the * collector. */ void add_relation(const osmium::Relation& relation) { const size_t offset = m_relations_buffer.committed(); m_relations_buffer.add_item(relation); RelationMeta relation_meta(offset); int n = 0; for (auto& member : m_relations_buffer.get<osmium::Relation>(offset).members()) { if (static_cast<TCollector*>(this)->keep_member(relation_meta, member)) { member_meta(member.type()).emplace_back(member.ref(), m_relations.size(), n); relation_meta.increment_need_members(); } else { member.ref(0); // set member id to zero to indicate we are not interested } ++n; } assert(offset == m_relations_buffer.committed()); if (relation_meta.has_all_members()) { m_relations_buffer.rollback(); } else { m_relations_buffer.commit(); m_relations.push_back(std::move(relation_meta)); // std::cerr << "added relation id=" << relation.id() << "\n"; } }
/** * Parses one line in OPL format. The line must not have a newline * character at the end. Buffer.commit() is called automatically if the * write succeeded. * * @param data Line must be in this zero-delimited string. * @param buffer Result will be written to this buffer. * * @returns true if an entity was parsed, false otherwise (for instance * when the line is empty). * @throws osmium::opl_error If the parsing fails. */ inline bool opl_parse(const char* data, osmium::memory::Buffer& buffer) { try { const bool wrote_something = osmium::io::detail::opl_parse_line(0, data, buffer); buffer.commit(); return wrote_something; } catch (const osmium::opl_error&) { buffer.rollback(); throw; } }
/** * Assemble an area from the given way. * The resulting area is put into the out_buffer. * * @returns false if there was some kind of error building the * area, true otherwise. */ bool operator()(const osmium::Way& way, osmium::memory::Buffer& out_buffer) { if (!config().create_way_polygons) { return true; } if (config().problem_reporter) { config().problem_reporter->set_object(osmium::item_type::way, way.id()); config().problem_reporter->set_nodes(way.nodes().size()); } // Ignore (but count) ways without segments. if (way.nodes().size() < 2) { ++stats().short_ways; return false; } if (!way.ends_have_same_id()) { ++stats().duplicate_nodes; if (config().problem_reporter) { config().problem_reporter->report_duplicate_node(way.nodes().front().ref(), way.nodes().back().ref(), way.nodes().front().location()); } } ++stats().from_ways; stats().invalid_locations = segment_list().extract_segments_from_way(config().problem_reporter, stats().duplicate_nodes, way); if (!config().ignore_invalid_locations && stats().invalid_locations > 0) { return false; } if (config().debug_level > 0) { std::cerr << "\nAssembling way " << way.id() << " containing " << segment_list().size() << " nodes\n"; } // Now create the Area object and add the attributes and tags // from the way. const bool okay = create_area(out_buffer, way); if (okay) { out_buffer.commit(); } else { out_buffer.rollback(); } if (debug()) { std::cerr << "Done: " << stats() << "\n"; } return okay; }
/** * Assemble an area from the given relation and its members. * The resulting area is put into the out_buffer. * * @returns false if there was some kind of error building the * area(s), true otherwise. */ bool operator()(const osmium::Relation& relation, const std::vector<const osmium::Way*>& members, osmium::memory::Buffer& out_buffer) { if (!config().create_new_style_polygons) { return true; } assert(relation.cmembers().size() >= members.size()); if (config().problem_reporter) { config().problem_reporter->set_object(osmium::item_type::relation, relation.id()); } if (relation.members().empty()) { ++stats().no_way_in_mp_relation; return false; } ++stats().from_relations; stats().invalid_locations = segment_list().extract_segments_from_ways(config().problem_reporter, stats().duplicate_nodes, stats().duplicate_ways, relation, members); if (!config().ignore_invalid_locations && stats().invalid_locations > 0) { return false; } stats().member_ways = members.size(); if (stats().member_ways == 1) { ++stats().single_way_in_mp_relation; } if (config().debug_level > 0) { std::cerr << "\nAssembling relation " << relation.id() << " containing " << members.size() << " way members with " << segment_list().size() << " nodes\n"; } // Now create the Area object and add the attributes and tags // from the relation. bool okay = create_area(out_buffer, relation, members); if (okay) { out_buffer.commit(); } else { out_buffer.rollback(); } return okay; }