/* This is an example tool that creates multipolygons from OSM data and dumps them to stdout. The code in this example file is released into the Public Domain. */ #include #include #include #include #include #include #include #include #include #include #include #include typedef osmium::index::map::Dummy index_neg_type; typedef osmium::index::map::SparseMemArray index_pos_type; typedef osmium::handler::NodeLocationsForWays location_handler_type; class WKTDump : public osmium::handler::Handler { osmium::geom::WKTFactory<> m_factory ; std::ostream& m_out; public: WKTDump(std::ostream& out) : m_out(out) { } void area(const osmium::Area& area) { try { m_out << m_factory.create_multipolygon(area) << "\n"; } catch (osmium::geometry_error& e) { m_out << "GEOMETRY ERROR: " << e.what() << "\n"; } } }; // class WKTDump void print_help() { std::cout << "osmium_area_test [OPTIONS] OSMFILE\n\n" << "Read OSMFILE and build multipolygons from it.\n" << "\nOptions:\n" << " -h, --help This help message\n" << " -w, --dump-wkt Dump area geometries as WKT\n" << " -o, --dump-objects Dump area objects\n"; } int main(int argc, char* argv[]) { static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"dump-wkt", no_argument, 0, 'w'}, {"dump-objects", no_argument, 0, 'o'}, {0, 0, 0, 0} }; osmium::handler::DynamicHandler handler; while (true) { int c = getopt_long(argc, argv, "hwo", long_options, 0); if (c == -1) { break; } switch (c) { case 'h': print_help(); exit(0); case 'w': handler.set(std::cout); break; case 'o': handler.set(std::cout); break; default: exit(1); } } int remaining_args = argc - optind; if (remaining_args != 1) { std::cerr << "Usage: " << argv[0] << " [OPTIONS] OSMFILE\n"; exit(1); } osmium::io::File infile(argv[optind]); osmium::area::Assembler::config_type assembler_config; osmium::area::MultipolygonCollector collector(assembler_config); std::cout << "Pass 1...\n"; osmium::io::Reader reader1(infile, osmium::osm_entity_bits::relation); collector.read_relations(reader1); reader1.close(); std::cout << "Pass 1 done\n"; std::cout << "Memory:\n"; collector.used_memory(); index_pos_type index_pos; index_neg_type index_neg; location_handler_type location_handler(index_pos, index_neg); location_handler.ignore_errors(); // XXX std::cout << "Pass 2...\n"; osmium::io::Reader reader2(infile); osmium::apply(reader2, location_handler, collector.handler([&handler](osmium::memory::Buffer&& buffer) { osmium::apply(buffer, handler); })); reader2.close(); std::cout << "Pass 2 done\n"; std::cout << "Memory:\n"; collector.used_memory(); std::vector incomplete_relations = collector.get_incomplete_relations(); if (!incomplete_relations.empty()) { std::cerr << "Warning! Some member ways missing for these multipolygon relations:"; for (const auto* relation : incomplete_relations) { std::cerr << " " << relation->id(); } std::cerr << "\n"; } }