198 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* The code in this file is released into the Public Domain. */
 | 
						|
 | 
						|
#include <iostream>
 | 
						|
 | 
						|
#include <osmium/index/map/sparse_mem_array.hpp>
 | 
						|
 | 
						|
#include <osmium/geom/ogr.hpp>
 | 
						|
#include <osmium/handler.hpp>
 | 
						|
#include <osmium/handler/node_locations_for_ways.hpp>
 | 
						|
#include <osmium/io/xml_input.hpp>
 | 
						|
#include <osmium/visitor.hpp>
 | 
						|
 | 
						|
typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
 | 
						|
typedef osmium::handler::NodeLocationsForWays<index_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_type index;
 | 
						|
    location_handler_type location_handler(index);
 | 
						|
    location_handler.ignore_errors();
 | 
						|
 | 
						|
    TestOverviewHandler handler(output_format, output_filename);
 | 
						|
 | 
						|
    osmium::apply(reader, location_handler, handler);
 | 
						|
    reader.close();
 | 
						|
}
 | 
						|
 |