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"; }
double getNodeDistance(osmium::Way& w) { const char* way = w.tags() ["highway"]; const char* maxspeed = w.tags() ["maxspeed"]; double nodeDistance; // std::cout<<way<<std::endl; if(!maxspeed) { if(!strcmp (way, "primary") || !strcmp (way, "secondary") || !strcmp (way,"tertiary") || !strcmp (way, "unclassified") || !strcmp (way ,"road") || !strcmp (way, "primary_link") || !strcmp (way, "secondary_link")) { maxspeed = "90"; } if(!strcmp(way,"trunk") || !strcmp(way,"trunk_link")) { maxspeed = "110"; } if(!strcmp(way, "motorway")) { maxspeed = "130"; } if(!strcmp (way, "residential") || !strcmp (way, "track")) { maxspeed = "50"; } if(!strcmp (way, "platform") || !strcmp (way, "service") || !strcmp (way, "path") || !strcmp (way, "living_street")) { maxspeed = "20"; } } else maxspeed = "30"; nodeDistance = atoi(maxspeed) * 0.2 / 3.6; return nodeDistance; }
// Many pubs are mapped as a way (often tagged as building=yes too). // Potentially a pub could be mapped as just building=pub - but this is exceedingly rare, so it is not tested here void way(const osmium::Way& way) { const char* amenity = way.tags().get_value_by_key("amenity"); if (amenity && !strcmp(amenity, "pub")) { // For such buildings one may want to confirm the way is closed before doing more processing eg: //if (!way.is_closed()) { // return; //} // However for just listing names, the above check is not really necessary const char* name = way.tags().get_value_by_key("name"); if (name) { std::cout << name << std::endl; } } }
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"; } }
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); }
// 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); } }
void way(const osmium::Way& way) { try { std::unique_ptr<OGRLineString> ogr_linestring = m_ogr_factory.create_linestring(way); OGRFeature* feature = OGRFeature::CreateFeature(m_layer_linestring->GetLayerDefn()); feature->SetGeometry(ogr_linestring.get()); feature->SetField("id", static_cast<double>(way.id())); feature->SetField("type", way.tags().get_value_by_key("type")); if (m_layer_linestring->CreateFeature(feature) != OGRERR_NONE) { std::cerr << "Failed to create feature.\n"; exit(1); } OGRFeature::DestroyFeature(feature); } catch (osmium::geometry_error&) { std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n"; } }
bool create_area(osmium::memory::Buffer& out_buffer, const osmium::Way& way) { osmium::builder::AreaBuilder builder{out_buffer}; builder.initialize_from_object(way); const bool area_okay = create_rings(); if (area_okay || config().create_empty_areas) { builder.add_item(way.tags()); } if (area_okay) { add_rings_to_area(builder); } if (report_ways()) { config().problem_reporter->report_way(way); } return area_okay || config().create_empty_areas; }
void feed_way(const osmium::Way& way) { try { const char* building = way.tags().get_value_by_key("building"); if (building && way.is_closed()) { const char* street = way.tags().get_value_by_key("addr:street"); const char* houseno = way.tags().get_value_by_key("addr:housenumber"); if (street || houseno) { std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way); OGRFeature* feature = OGRFeature::CreateFeature(m_layer->GetLayerDefn()); OGRPolygon polygon; polygon.addRing(static_cast<OGRLinearRing*>(ogr_linestring.get())); feature->SetGeometry(static_cast<OGRGeometry*>(&polygon)); feature->SetField("way_id", static_cast<double>(way.id())); //TODO: node.id() is of type int64_t. is this ok? feature->SetField("lastchange", way.timestamp().to_iso().c_str()); const char* postcode = way.tags().get_value_by_key("addr:postcode"); const char* city = way.tags().get_value_by_key("addr:city"); const char* country = way.tags().get_value_by_key("addr:country"); const char* fulladdr = way.tags().get_value_by_key("addr:full"); const char* place = way.tags().get_value_by_key("addr:place"); if (street) { feature->SetField("street" , street); } if (houseno) { feature->SetField("houseno" , houseno); } if (postcode) { feature->SetField("postcode", postcode); } if (city) { feature->SetField("city", city); } if (country) { feature->SetField("country", country); } if (fulladdr) { feature->SetField("fulladdr", fulladdr); } if (place) { feature->SetField("place", place); } create_feature(feature); } } } catch (osmium::geometry_error& e) { catch_geometry_error(e, way); } }
void feed_way(const osmium::Way& way) { try { const char* building = way.tags().get_value_by_key("building"); if (building && way.is_closed()) { std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way); OGRFeature* feature = OGRFeature::CreateFeature(m_layer->GetLayerDefn()); OGRPolygon polygon; polygon.addRing(static_cast<OGRLinearRing*>(ogr_linestring.get())); feature->SetGeometry(static_cast<OGRGeometry*>(&polygon)); feature->SetField("way_id", static_cast<double>(way.id())); //TODO: node.id() is of type int64_t. is this ok? feature->SetField("lastchange", way.timestamp().to_iso().c_str()); create_feature(feature); } } catch (osmium::geom::geometry_error& e) { catch_geometry_error(e, way); } }
void way ( osmium::Way& way ) { const char* highway = way.tags() ["highway"]; if ( !highway ) return; // http://wiki.openstreetmap.org/wiki/Key:highway if ( !strcmp ( highway, "footway" ) || !strcmp ( highway, "cycleway" ) || !strcmp ( highway, "bridleway" ) || !strcmp ( highway, "steps" ) || !strcmp ( highway, "path" ) || !strcmp ( highway, "construction" ) ) return; onewayf = false; const char* oneway = way.tags() ["oneway"]; if ( oneway ) { onewayf = true; ++onewayc; } ++nOSM_ways; double way_length = osmium::geom::haversine::distance ( way.nodes() ); sum_highhway_length += way_length; int node_counter {0}; int unique_node_counter {0}; osmium::Location from_loc; osmium::unsigned_object_id_type vertex_old; for ( const osmium::NodeRef& nr : way.nodes() ) { osmium::unsigned_object_id_type vertex = nr.positive_ref(); way2nodes[way.id()].push_back ( vertex ); try { vert.get ( vertex ); } catch ( std::exception& e ) { vert.set ( vertex, 1 ); ++unique_node_counter; //waynode_locations.set ( vertex, nr.location() ); waynode_locations[vertex] = nr.location(); } if ( node_counter > 0 ) { if ( !edge ( vertex_old, vertex ) ) { alist[vertex_old].push_back ( vertex ); double edge_length = distance ( vertex_old, vertex ); palist[vertex_old].push_back ( edge_length / 3.0 ); if ( edge_length>max_edge_length ) max_edge_length = edge_length; mean_edge_length += edge_length; ++m_estimator; ++cedges; } else ++edge_multiplicity; if ( !onewayf ) { if ( !edge ( vertex, vertex_old ) ) { alist[vertex].push_back ( vertex_old ); double edge_length = distance ( vertex_old, vertex ); palist[vertex].push_back ( edge_length / 3.0 ); if ( edge_length>max_edge_length ) max_edge_length = edge_length; mean_edge_length += edge_length; ++m_estimator; ++cedges; } else ++edge_multiplicity; } } vertex_old = vertex; ++node_counter; } sum_highhway_nodes += node_counter; sum_unique_highhway_nodes += unique_node_counter; }
void feed_way(const osmium::Way& way) { try { const char* interpolation = way.tags().get_value_by_key("addr:interpolation"); if (interpolation) { std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way); OGRFeature* feature = OGRFeature::CreateFeature(m_layer->GetLayerDefn()); const osmium::object_id_type first_node_id = m_geometry_helper.get_first_node_id(way); const osmium::object_id_type last_node_id = m_geometry_helper.get_last_node_id(way); feature->SetGeometry(ogr_linestring.get()); feature->SetField("way_id", static_cast<double>(way.id())); //TODO: node.id() is of type int64_t. is this ok? feature->SetField("typename", interpolation); feature->SetField("firstid", static_cast<double>(first_node_id)); //TODO: node.id() is of type int64_t. is cast do double ok? feature->SetField("lastid", static_cast<double>(last_node_id)); //TODO: node.id() is of type int64_t. is cast do double ok? feature->SetField("lastchange", way.timestamp().to_iso().c_str()); AltTagList first_taglist = m_addr_interpolation_node_map->get(first_node_id); AltTagList last_taglist = m_addr_interpolation_node_map->get(last_node_id); std::string first_node_housenumber = first_taglist.get_value_by_key(std::string("addr:housenumber")); std::string last_node_housenumber = last_taglist.get_value_by_key(std::string("addr:housenumber")); unsigned int first; unsigned int last; if (first_node_housenumber != "") { feature->SetField("firstno", first_node_housenumber.c_str()); first = atoi(first_node_housenumber.c_str()); } else { first = 0; } if (last_node_housenumber != "") { feature->SetField("lastno", last_node_housenumber.c_str()); last = atoi(last_node_housenumber.c_str()); } else { last = 0; } if (!(!strcmp(interpolation,"all") || !strcmp(interpolation,"even") || !strcmp(interpolation,"odd"))) { // TODO: add support for 'alphabetic' feature->SetField("error", "unknown interpolation type"); } else if ( first == 0 || last == 0 || first_node_housenumber.length() != floor(log10(first))+1 || // make sure 123%& is not recognized as 123 last_node_housenumber.length() != floor(log10(last) )+1 // ) { feature->SetField("error", "endpoint hast wrong format"); } else if (abs(first-last) > 1000) { feature->SetField("error", "range too large"); } else if (((!strcmp(interpolation,"even") || !strcmp(interpolation,"odd")) && abs(first-last)==2) || (!strcmp(interpolation,"all") && abs(first-last)==1) ) { feature->SetField("error", "needless interpolation"); } else if (!strcmp(interpolation,"even") && ( first%2==1 || last%2==1 )) { feature->SetField("error", "interpolation even but number odd"); } else if (!strcmp(interpolation,"odd") && ( first%2==0 || last%2==0 )) { feature->SetField("error", "interpolation odd but number even"); } else if ( (first_taglist.get_value_by_key(std::string("addr:street")) != last_taglist.get_value_by_key(std::string("addr:street"))) || (first_taglist.get_value_by_key(std::string("addr:postcode")) != last_taglist.get_value_by_key(std::string("addr:postcode"))) || (first_taglist.get_value_by_key(std::string("addr:city")) != last_taglist.get_value_by_key(std::string("addr:city"))) || (first_taglist.get_value_by_key(std::string("addr:country")) != last_taglist.get_value_by_key(std::string("addr:country"))) || (first_taglist.get_value_by_key(std::string("addr:full")) != last_taglist.get_value_by_key(std::string("addr:full"))) || (first_taglist.get_value_by_key(std::string("addr:place")) != last_taglist.get_value_by_key(std::string("addr:place"))) ) { feature->SetField("error", "different tags on endpoints"); } else if ( // no interpolation error (!strcmp(interpolation, "all")) || (!strcmp(interpolation, "odd")) || (!strcmp(interpolation, "even")) ) { double length = ogr_linestring.get()->get_Length(); int increment; if (strcmp(interpolation, "all")) { increment = 2; } else { increment = 1; } double fraction; unsigned int lower, upper; if (first < last) { fraction = 1/static_cast<double>(last-first); lower = first; upper = last; } else { fraction = 1/static_cast<double>(first-last); increment *= -1; lower = last; upper = first; } for (unsigned int nr=first+increment; nr<upper && nr>lower; nr+=increment) { std::unique_ptr<OGRPoint> point (new OGRPoint); if (increment > 0) { ogr_linestring.get()->Value((nr-lower)*fraction*length, point.get()); } else { ogr_linestring.get()->Value((1-((nr-lower)*fraction))*length, point.get()); } std::string road_id(""); m_clpp.process_interpolated_node( *(point.get()), road_id, first_taglist.get_value_by_key(std::string("addr:street")) ); m_nwa_writer.process_interpolated_node( *(point.get()), nr, first_taglist.get_value_by_key(std::string("addr:street")), first_taglist.get_value_by_key(std::string("addr:postcode")), first_taglist.get_value_by_key(std::string("addr:city")), first_taglist.get_value_by_key(std::string("addr:country")), first_taglist.get_value_by_key(std::string("addr:full")), first_taglist.get_value_by_key(std::string("addr:place")), road_id ); } } create_feature(feature); } } catch (osmium::geom::geometry_error& e) { catch_geometry_error(e, way); } }
// If the way has a "highway" tag, find its length and add it to the // overall length. void way(const osmium::Way& way) { const char* highway = way.tags()["highway"]; if (highway) { length += osmium::geom::haversine::distance(way.nodes()); } }
void feed_way(const osmium::Way& way) { try { const char* street = way.tags().get_value_by_key("addr:street"); const char* housenumber = way.tags().get_value_by_key("addr:housenumber"); const char* full = way.tags().get_value_by_key("addr:full"); const char* conscriptionnumber = way.tags().get_value_by_key("addr:conscriptionnumber"); const char* housename = way.tags().get_value_by_key("addr:housename"); const char* place = way.tags().get_value_by_key("addr:place"); const char* postcode = way.tags().get_value_by_key("addr:postcode"); const char* flats = way.tags().get_value_by_key("addr:flats"); const char* door = way.tags().get_value_by_key("addr:door"); const char* unit = way.tags().get_value_by_key("addr:unit"); const char* floor = way.tags().get_value_by_key("addr:floor"); const char* city = way.tags().get_value_by_key("addr:city"); const char* country = way.tags().get_value_by_key("addr:country"); const char* hamlet = way.tags().get_value_by_key("addr:hamlet"); const char* suburb = way.tags().get_value_by_key("addr:suburb"); const char* district = way.tags().get_value_by_key("addr:district"); const char* subdistrict = way.tags().get_value_by_key("addr:subdistrict"); const char* province = way.tags().get_value_by_key("addr:province"); const char* region = way.tags().get_value_by_key("addr:region"); const char* state = way.tags().get_value_by_key("addr:state"); if (!way.is_closed() && (street || housenumber || full || conscriptionnumber || housename || place || postcode || flats || door || unit || floor || city || country || hamlet || suburb || district || subdistrict || province || region || state)) { std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way); OGRFeature* const feature = OGRFeature::CreateFeature(m_layer->GetLayerDefn()); feature->SetGeometryDirectly(static_cast<OGRGeometry*>(ogr_linestring.release())); feature->SetField("way_id", static_cast<double>(way.id())); //TODO: node.id() is of type int64_t. is this ok? feature->SetField("lastchange", way.timestamp().to_iso().c_str()); create_feature(feature); } } catch (osmium::geometry_error& e) { catch_geometry_error(e, way); } }
void way ( osmium::Way& way ) { const char* highway = way.tags() ["highway"]; if ( !highway ) return; // http://wiki.openstreetmap.org/wiki/Key:highway if ( !strcmp ( highway, "footway" ) || !strcmp ( highway, "cycleway" ) || !strcmp ( highway, "bridleway" ) || !strcmp ( highway, "steps" ) || !strcmp ( highway, "pedestrian") || !strcmp ( highway, "construction" ) ) return; double dist = getNodeDistance(way); //inicializáljuk a sebességét az utaknak, amit egy külön függvényben // std::cout<<speed; //írtunk meg,hogy melyik úthoz milyen sebesség tartozik. onewayf = false; const char* oneway = way.tags() ["oneway"]; if ( oneway ) { onewayf = true; ++onewayc; //oneway counter } ++nOSM_ways; double way_length = osmium::geom::haversine::distance ( way.nodes() ); sum_highhway_length += way_length; int node_counter {0}; int unique_node_counter {0}; osmium::Location from_loc; osmium::unsigned_object_id_type vertex_old; for ( const osmium::NodeRef& nr : way.nodes() ) { osmium::unsigned_object_id_type vertex = nr.positive_ref(); //Get absolute value of the reference ID of this NodeRef. way2nodes[way.id()].push_back ( vertex ); //Get ID of this object with way.id() and push the actual vertex to their vector try { vert.get ( vertex ); //Retrieve value by id. Does not check for overflow or empty fields. } catch ( std::exception& e ) { vert.set ( vertex, 1 ); //Set the field with id to value. ++unique_node_counter; //waynode_locations.set ( vertex, nr.location() ); waynode_locations[vertex] = nr.location(); //Get location of this NodeRef. } if ( node_counter > 0 ) { if ( !edge ( vertex_old, vertex ) ) { alist[vertex_old].push_back ( vertex ); double edge_length = distance ( vertex_old, vertex ); palist[vertex_old].push_back ( edge_length / dist ); if ( edge_length>max_edge_length ) max_edge_length = edge_length; mean_edge_length += edge_length; ++m_estimator; ++cedges; } else ++edge_multiplicity; if ( !onewayf ) { if ( !edge ( vertex, vertex_old ) ) { alist[vertex].push_back ( vertex_old ); // double edge_length = distance ( vertex_old, vertex ); palist[vertex].push_back ( edge_length / dist ); if ( edge_length>max_edge_length ) max_edge_length = edge_length; mean_edge_length += edge_length; ++m_estimator; ++cedges; } else ++edge_multiplicity; } } vertex_old = vertex; ++node_counter; } sum_highhway_nodes += node_counter; sum_unique_highhway_nodes += unique_node_counter; }
void feed_way(const osmium::Way& way) { try { const char* interpolation = way.tags().get_value_by_key("addr:interpolation"); if (interpolation) { std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way); OGRFeature* feature = OGRFeature::CreateFeature(m_layer->GetLayerDefn()); const osmium::object_id_type first_node_id = m_geometry_helper.get_first_node_id(way); const osmium::object_id_type last_node_id = m_geometry_helper.get_last_node_id(way); feature->SetGeometry(ogr_linestring.get()); feature->SetField("way_id", static_cast<double>(way.id())); //TODO: node.id() is of type int64_t. is this ok? feature->SetField("typename", interpolation); feature->SetField("firstid", static_cast<double>(first_node_id)); //TODO: node.id() is of type int64_t. is cast do double ok? feature->SetField("lastid", static_cast<double>(last_node_id)); //TODO: node.id() is of type int64_t. is cast do double ok? feature->SetField("lastchange", way.timestamp().to_iso().c_str()); AltTagList first_taglist = m_addr_interpolation_node_map->get(first_node_id); AltTagList last_taglist = m_addr_interpolation_node_map->get(last_node_id); // the raw expression given in the first addr:housenumber= entry std::string first_raw = first_taglist.get_value_by_key("addr:housenumber"); // the raw expression given in the last addr:housenumber= entry std::string last_raw = last_taglist.get_value_by_key("addr:housenumber"); unsigned int first; unsigned int last; std::string first_numeric; // the numeric part of the first housenumber std::string last_numeric; // the numeric part of the last housenumber bool is_alphabetic_ip_correct = false; if (first_raw != "") { feature->SetField("firstno", first_raw.c_str()); first = atoi(first_raw.c_str()); } else { first = 0; } if (last_raw != "") { feature->SetField("lastno", last_raw.c_str()); last = atoi(last_raw.c_str()); } else { last = 0; } if (!strcmp(interpolation, "alphabetic") && // second last characters are numbers? !isalpha(first_raw[first_raw.length()-2]) && !isalpha(last_raw[last_raw.length()-2])){ // last characters are letters? if (isalpha(first_raw[first_raw.length()-1]) && isalpha(last_raw[last_raw.length()-1])) { first_numeric = std::string(first_raw.begin(), first_raw.end() - 1); last_numeric = std::string(last_raw.begin(), last_raw.end() - 1); if (first_numeric == last_numeric) { first = first_raw[first_raw.length() - 1]; last = last_raw[last_raw.length() - 1]; is_alphabetic_ip_correct = true; } else { is_alphabetic_ip_correct = false; feature->SetField("error", "numeric parts of housenumbers not identical"); } } else { is_alphabetic_ip_correct = false; feature->SetField("error", "no alphabetic part in addr:housenumber"); } } if (!( !strcmp(interpolation, "all") || !strcmp(interpolation, "even") || !strcmp(interpolation, "odd") || !strcmp(interpolation, "alphabetic"))) { feature->SetField("error", "unknown interpolation type"); } else if ( strcmp(interpolation, "alphabetic") && // don't overwrite more precise error messages set before (first == 0 || last == 0 || first_raw.length() != floor(log10(first))+1 || // make sure 123%& is not recognized as 123 last_raw.length() != floor(log10(last) )+1 // )) { feature->SetField("error", "endpoint has wrong format"); } else if (abs_diff(first,last) > 1000) { feature->SetField("error", "range too large"); } else if (((!strcmp(interpolation,"even") || !strcmp(interpolation,"odd")) && abs_diff(first,last)==2) || (!strcmp(interpolation,"all") && abs_diff(first,last)==1) ) { feature->SetField("error", "needless interpolation"); } else if (!strcmp(interpolation,"even") && ( first%2==1 || last%2==1 )) { feature->SetField("error", "interpolation even but number odd"); } else if (!strcmp(interpolation,"odd") && ( first%2==0 || last%2==0 )) { feature->SetField("error", "interpolation odd but number even"); } else if ( (first_taglist.get_value_by_key("addr:street") != last_taglist.get_value_by_key("addr:street")) || (first_taglist.get_value_by_key("addr:postcode") != last_taglist.get_value_by_key("addr:postcode")) || (first_taglist.get_value_by_key("addr:city") != last_taglist.get_value_by_key("addr:city")) || (first_taglist.get_value_by_key("addr:country") != last_taglist.get_value_by_key("addr:country")) || (first_taglist.get_value_by_key("addr:full") != last_taglist.get_value_by_key("addr:full")) || (first_taglist.get_value_by_key("addr:place") != last_taglist.get_value_by_key("addr:place")) ) { feature->SetField("error", "different tags on endpoints"); } else if (way.is_closed()) { feature->SetField("error", "interpolation is a closed way"); } else if ( // no interpolation error (!strcmp(interpolation, "all")) || (!strcmp(interpolation, "odd")) || (!strcmp(interpolation, "even")) || (is_alphabetic_ip_correct == true)) { double length = ogr_linestring.get()->get_Length(); int increment; if (strcmp(interpolation, "all") && strcmp(interpolation, "alphabetic")) { increment = 2; // even , odd } else { increment = 1; //all , alphabetic } double fraction; unsigned int lower, upper; if (first < last) { fraction = 1/static_cast<double>(last-first); lower = first; upper = last; } else { fraction = 1/static_cast<double>(first-last); increment *= -1; lower = last; upper = first; } for (unsigned int nr=first+increment; nr<upper && nr>lower; nr+=increment) { std::unique_ptr<OGRPoint> point (new OGRPoint); if (increment > 0) { ogr_linestring.get()->Value((nr-lower)*fraction*length, point.get()); } else { ogr_linestring.get()->Value((1-((nr-lower)*fraction))*length, point.get()); } std::string road_id(""); std::string nrstr; if(strcmp(interpolation, "alphabetic")) { nrstr = std::to_string(nr); } else { // is alphabetic // std::string strend = printf("%d", nr); nrstr = first_numeric + static_cast<char>(nr); } m_clpp.process_interpolated_node( // osmi_addresses_connection_line *(point.get()), road_id, first_taglist.get_value_by_key("addr:street") ); m_nwa_writer.process_interpolated_node( //osmi_addresses_nodes_with_addresses *(point.get()), nrstr, //nr, //std::to_string(nr), first_taglist.get_value_by_key("addr:street"), first_taglist.get_value_by_key("addr:postcode"), first_taglist.get_value_by_key("addr:city"), first_taglist.get_value_by_key("addr:country"), first_taglist.get_value_by_key("addr:full"), first_taglist.get_value_by_key("addr:place"), road_id ); } } create_feature(feature); } } catch (osmium::geometry_error& e) { catch_geometry_error(e, way); } }
void way(const osmium::Way& way) { const char* inter = way.tags().get_value_by_key("addr:interpolation"); if (inter) { interpolation_count ++; osmium::unsigned_object_id_type fromnode = way.nodes().front().ref(); osmium::unsigned_object_id_type tonode = way.nodes().back().ref(); uint16_t fromhouse = housenumberMap[fromnode]; uint16_t tohouse = housenumberMap[tonode]; // back out if we don't have both house numbers if (!(fromhouse && tohouse)) { interpolation_error++; if (debug) { if (!fromhouse) std::cerr << "interpolation way " << way.id() << " references node " << fromnode << " which has no addr:housenumber" << std::endl; if (!tohouse) std::cerr << "interpolation way " << way.id() << " references node " << tonode << " which has no addr:housenumber" << std::endl; } return; } // swap if range is backwards if (tohouse < fromhouse) { fromhouse = tohouse; tohouse = housenumberMap[fromnode]; } if (!strcmp(inter, "even")) { if ((fromhouse %2 == 1) || (tohouse %2 == 1)) { if (debug) { if (fromhouse%2==1) std::cerr << "interpolation way " << way.id() << " (addr:interpolation=even) references node " << fromnode << " which has an odd house number of " << fromhouse << std::endl; if (tohouse%2==1) std::cerr << "interpolation way " << way.id() << " (addr:interpolation=even) references node " << tonode << " which has an odd house number of " << tohouse << std::endl; } interpolation_error++; return; } numbers_through_interpolation += (tohouse - fromhouse) / 2 - 1; } else if (!strcmp(inter, "odd")) { if ((fromhouse %2 == 0) || (tohouse %2 == 0)) { if (debug) { if (fromhouse%2==1) std::cerr << "interpolation way " << way.id() << " (addr:interpolation=odd) references node " << fromnode << " which has an even house number of " << fromhouse << std::endl; if (tohouse%2==1) std::cerr << "interpolation way " << way.id() << " (addr:interpolation=odd) references node " << tonode << " which has an even house number of " << tohouse << std::endl; } interpolation_error++; return; } numbers_through_interpolation += (tohouse - fromhouse) / 2 - 1; } else if (!strcmp(inter, "both") || !strcmp(inter, "all")) { numbers_through_interpolation += (tohouse - fromhouse) - 1; } else { if (debug) { std::cerr << "interpolation way " << way.id() << " has invalid interpolation mode '" << inter << "'" << std::endl; } interpolation_error++; } // slight error here - if interpolation way contains intermediate nodes with addresses then these are counted twice. } else { const char *hno = way.tags().get_value_by_key("addr:housenumber"); if (hno) { numbers_ways_overall ++; if (way.tags().get_value_by_key("addr:street")) numbers_ways_withstreet ++; if (way.tags().get_value_by_key("addr:city")) numbers_ways_withcity ++; if (way.tags().get_value_by_key("addr:country")) numbers_ways_withcountry ++; if (way.tags().get_value_by_key("addr:postcode")) { numbers_ways_withpostcode ++; postcode[way.tags().get_value_by_key("addr:postcode")] = true; } } else { const char *bdy = way.tags().get_value_by_key("boundary"); if (bdy && !strcmp(bdy, "postal_code")) { postcode_boundaries++; const char *ref = way.tags().get_value_by_key("ref"); if (ref) postcode[ref]=true; } } } }