void way(const osmium::Way& way) { if (m_write_change_ops) { open_close_op_tag(way.visible() ? (way.version() == 1 ? operation::op_create : operation::op_modify) : operation::op_delete); } write_prefix(); m_out += "<way"; write_meta(way); if (way.tags().empty() && way.nodes().empty()) { m_out += "/>\n"; return; } m_out += ">\n"; for (const auto& node_ref : way.nodes()) { write_prefix(); oprintf(m_out, " <nd ref=\"%" PRId64 "\"/>\n", node_ref.ref()); } write_tags(way.tags()); write_prefix(); m_out += "</way>\n"; }
void way(const osmium::Way& way) { *m_out += 'w'; write_meta(way); *m_out += " N"; if (!way.nodes().empty()) { auto it = way.nodes().begin(); if (m_options.locations_on_ways) { write_field_ref(*it); for (++it; it != way.nodes().end(); ++it) { *m_out += ','; write_field_ref(*it); } } else { write_field_int('n', it->ref()); for (++it; it != way.nodes().end(); ++it) { *m_out += ','; write_field_int('n', it->ref()); } } } *m_out += '\n'; }
/** * Extract segments from given way and add them to the list. * * Segments connecting two nodes with the same location (ie * same node or different nodes with same location) are * removed after reporting the duplicate node. */ uint32_t extract_segments_from_way(osmium::area::ProblemReporter* problem_reporter, const osmium::Way& way) { if (way.nodes().empty()) { return 0; } m_segments.reserve(way.nodes().size() - 1); return extract_segments_from_way_impl(problem_reporter, way, role_type::outer); }
inline void parseWay(const osmium::Way& way) { const auto& tags = way.tags(); auto it = std::find_if(tags.begin(), tags.end(), highway_filter); if (it == tags.end()) { return; } const osmium::NodeRef& first = way.nodes().front(); const osmium::NodeRef& last = way.nodes().back(); // filter out closed ways, generally this will just cause false // positives with round-a-abouts if (first == last) { return; } const char* name = tags.get_value_by_key("name", ""); const char* ref = tags.get_value_by_key("ref", ""); unsigned name_id = getStringID(name); unsigned ref_id = getStringID(ref); // we can't use osmium ids because MultiMap expects unsigned keys unsigned long firstID = static_cast<unsigned long>(first.ref()); unsigned long lastID = static_cast<unsigned long>(last.ref()); const unsigned wayIdx = parsed_ways->size(); endpoint_way_map->unsorted_set(firstID, wayIdx); endpoint_way_map->unsorted_set(lastID, wayIdx); parsed_ways->emplace_back(way.id(), firstID, lastID, name_id, ref_id); }
void way(const osmium::Way& way) { // detect a new way if (current_way_id != 0 && current_way_id != way.positive_id()) { write_way_extra_nodes(); current_way_nodes.clear(); } current_way_id = way.positive_id(); if (debug) { std::cerr << "softcut way " << way.positive_id() << " v" << way.version() << "\n"; } for (const auto& node_ref : way.nodes()) { current_way_nodes.insert(node_ref.positive_ref()); } for (const auto& extract : info->extracts) { for (const auto& node_ref : way.nodes()) { if (extract->node_tracker.get(node_ref.positive_ref())) { if (debug) { std::cerr << "way has a node (" << node_ref.positive_ref() << ") inside extract, recording in way_tracker\n"; } extract->way_tracker.set(way.positive_id()); break; } } } }
/*** * Insert error node into nodes table: way contains of one * coordinate. */ void insert_way_error(const osmium::Way &way) { ErrorSum *sum = new ErrorSum(); sum->set_way_error(); ds.insert_node_feature(way.nodes().begin()->location(), way.nodes().begin()->ref(), sum); delete sum; }
void eway(extract_data& e, const osmium::Way& way) { for (const auto& nr : way.nodes()) { if (e.node_ids.get(nr.positive_ref())) { e.way_ids.set(way.positive_id()); for (const auto& nr : way.nodes()) { e.extra_node_ids.set(nr.ref()); } return; } } }
/** * 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; }
uint32_t extract_segments_from_way_impl(osmium::area::ProblemReporter* problem_reporter, uint64_t& duplicate_nodes, const osmium::Way& way, role_type role) { uint32_t invalid_locations = 0; osmium::NodeRef previous_nr; for (const osmium::NodeRef& nr : way.nodes()) { if (!nr.location().valid()) { ++invalid_locations; if (problem_reporter) { problem_reporter->report_invalid_location(way.id(), nr.ref()); } continue; } if (previous_nr.location()) { if (previous_nr.location() != nr.location()) { m_segments.emplace_back(previous_nr, nr, role, &way); } else { ++duplicate_nodes; if (problem_reporter) { problem_reporter->report_duplicate_node(previous_nr.ref(), nr.ref(), nr.location()); } } } previous_nr = nr; } return invalid_locations; }
/*** * Iterate through all nodes of waterways in pass 3 if way is coastline * or riverbank. Otherwise iterate just through the nodes between * firstnode and lastnode. */ void way(const osmium::Way& way) { if (is_valid(way)) { if (check_all_nodes(way)) { for (auto node : way.nodes()) { check_node(node); } } else { if (way.nodes().size() > 2) { for (auto node = way.nodes().begin() + 1; node != way.nodes().end() - 1; ++node) { check_node(*node); } } } } }
void output_pgsql_t::pgsql_out_way(osmium::Way const &way, taglist_t *tags, bool polygon, bool roads) { if (polygon && way.is_closed()) { auto wkb = m_builder.get_wkb_polygon(way); if (!wkb.empty()) { expire.from_wkb(wkb.c_str(), way.id()); if (m_enable_way_area) { char tmp[32]; 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); tags->push_override(tag_t("way_area", tmp)); } m_tables[t_poly]->write_row(way.id(), *tags, wkb); } } else { double const split_at = m_options.projection->target_latlon() ? 1 : 100 * 1000; for (auto const &wkb : m_builder.get_wkb_line(way.nodes(), split_at)) { expire.from_wkb(wkb.c_str(), way.id()); m_tables[t_line]->write_row(way.id(), *tags, wkb); if (roads) { m_tables[t_roads]->write_row(way.id(), *tags, wkb); } } } }
polygon_type create_polygon(const osmium::Way& way, use_nodes un=use_nodes::unique, direction dir = direction::forward) { try { return create_polygon(way.nodes(), un, dir); } catch (osmium::geometry_error& e) { e.set_id("way", way.id()); throw; } }
/** * Extract segments from given way and add them to the list. * * Segments connecting two nodes with the same location (ie same * node or different node with same location) are removed. * * XXX should two nodes with same location be reported? */ void extract_segments_from_way(const osmium::Way& way, const char* role) { osmium::NodeRef last_nr; for (const osmium::NodeRef& nr : way.nodes()) { if (last_nr.location() && last_nr.location() != nr.location()) { m_segments.emplace_back(last_nr, nr, role, &way); } last_nr = nr; } }
/** * This is called when a way is not in any multipolygon * relation. */ void way_not_in_any_relation(const osmium::Way& way) { // you need at least 4 nodes to make up a polygon if (way.nodes().size() <= 3) { return; } try { if (!way.nodes().front().location() || !way.nodes().back().location()) { throw osmium::invalid_location{"invalid location"}; } if (way.ends_have_same_location()) { // way is closed and has enough nodes, build simple multipolygon TAssembler assembler{m_assembler_config}; assembler(way, this->buffer()); m_stats += assembler.stats(); } } catch (const osmium::invalid_location&) { // XXX ignore } }
/** * This is called when a way is not in any multipolygon * relation. * * Overwritten from the base class. */ void way_not_in_any_relation(const osmium::Way& way) { // you need at least 4 nodes to make up a polygon if (way.nodes().size() <= 3) { return; } try { if (!way.nodes().front().location() || !way.nodes().back().location()) { throw osmium::invalid_location("invalid location"); } if (way.ends_have_same_location()) { // way is closed and has enough nodes, build simple multipolygon TAssembler assembler(m_assembler_config); assembler(way, m_output_buffer); possibly_flush_output_buffer(); } } catch (osmium::invalid_location&) { // XXX ignore } }
void way(const osmium::Way& way) { ++ways; if (!matches_user_filter(way)) return; ++uways; for (const auto& node : way.nodes()) { m_nodefile << way.id() << "\t" << way.version() << "\t" << node.ref() << std::endl; } }
// The way handler is called for each node in the input data. void way(const osmium::Way& way) { { osmium::builder::WayBuilder builder{m_buffer}; copy_attributes(builder, way); copy_tags(builder, way.tags()); // Copy the node list over to the new way. builder.add_item(way.nodes()); } m_buffer.commit(); }
void middle_pgsql_t::ways_set(osmium::Way const &way) { copy_buffer.reserve(way.nodes().size() * 10 + way.tags().byte_size() + 100); bool copy = way_table->copyMode; char delim = copy ? '\t' : '\0'; // Three params: id, nodes, tags */ const char *paramValues[4] = { copy_buffer.c_str(), }; copy_buffer = std::to_string(way.id()); copy_buffer += delim; paramValues[1] = paramValues[0] + copy_buffer.size(); if (way.nodes().size() == 0) { copy_buffer += "{}"; } else { copy_buffer += "{"; for (auto const &n : way.nodes()) { copy_buffer += std::to_string(n.ref()); copy_buffer += ','; } copy_buffer[copy_buffer.size() - 1] = '}'; } copy_buffer += delim; if (way.tags().empty() && !out_options->extra_attributes) { paramValues[2] = nullptr; copy_buffer += "\\N"; } else { paramValues[2] = paramValues[0] + copy_buffer.size(); buffer_store_tags(way, out_options->extra_attributes, copy); } if (copy) { copy_buffer += '\n'; pgsql_CopyData(__FUNCTION__, way_table->sql_conn, copy_buffer); } else { buffer_correct_params(paramValues, 3); pgsql_execPrepared(way_table->sql_conn, "insert_way", 3, (const char * const *)paramValues, PGRES_COMMAND_OK); } }
/** * This is called when a way is not in any multipolygon * relation. * * Overwritten from the base class. */ void way_not_in_any_relation(const osmium::Way& way) { if (way.nodes().size() > 3 && way.ends_have_same_location()) { // way is closed and has enough nodes, build simple multipolygon try { TAssembler assembler(m_assembler_config); assembler(way, m_output_buffer); possibly_flush_output_buffer(); } catch (osmium::invalid_location&) { // XXX ignore } } }
void way(const osmium::Way& way) { for (const auto& node_ref : way.nodes()) { try { add_location(m_old_index.get(node_ref.ref())); } catch (...) { } try { add_location(m_tmp_index.get(node_ref.ref())); } catch (...) { } } }
void way(osmium::Way& w) { ++utak; osmium::WayNodeList& wnl = w.nodes(); std::vector<osmium::unsigned_object_id_type> nds; for( osmium::NodeRef& n : wnl ) { nds.emplace_back(n.ref()); } way_node_map[w.id()] = nds; nds.clear(); }
// - walk over all way-versions // - walk over all bboxes // - if the way-id is recorded in the bboxes way-trackers // - send the way to the bboxes writer void way(const osmium::Way& way) { if (debug) { std::cerr << "cut_administrative way " << way.id() << " v" << way.version() << "\n"; } for (const auto& extract : info->extracts) { if (extract->way_tracker.get(way.id())){ for (const auto& node_ref : way.nodes()) { if (!extract->node_tracker.get(node_ref.ref())) { extract->node_tracker.set(node_ref.ref()); } } } } }
void way(const osmium::Way& way) { *m_out += 'w'; write_meta(way); *m_out += " N"; bool first = true; for (const auto& node_ref : way.nodes()) { if (first) { first = false; } else { *m_out += ','; } output_formatted("n%" PRId64, node_ref.ref()); } *m_out += '\n'; }
void way(const osmium::Way& way) { m_length += osmium::geom::haversine::distance(way.nodes()); try { std::unique_ptr<OGRLineString> ogrlinestring = m_factory.create_linestring(way); gdalcpp::Feature feature(m_layer_ways, std::move(ogrlinestring)); feature.set_field("way_id", std::to_string(way.id()).c_str()); feature.set_field("name", way.tags().get_value_by_key("name")); feature.set_field("source", way.tags().get_value_by_key("source")); const bool bogus = way.tags().has_tag("coastline", "bogus"); feature.set_field("bogus", bogus ? "t" : "f"); feature.add_to_layer(); } catch (const osmium::geometry_error&) { std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n"; } }
int osmdata_t::way_modify(osmium::Way const &way) { idlist_t nodes(way.nodes()); slim_middle_t *slim = dynamic_cast<slim_middle_t *>(mid.get()); slim->ways_delete(way.id()); slim->ways_set(way); int status = 0; for (auto& out: outs) { status |= out->way_modify(way); } slim->way_changed(way.id()); return status; }
/** * Retrieve locations of all nodes in the way from storage and add * them to the way object. */ void way(osmium::Way& way) { if (m_must_sort) { m_storage_pos.sort(); m_storage_neg.sort(); m_must_sort = false; m_last_id = std::numeric_limits<osmium::unsigned_object_id_type>::max(); } bool error = false; for (auto& node_ref : way.nodes()) { node_ref.set_location(get_node_location(node_ref.ref())); if (!node_ref.location()) { error = true; } } if (!m_ignore_errors && error) { throw osmium::not_found{"location for one or more nodes not found in node location index"}; } }
void CreateGraph::way(const osmium::Way& way) { const char* highway = way.get_value_by_key("highway"); if (!highway || !strcmp(highway, "footway")) { return; } vertex_type u = -1; for (const auto& node_ref : way.nodes()) { node_id_map_type::iterator pos; bool inserted; boost::tie(pos, inserted) = node_id_map.emplace(node_ref.positive_ref(), vertex_type()); if (inserted) { double x = osmium::geom::detail::lon_to_x(node_ref.lon()); double y = osmium::geom::detail::lat_to_y(node_ref.lat()); Location loc(x, y); pos->second = boost::add_vertex(vertex_property(loc), graph); } const vertex_type v = pos->second; if (u+1) { const char* street_name = way.get_value_by_key("name", ""); const Location& a = boost::get(boost::vertex_name, graph, u); const Location& b = boost::get(boost::vertex_name, graph, v); const double length = dist(a, b); edge_property prop; boost::get_property_value(prop, boost::edge_name) = street_name; boost::get_property_value(prop, boost::edge_weight) = length; boost::add_edge(u, v, prop, graph); } u = v; } }
bool is_way_with_nonzero_length(const osmium::Way& way) { if (way.nodes().size() < 2) { return false; } for (unsigned int i=1; i<way.nodes().size(); i++) { if (way.nodes()[0].location().lat() != way.nodes()[i].location().lat()) { return true; } if (way.nodes()[0].location().lon() != way.nodes()[i].location().lon()) { return true; } } return false; }
/** * Retrieve locations of all nodes in the way from storage and add * them to the way object. */ void way(osmium::Way& way) { if (m_must_sort) { m_storage_pos.sort(); m_storage_neg.sort(); m_must_sort = false; } bool error = false; for (auto& node_ref : way.nodes()) { try { node_ref.set_location(get_node_location(node_ref.ref())); if (!node_ref.location()) { error = true; } } catch (osmium::not_found&) { error = true; } } if (error && !m_ignore_errors) { throw osmium::not_found("location for one or more nodes not found in node location index"); } }
void way(const osmium::Way& way) { m_check_order.way(way); if (m_way_count == 0) { m_progress_bar.remove(); m_vout << "Reading ways...\n"; } ++m_way_count; if (m_check_relations) { set(osmium::item_type::way, way.id()); } for (const auto& node_ref : way.nodes()) { if (!get(osmium::item_type::node, node_ref.ref())) { ++m_missing_nodes_in_ways; if (m_show_ids) { std::cout << "n" << node_ref.ref() << " in w" << way.id() << "\n"; } } } }