void node(const osmium::Node& node) { const char* label = node.tags().get_value_by_key("label"); if (label) { OGRFeature* feature = OGRFeature::CreateFeature(m_layer_labels->GetLayerDefn()); std::unique_ptr<OGRPoint> ogr_point = m_factory.create_point(node); feature->SetGeometry(ogr_point.get()); feature->SetField("id", static_cast<double>(node.id())); feature->SetField("label", label); if (m_layer_labels->CreateFeature(feature) != OGRERR_NONE) { std::cerr << "Failed to create feature.\n"; exit(1); } OGRFeature::DestroyFeature(feature); } else { OGRFeature* feature = OGRFeature::CreateFeature(m_layer_nodes->GetLayerDefn()); std::unique_ptr<OGRPoint> ogr_point = m_factory.create_point(node); feature->SetGeometry(ogr_point.get()); feature->SetField("id", static_cast<double>(node.id())); if (m_layer_nodes->CreateFeature(feature) != OGRERR_NONE) { std::cerr << "Failed to create feature.\n"; exit(1); } OGRFeature::DestroyFeature(feature); } }
void area(const osmium::Area& area) { const char* building = area.tags()["building"]; if (building) { try { std::unique_ptr<OGRMultiPolygon> ogr_polygon = m_factory.create_multipolygon(area); OGRFeature* feature = OGRFeature::CreateFeature(m_layer_polygon->GetLayerDefn()); feature->SetGeometry(ogr_polygon.get()); feature->SetField("id", static_cast<int>(area.id())); feature->SetField("type", building); std::string type = ""; if (area.from_way()) { type += "w"; } else { type += "r"; } feature->SetField("type", type.c_str()); if (m_layer_polygon->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 area " << area.id() << " created from " << (area.from_way() ? "way" : "relation") << " with id=" << area.orig_id() << ".\n"; } } }
void write_point(const char* problem_type, osmium::object_id_type id1, osmium::object_id_type id2, osmium::Location location) { gdalcpp::Feature feature(m_layer_perror, m_ogr_factory.create_point(location)); feature.set_field("id1", static_cast<double>(id1)); feature.set_field("id2", static_cast<double>(id2)); feature.set_field("problem_type", problem_type); feature.add_to_layer(); }
void write_line(const char* problem_type, osmium::object_id_type id1, osmium::object_id_type id2, osmium::Location loc1, osmium::Location loc2) { std::unique_ptr<OGRPoint> ogr_point1 = m_ogr_factory.create_point(loc1); std::unique_ptr<OGRPoint> ogr_point2 = m_ogr_factory.create_point(loc2); std::unique_ptr<OGRLineString> ogr_linestring = std::unique_ptr<OGRLineString>(new OGRLineString()); ogr_linestring->addPoint(ogr_point1.get()); ogr_linestring->addPoint(ogr_point2.get()); gdalcpp::Feature feature(m_layer_lerror, std::move(ogr_linestring)); feature.set_field("id1", static_cast<double>(id1)); feature.set_field("id2", static_cast<double>(id2)); feature.set_field("problem_type", problem_type); feature.add_to_layer(); }
void area(const osmium::Area& area) { if (m_first_out) { m_out << "[\n"; m_first_out = false; } else { m_out << ",\n"; } m_out << "{\n \"test_id\": " << (area.orig_id() / 1000) << ",\n \"area_id\": " << area.id() << ",\n \"from_id\": " << area.orig_id() << ",\n \"from_type\": \"" << (area.from_way() ? "way" : "relation") << "\",\n \"wkt\": \""; try { std::string wkt = m_wkt_factory.create_multipolygon(area); m_out << wkt << "\",\n \"tags\": {"; auto tagmap = create_map(area.tags()); bool first = true; for (auto& tag : tagmap) { if (first) { first = false; } else { m_out << ", "; } m_out << '"' << tag.first << "\": \"" << tag.second << '"'; } m_out << "}\n}"; } catch (osmium::geometry_error&) { m_out << "INVALID\"\n}"; } try { std::unique_ptr<OGRMultiPolygon> ogr_polygon = m_ogr_factory.create_multipolygon(area); OGRFeature* feature = OGRFeature::CreateFeature(m_layer_polygon->GetLayerDefn()); feature->SetGeometry(ogr_polygon.get()); feature->SetField("id", static_cast<int>(area.orig_id())); std::string from_type; if (area.from_way()) { from_type = "w"; } else { from_type = "r"; } feature->SetField("from_type", from_type.c_str()); if (m_layer_polygon->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 area " << area.id() << " created from " << (area.from_way() ? "way" : "relation") << " with id=" << area.orig_id() << ".\n"; } }
void write_point(const char* problem_type, osmium::object_id_type id1, osmium::object_id_type id2, osmium::Location location) { OGRFeature* feature = OGRFeature::CreateFeature(m_layer_perror->GetLayerDefn()); std::unique_ptr<OGRPoint> ogr_point = m_ogr_factory.create_point(location); feature->SetGeometry(ogr_point.get()); feature->SetField("id1", static_cast<double>(id1)); feature->SetField("id2", static_cast<double>(id2)); feature->SetField("problem_type", problem_type); if (m_layer_perror->CreateFeature(feature) != OGRERR_NONE) { std::runtime_error("Failed to create feature on layer 'perrors'"); } OGRFeature::DestroyFeature(feature); }
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"; } }
void node(const osmium::Node& node) { const char* amenity = node.tags()["amenity"]; if (amenity && !strcmp(amenity, "post_box")) { OGRFeature* feature = OGRFeature::CreateFeature(m_layer_point->GetLayerDefn()); std::unique_ptr<OGRPoint> ogr_point = m_factory.create_point(node); feature->SetGeometry(ogr_point.get()); feature->SetField("id", static_cast<double>(node.id())); feature->SetField("operator", node.tags()["operator"]); if (m_layer_point->CreateFeature(feature) != OGRERR_NONE) { std::cerr << "Failed to create feature.\n"; exit(1); } OGRFeature::DestroyFeature(feature); } }
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"; } }
void write_line(const char* problem_type, osmium::object_id_type id1, osmium::object_id_type id2, osmium::Location loc1, osmium::Location loc2) { std::unique_ptr<OGRPoint> ogr_point1 = m_ogr_factory.create_point(loc1); std::unique_ptr<OGRPoint> ogr_point2 = m_ogr_factory.create_point(loc2); std::unique_ptr<OGRLineString> ogr_linestring = std::unique_ptr<OGRLineString>(new OGRLineString()); ogr_linestring->addPoint(ogr_point1.get()); ogr_linestring->addPoint(ogr_point2.get()); OGRFeature* feature = OGRFeature::CreateFeature(m_layer_lerror->GetLayerDefn()); feature->SetGeometry(ogr_linestring.get()); feature->SetField("id1", static_cast<double>(id1)); feature->SetField("id2", static_cast<double>(id2)); feature->SetField("problem_type", problem_type); if (m_layer_lerror->CreateFeature(feature) != OGRERR_NONE) { std::runtime_error("Failed to create feature on layer 'lerrors'"); } OGRFeature::DestroyFeature(feature); }
MyOGRHandler(const std::string& driver_name, const std::string& filename) { OGRRegisterAll(); OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str()); if (!driver) { std::cerr << driver_name << " driver not available.\n"; exit(1); } CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE"); const char* options[] = { "SPATIALITE=TRUE", nullptr }; m_data_source = driver->CreateDataSource(filename.c_str(), const_cast<char**>(options)); if (!m_data_source) { std::cerr << "Creation of output file failed.\n"; exit(1); } OGRSpatialReference sparef; sparef.importFromProj4(m_factory.proj_string().c_str()); m_layer_point = m_data_source->CreateLayer("postboxes", &sparef, wkbPoint, nullptr); if (!m_layer_point) { std::cerr << "Layer creation failed.\n"; exit(1); } OGRFieldDefn layer_point_field_id("id", OFTReal); layer_point_field_id.SetWidth(10); if (m_layer_point->CreateField(&layer_point_field_id) != OGRERR_NONE) { std::cerr << "Creating id field failed.\n"; exit(1); } OGRFieldDefn layer_point_field_operator("operator", OFTString); layer_point_field_operator.SetWidth(30); if (m_layer_point->CreateField(&layer_point_field_operator) != OGRERR_NONE) { std::cerr << "Creating operator field failed.\n"; exit(1); } /* Transactions might make things faster, then again they might not. Feel free to experiment and benchmark and report back. */ m_layer_point->StartTransaction(); m_layer_linestring = m_data_source->CreateLayer("roads", &sparef, wkbLineString, nullptr); if (!m_layer_linestring) { std::cerr << "Layer creation failed.\n"; exit(1); } OGRFieldDefn layer_linestring_field_id("id", OFTReal); layer_linestring_field_id.SetWidth(10); if (m_layer_linestring->CreateField(&layer_linestring_field_id) != OGRERR_NONE) { std::cerr << "Creating id field failed.\n"; exit(1); } OGRFieldDefn layer_linestring_field_type("type", OFTString); layer_linestring_field_type.SetWidth(30); if (m_layer_linestring->CreateField(&layer_linestring_field_type) != OGRERR_NONE) { std::cerr << "Creating type field failed.\n"; exit(1); } m_layer_linestring->StartTransaction(); m_layer_polygon = m_data_source->CreateLayer("buildings", &sparef, wkbMultiPolygon, nullptr); if (!m_layer_polygon) { std::cerr << "Layer creation failed.\n"; exit(1); } OGRFieldDefn layer_polygon_field_id("id", OFTInteger); layer_polygon_field_id.SetWidth(10); if (m_layer_polygon->CreateField(&layer_polygon_field_id) != OGRERR_NONE) { std::cerr << "Creating id field failed.\n"; exit(1); } OGRFieldDefn layer_polygon_field_type("type", OFTString); layer_polygon_field_type.SetWidth(30); if (m_layer_polygon->CreateField(&layer_polygon_field_type) != OGRERR_NONE) { std::cerr << "Creating type field failed.\n"; exit(1); } m_layer_polygon->StartTransaction(); }
#include "catch.hpp" #include <osmium/geom/ogr.hpp> #include "area_helper.hpp" #include "wnl_helper.hpp" TEST_CASE("OGR_Geometry") { SECTION("point") { osmium::geom::OGRFactory<> factory; std::unique_ptr<OGRPoint> point {factory.create_point(osmium::Location(3.2, 4.2))}; REQUIRE(3.2 == point->getX()); REQUIRE(4.2 == point->getY()); } SECTION("empty_point") { osmium::geom::OGRFactory<> factory; REQUIRE_THROWS_AS(factory.create_point(osmium::Location()), osmium::invalid_location); } SECTION("linestring") { osmium::geom::OGRFactory<> factory; osmium::memory::Buffer buffer(10000); auto &wnl = create_test_wnl_okay(buffer); { std::unique_ptr<OGRLineString> linestring {factory.create_linestring(wnl)};
#include "area_helper.hpp" #include "wnl_helper.hpp" std::string to_wkb(const OGRGeometry* geometry) { std::string buffer; buffer.resize(geometry->WkbSize()); geometry->exportToWkb(wkbNDR, reinterpret_cast<unsigned char*>(&*buffer.begin())); return buffer; } TEST_CASE("compare WKB point against GDAL/OGR") { osmium::geom::WKBFactory<> wkb_factory{osmium::geom::wkb_type::wkb}; osmium::geom::OGRFactory<> ogr_factory; const osmium::Location loc{3.2, 4.2}; const std::string wkb{wkb_factory.create_point(loc)}; const std::unique_ptr<OGRPoint> geometry = ogr_factory.create_point(loc); REQUIRE(to_wkb(geometry.get()) == wkb); } TEST_CASE("compare WKB linestring against GDAL/OGR") { osmium::geom::WKBFactory<> wkb_factory{osmium::geom::wkb_type::wkb}; osmium::geom::OGRFactory<> ogr_factory; osmium::memory::Buffer buffer{10000}; const auto& wnl = create_test_wnl_okay(buffer); SECTION("linestring") {
OGREnvelope extract( Options& options, osmium::geom::OGRFactory<osmium::geom::Projection>& factory, osmium::memory::Buffer::t_iterator<osmium::OSMObject> begin, osmium::memory::Buffer::t_iterator<osmium::OSMObject> relations, osmium::memory::Buffer::t_iterator<osmium::OSMObject> end, osmium::Timestamp point_in_time) { options.vout << "Working on " << point_in_time << "...\n"; options.vout << " Filtering data...\n"; // nodes and ways using diff_iterator = osmium::DiffIterator<osmium::memory::Buffer::t_iterator<osmium::OSMObject>>; osmium::memory::Buffer fbuffer{initial_buffer_size, osmium::memory::Buffer::auto_grow::yes}; { const diff_iterator dbegin{begin, relations}; const diff_iterator dend{relations, relations}; std::for_each(dbegin, dend, [point_in_time, &fbuffer](const osmium::DiffObject& d) { if (d.is_visible_at(point_in_time)) { fbuffer.add_item(d.curr()); fbuffer.commit(); } }); } options.vout << " Done. Filtered data needs " << (fbuffer.committed() / (1024 * 1024)) << " MBytes.\n"; // relations osmium::memory::Buffer rbuffer(initial_buffer_size, osmium::memory::Buffer::auto_grow::yes); { const diff_iterator dbegin{relations, end}; const diff_iterator dend{end, end}; std::for_each(dbegin, dend, [point_in_time, &rbuffer](const osmium::DiffObject& d) { if (d.is_visible_at(point_in_time)) { rbuffer.add_item(d.curr()); rbuffer.commit(); } }); } osmium::area::AssemblerLegacy::config_type assembler_config; osmium::area::MultipolygonManagerLegacy<osmium::area::AssemblerLegacy> mp_manager{assembler_config}; options.vout << " Reading relations...\n"; osmium::apply(rbuffer, mp_manager); mp_manager.prepare_for_lookup(); index_type index_pos; location_handler_type location_handler(index_pos); location_handler.ignore_errors(); options.vout << " Creating geometries...\n"; const std::string date = point_in_time.to_iso().substr(0, 10); std::vector<std::string> datasource_options; std::string datasource_name{options.output_directory + "/" + date}; if (options.output_format == "GeoJSON") { datasource_name += ".json"; } else if (options.output_format == "SQLite") { datasource_name += ".db"; datasource_options.push_back("SPATIALITE=TRUE"); CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE"); CPLSetConfigOption("OGR_SQLITE_CACHE", "512"); } gdalcpp::Dataset dataset{options.output_format, datasource_name, gdalcpp::SRS{factory.proj_string()}, datasource_options}; #ifdef HANDLER HANDLER geom_handler{factory, dataset, date}; #else BuildingsHandler geom_handler{factory, dataset, date}; #endif osmium::apply(fbuffer.begin(), fbuffer.end(), location_handler, geom_handler, mp_manager.handler([&geom_handler](const osmium::memory::Buffer& buffer) { osmium::apply(buffer, geom_handler); })); return geom_handler.envelope(); }