1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
/*
EXAMPLE osmium_convert
Convert OSM files from one format into another.
DEMONSTRATES USE OF:
* file input and output
* file types
* Osmium buffers
SIMPLER EXAMPLES you might want to understand first:
* osmium_read
LICENSE
The code in this example file is released into the Public Domain.
*/
#include <cstdlib> // for std::exit
#include <cstring> // for std::strcmp
#include <exception> // for std::exception
#include <iostream> // for std::cout, std::cerr
#include <string> // for std::string
// Allow any format of input files (XML, PBF, ...)
#include <osmium/io/any_input.hpp>
// Allow any format of output files (XML, PBF, ...)
#include <osmium/io/any_output.hpp>
void print_help() {
std::cout << "osmium_convert [OPTIONS] [INFILE [OUTFILE]]\n\n" \
<< "If INFILE or OUTFILE is not given stdin/stdout is assumed.\n" \
<< "File format is autodetected from file name suffix.\n" \
<< "Use -f and -t options to force file format.\n" \
<< "\nFile types:\n" \
<< " osm normal OSM file\n" \
<< " osc OSM change file\n" \
<< " osh OSM file with history information\n" \
<< "\nFile format:\n" \
<< " (default) XML encoding\n" \
<< " pbf binary PBF encoding\n" \
<< " opl OPL encoding\n" \
<< "\nFile compression\n" \
<< " gz compressed with gzip\n" \
<< " bz2 compressed with bzip2\n" \
<< "\nOptions:\n" \
<< " -h, --help This help message\n" \
<< " -f, --from-format=FORMAT Input format\n" \
<< " -t, --to-format=FORMAT Output format\n";
}
void print_usage(const char* prgname) {
std::cerr << "Usage: " << prgname << " [OPTIONS] [INFILE [OUTFILE]]\n";
std::exit(0);
}
int main(int argc, char* argv[]) {
if (argc == 1) {
print_usage(argv[0]);
}
if (argc > 1 && (!std::strcmp(argv[1], "-h") ||
!std::strcmp(argv[1], "--help"))) {
print_help();
std::exit(0);
}
// Input and output format are empty by default. Later this will mean that
// the format should be taken from the input and output file suffix,
// respectively.
std::string input_format;
std::string output_format;
std::string input_file_name;
std::string output_file_name;
for (int i = 1; i < argc; ++i) {
if (!std::strcmp(argv[i], "-f") || !std::strcmp(argv[i], "--from-format")) {
++i;
if (i < argc) {
input_format = argv[i];
} else {
print_usage(argv[0]);
}
} else if (!std::strncmp(argv[i], "--from-format=", 14)) {
input_format = argv[i] + 14;
} else if (!std::strcmp(argv[i], "-t") || !std::strcmp(argv[i], "--to-format")) {
++i;
if (i < argc) {
output_format = argv[i];
} else {
print_usage(argv[0]);
}
} else if (!std::strncmp(argv[i], "--to-format=", 12)) {
output_format = argv[i] + 12;
} else if (input_file_name.empty()) {
input_file_name = argv[i];
} else if (output_file_name.empty()) {
output_file_name = argv[i];
} else {
print_usage(argv[0]);
}
}
// This declares the input and output files using either the suffix of
// the file names or the format in the 2nd argument. It does not yet open
// the files.
const osmium::io::File input_file{input_file_name, input_format};
const osmium::io::File output_file{output_file_name, output_format};
// Input and output files can be OSM data files (without history) or
// OSM history files. History files are detected if they use the '.osh'
// file suffix.
if ( input_file.has_multiple_object_versions() &&
!output_file.has_multiple_object_versions()) {
std::cerr << "Warning! You are converting from an OSM file with (potentially) several versions of the same object to one that is not marked as such.\n";
}
try {
// Initialize Reader
osmium::io::Reader reader{input_file};
// Get header from input file and change the "generator" setting to
// ourselves.
osmium::io::Header header = reader.header();
header.set("generator", "osmium_convert");
// Initialize Writer using the header from above and tell it that it
// is allowed to overwrite a possibly existing file.
osmium::io::Writer writer{output_file, header, osmium::io::overwrite::allow};
// Copy the contents from the input to the output file one buffer at
// a time. This is much easier and faster than copying each object
// in the file. Buffers are moved around, so there is no cost for
// copying in memory.
while (osmium::memory::Buffer buffer = reader.read()) { // NOLINT(bugprone-use-after-move) Bug in clang-tidy https://bugs.llvm.org/show_bug.cgi?id=36516
writer(std::move(buffer));
}
// Explicitly close the writer and reader. Will throw an exception if
// there is a problem. If you wait for the destructor to close the writer
// and reader, you will not notice the problem, because destructors must
// not throw.
writer.close();
reader.close();
} catch (const std::exception& e) {
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << '\n';
std::exit(1);
}
}
|