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(); }
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(); }