// - walk over all relations-versions // - walk over all relations-nodes // - Adds the nodes and ways that aren't in node-tracker to a vector // - if node or way is in the box hit becames true // - if hit is true and the vector is not empty (it means their are nodes or ways that belong to a relation that has at least one node or way inside the box) // - Records the id of node or way to outside_node_tracker or outside_way_tracker void relation(const osmium::Relation& relation) { bool hit = false; if (debug) { std::cerr << "cut_administrative relation " << relation.id() << " v" << relation.version() << "\n"; } std::vector<const osmium::RelationMember*> members; std::vector<const osmium::TagList*> tags; for (auto& tag : relation.tags()) { if (strcmp(tag.key(), "boundary") == 0 && strcmp(tag.value(), "administrative") == 0) hit = true; } for (const auto& extract : info->extracts) { if (hit){ if(!extract->relation_tracker.get(relation.id())){ extract->relation_tracker.set(relation.id()); } //Add only the nodes and ways that were not yet in the respective trackers if hit is true for (const auto& member : relation.members()) { if (member.type() == osmium::item_type::way && !extract->way_tracker.get(member.ref())){ extract->way_tracker.set(member.ref()); } } } } }
void relation(const osmium::Relation& relation) { if (m_max_relation_id == relation.id()) { throw out_of_order_error{"Relation ID twice in input. Maybe you are using a history or change file?", relation.id()}; } if (id_order{}(relation.id(), m_max_relation_id)) { throw out_of_order_error{"Relation IDs out of order.", relation.id()}; } m_max_relation_id = relation.id(); }
// - walk over all relation-versions // - walk over all bboxes // - if the relation-id is recorded in the bboxes relation-tracker // - send the relation to the bboxes writer void relation(const osmium::Relation& relation) { if (debug) { std::cerr << "softcut relation " << relation.id() << " v" << relation.version() << "\n"; } for (const auto& extract : info->extracts) { if (extract->relation_tracker.get(relation.id())) { extract->write(relation); } } }
void parse_osmium_t::relation(osmium::Relation& rel) { if (rel.deleted()) { m_data->relation_delete(rel.id()); } else { if (m_append) { m_data->relation_modify(rel); } else { m_data->relation_add(rel); } } m_stats.add_rel(rel.id()); }
int osmdata_t::relation_modify(osmium::Relation const &rel) { slim_middle_t *slim = dynamic_cast<slim_middle_t *>(mid.get()); slim->relations_delete(rel.id()); slim->relations_set(rel); int status = 0; for (auto& out: outs) { status |= out->relation_modify(rel); } slim->relation_changed(rel.id()); return status; }
void relation(const osmium::Relation& relation) { m_check_order.relation(relation); if (m_relation_count == 0) { m_progress_bar.remove(); m_vout << "Reading relations...\n"; } ++m_relation_count; if (m_check_relations) { set(osmium::item_type::relation, relation.id()); for (const auto& member : relation.members()) { switch (member.type()) { case osmium::item_type::node: if (!get(osmium::item_type::node, member.ref())) { ++m_missing_nodes_in_relations; set(osmium::item_type::node, member.ref()); if (m_show_ids) { std::cout << "n" << member.ref() << " in r" << relation.id() << "\n"; } } break; case osmium::item_type::way: if (!get(osmium::item_type::way, member.ref())) { ++m_missing_ways_in_relations; set(osmium::item_type::way, member.ref()); if (m_show_ids) { std::cout << "w" << member.ref() << " in r" << relation.id() << "\n"; } } break; case osmium::item_type::relation: if (member.ref() > relation.id() || !get(osmium::item_type::relation, member.ref())) { m_relation_refs.emplace_back(member.ref(), relation.id()); } break; default: break; } } } }
int output_pgsql_t::relation_modify(osmium::Relation const &rel) { if( !m_options.slim ) { fprintf( stderr, "Cannot apply diffs unless in slim mode\n" ); util::exit_nicely(); } relation_delete(rel.id()); relation_add(rel); return 0; }
// - walk over all relation-versions // - walk over all bboxes // - walk over all relation-members // - if the relation-member is recorded in the bboxes node- or way-tracker // - record its id in the bboxes relation-tracker void relation(const osmium::Relation& relation) { if (first_relation) { write_way_extra_nodes(); first_relation = false; } if (debug) { std::cerr << "softcut relation " << relation.id() << " v" << relation.version() << "\n"; } for (const auto& extract : info->extracts) { bool hit = false; for (const auto& member : relation.members()) { if (!hit && ( (member.type() == osmium::item_type::node && extract->node_tracker.get(member.ref())) || (member.type() == osmium::item_type::way && extract->way_tracker.get(member.ref())) || (member.type() == osmium::item_type::relation && extract->relation_tracker.get(member.ref())) )) { if (debug) std::cerr << "relation has a member (" << member.type() << " " << member.ref() << ") inside extract, recording in relation_tracker\n"; hit = true; extract->relation_tracker.set(relation.id()); } if (member.type() == osmium::item_type::relation) { if (debug) { std::cerr << "recording cascading-pair: " << member.ref() << " -> " << relation.id() << "\n"; } info->cascading_relations_tracker.insert(std::make_pair(member.ref(), relation.id())); } } if (hit) { cascading_relations(extract, relation.id()); } } }
void relation(const osmium::Relation& rel) { ++rels; if (!matches_user_filter(rel)) return; ++urels; if (rel.visible()==false) { m_relfile << rel.id() << "\t" << rel.version() << "\t" << rel.changeset() << "\t" << rel.timestamp().to_iso() << "\t" << rel.uid() << std::endl; } }
/** * 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; }
void middle_pgsql_t::relations_set(osmium::Relation const &rel) { idlist_t parts[3]; for (auto const &m : rel.members()) { parts[osmium::item_type_to_nwr_index(m.type())].push_back(m.ref()); } copy_buffer.reserve(rel.members().byte_size() * 2 + rel.tags().byte_size() + 128); // Params: id, way_off, rel_off, parts, members, tags */ const char *paramValues[6] = { copy_buffer.c_str(), }; bool copy = rel_table->copyMode; char delim = copy ? '\t' : '\0'; copy_buffer = std::to_string(rel.id()); copy_buffer+= delim; paramValues[1] = paramValues[0] + copy_buffer.size(); copy_buffer += std::to_string(parts[0].size()); copy_buffer+= delim; paramValues[2] = paramValues[0] + copy_buffer.size(); copy_buffer += std::to_string(parts[0].size() + parts[1].size()); copy_buffer+= delim; paramValues[3] = paramValues[0] + copy_buffer.size(); if (rel.members().empty()) { copy_buffer += "{}"; } else { copy_buffer += "{"; for (int i = 0; i < 3; ++i) { for (auto it : parts[i]) { copy_buffer += std::to_string(it); copy_buffer += ','; } } copy_buffer[copy_buffer.size() - 1] = '}'; } copy_buffer+= delim; if (rel.members().empty()) { paramValues[4] = nullptr; copy_buffer += "\\N"; } else { paramValues[4] = paramValues[0] + copy_buffer.size(); copy_buffer += "{"; for (auto const &m : rel.members()) { copy_buffer += '"'; copy_buffer += osmium::item_type_to_char(m.type()); copy_buffer += std::to_string(m.ref()); copy_buffer += "\",\""; buffer_store_string(m.role(), copy); copy_buffer += "\","; } copy_buffer[copy_buffer.size() - 1] = '}'; } copy_buffer+= delim; if (rel.tags().empty() && !out_options->extra_attributes) { paramValues[5] = nullptr; copy_buffer += "\\N"; } else { paramValues[5] = paramValues[0] + copy_buffer.size(); buffer_store_tags(rel, out_options->extra_attributes, copy); } if (copy) { copy_buffer+= '\n'; pgsql_CopyData(__FUNCTION__, rel_table->sql_conn, copy_buffer); } else { buffer_correct_params(paramValues, 6); pgsql_execPrepared(rel_table->sql_conn, "insert_rel", 6, (const char * const *)paramValues, PGRES_COMMAND_OK); } }
void middle_ram_t::relations_set(osmium::Relation const &rel) { rels.set(rel.id(), new ramRel(rel, out_options->extra_attributes)); }
void relation(const osmium::Relation& relation) { if (m_max_relation_id >= relation.id()) { throw std::runtime_error("Relation IDs out of order."); } m_max_relation_id = relation.id(); }
/* This is the workhorse of pgsql_add_relation, split out because it is used as the callback for iterate relations */ int output_pgsql_t::pgsql_process_relation(osmium::Relation const &rel) { taglist_t prefiltered_tags; if (m_tagtransform->filter_tags(rel, nullptr, nullptr, prefiltered_tags)) { return 1; } idlist_t xid2; for (auto const &m : rel.members()) { /* Need to handle more than just ways... */ if (m.type() == osmium::item_type::way) { xid2.push_back(m.ref()); } } buffer.clear(); rolelist_t xrole; auto num_ways = m_mid->rel_way_members_get(rel, &xrole, buffer); if (num_ways == 0) return 0; int roads = 0; int make_polygon = 0; int make_boundary = 0; taglist_t outtags; // If it's a route relation make_boundary and make_polygon will be false // otherwise one or the other will be true. if (m_tagtransform->filter_rel_member_tags(prefiltered_tags, buffer, xrole, &make_boundary, &make_polygon, &roads, outtags)) { return 0; } for (auto &w : buffer.select<osmium::Way>()) { m_mid->nodes_get_list(&(w.nodes())); } // linear features and boundaries // Needs to be done before the polygon treatment below because // for boundaries the way_area tag may be added. if (!make_polygon) { double const split_at = m_options.projection->target_latlon() ? 1 : 100 * 1000; auto wkbs = m_builder.get_wkb_multiline(buffer, split_at); for (auto const &wkb : wkbs) { expire.from_wkb(wkb.c_str(), -rel.id()); m_tables[t_line]->write_row(-rel.id(), outtags, wkb); if (roads) m_tables[t_roads]->write_row(-rel.id(), outtags, wkb); } } // multipolygons and boundaries if (make_boundary || make_polygon) { auto wkbs = m_builder.get_wkb_multipolygon(rel, buffer); char tmp[32]; for (auto const &wkb : wkbs) { expire.from_wkb(wkb.c_str(), -rel.id()); if (m_enable_way_area) { auto const area = m_options.reproject_area ? ewkb::parser_t(wkb).get_area<reprojection>( m_options.projection.get()) : ewkb::parser_t(wkb) .get_area<osmium::geom::IdentityProjection>(); snprintf(tmp, sizeof(tmp), "%g", area); outtags.push_override(tag_t("way_area", tmp)); } m_tables[t_poly]->write_row(-rel.id(), outtags, wkb); } } return 0; }
int relation_add(osmium::Relation const &r) override { assert(r.id() > 0); ++rel.added; return 0; }
void relations(const osmium::Relation& relation) { id_check(relation.id(), 900, 999); --m_num_relations; }