213 lines
7.0 KiB
C++
213 lines
7.0 KiB
C++
|
/* The code in this file is released into the Public Domain. */
|
||
|
|
||
|
#include <iostream>
|
||
|
|
||
|
#pragma GCC diagnostic push
|
||
|
#ifdef __clang__
|
||
|
# pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
|
||
|
#endif
|
||
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||
|
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||
|
#pragma GCC diagnostic ignored "-Wpadded"
|
||
|
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||
|
#pragma GCC diagnostic ignored "-Wshadow"
|
||
|
# include <ogr_api.h>
|
||
|
# include <ogrsf_frmts.h>
|
||
|
#pragma GCC diagnostic pop
|
||
|
|
||
|
#include <osmium/geom/ogr.hpp>
|
||
|
#include <osmium/handler.hpp>
|
||
|
#include <osmium/handler/node_locations_for_ways.hpp>
|
||
|
#include <osmium/index/map/dummy.hpp>
|
||
|
#include <osmium/index/map/stl_vector.hpp>
|
||
|
#include <osmium/io/xml_input.hpp>
|
||
|
#include <osmium/visitor.hpp>
|
||
|
|
||
|
typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_neg_type;
|
||
|
typedef osmium::index::map::SparseMapMem<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
|
||
|
typedef osmium::handler::NodeLocationsForWays<index_pos_type, index_neg_type> location_handler_type;
|
||
|
|
||
|
class TestOverviewHandler : public osmium::handler::Handler {
|
||
|
|
||
|
OGRDataSource* m_data_source;
|
||
|
|
||
|
OGRLayer* m_layer_nodes;
|
||
|
OGRLayer* m_layer_labels;
|
||
|
OGRLayer* m_layer_ways;
|
||
|
|
||
|
osmium::geom::OGRFactory<> m_factory;
|
||
|
|
||
|
public:
|
||
|
|
||
|
TestOverviewHandler(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.SetWellKnownGeogCS("WGS84");
|
||
|
|
||
|
// nodes layer
|
||
|
|
||
|
m_layer_nodes = m_data_source->CreateLayer("nodes", &sparef, wkbPoint, nullptr);
|
||
|
if (!m_layer_nodes) {
|
||
|
std::cerr << "Layer creation failed.\n";
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
OGRFieldDefn layer_nodes_field_id("id", OFTReal);
|
||
|
layer_nodes_field_id.SetWidth(10);
|
||
|
|
||
|
if (m_layer_nodes->CreateField(&layer_nodes_field_id) != OGRERR_NONE) {
|
||
|
std::cerr << "Creating id field failed.\n";
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
// labels layer
|
||
|
|
||
|
m_layer_labels = m_data_source->CreateLayer("labels", &sparef, wkbPoint, nullptr);
|
||
|
if (!m_layer_labels) {
|
||
|
std::cerr << "Layer creation failed.\n";
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
OGRFieldDefn layer_labels_field_id("id", OFTReal);
|
||
|
layer_labels_field_id.SetWidth(10);
|
||
|
|
||
|
if (m_layer_labels->CreateField(&layer_labels_field_id) != OGRERR_NONE) {
|
||
|
std::cerr << "Creating id field failed.\n";
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
OGRFieldDefn layer_labels_field_label("label", OFTString);
|
||
|
layer_labels_field_label.SetWidth(30);
|
||
|
|
||
|
if (m_layer_labels->CreateField(&layer_labels_field_label) != OGRERR_NONE) {
|
||
|
std::cerr << "Creating label field failed.\n";
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
// ways layer
|
||
|
|
||
|
m_layer_ways = m_data_source->CreateLayer("ways", &sparef, wkbLineString, nullptr);
|
||
|
if (!m_layer_ways) {
|
||
|
std::cerr << "Layer creation failed.\n";
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
OGRFieldDefn layer_way_field_id("id", OFTReal);
|
||
|
layer_way_field_id.SetWidth(10);
|
||
|
|
||
|
if (m_layer_ways->CreateField(&layer_way_field_id) != OGRERR_NONE) {
|
||
|
std::cerr << "Creating id field failed.\n";
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
OGRFieldDefn layer_way_field_test("test", OFTInteger);
|
||
|
layer_way_field_test.SetWidth(3);
|
||
|
|
||
|
if (m_layer_ways->CreateField(&layer_way_field_test) != OGRERR_NONE) {
|
||
|
std::cerr << "Creating test field failed.\n";
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
~TestOverviewHandler() {
|
||
|
OGRDataSource::DestroyDataSource(m_data_source);
|
||
|
OGRCleanupAll();
|
||
|
}
|
||
|
|
||
|
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 way(const osmium::Way& way) {
|
||
|
try {
|
||
|
std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way);
|
||
|
OGRFeature* feature = OGRFeature::CreateFeature(m_layer_ways->GetLayerDefn());
|
||
|
feature->SetGeometry(ogr_linestring.get());
|
||
|
feature->SetField("id", static_cast<double>(way.id()));
|
||
|
|
||
|
const char* test = way.tags().get_value_by_key("test");
|
||
|
if (test) {
|
||
|
feature->SetField("test", test);
|
||
|
}
|
||
|
|
||
|
if (m_layer_ways->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";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
/* ================================================== */
|
||
|
|
||
|
int main(int argc, char* argv[]) {
|
||
|
if (argc != 2) {
|
||
|
std::cerr << "Usage: " << argv[0] << " INFILE\n";
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
std::string output_format("SQLite");
|
||
|
std::string input_filename(argv[1]);
|
||
|
std::string output_filename("testdata-overview.db");
|
||
|
::unlink(output_filename.c_str());
|
||
|
|
||
|
osmium::io::Reader reader(input_filename);
|
||
|
|
||
|
index_pos_type index_pos;
|
||
|
index_neg_type index_neg;
|
||
|
location_handler_type location_handler(index_pos, index_neg);
|
||
|
location_handler.ignore_errors();
|
||
|
|
||
|
TestOverviewHandler handler(output_format, output_filename);
|
||
|
|
||
|
osmium::apply(reader, location_handler, handler);
|
||
|
reader.close();
|
||
|
}
|
||
|
|