[osmium-tool] 28/44: Add renumber subcommand.
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Tue Jul 21 20:15:56 UTC 2015
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to tag v1.1.0
in repository osmium-tool.
commit e154dcc6bb0d97ba6d12bae348b4c2ff4523fadd
Author: Jochen Topf <jochen at topf.org>
Date: Thu Jul 2 10:10:10 2015 +0200
Add renumber subcommand.
---
CMakeLists.txt | 1 +
man/osmium-renumber.md | 86 +++++++++++++++++++
src/command_renumber.cpp | 184 ++++++++++++++++++++++++++++++++++++++++
src/command_renumber.hpp | 60 +++++++++++++
test/CMakeLists.txt | 1 +
test/renumber/CMakeLists.txt | 15 ++++
test/renumber/input-sorted.osm | 22 +++++
test/renumber/output-sorted.osm | 22 +++++
zsh_completion/_osmium | 20 ++++-
9 files changed, 409 insertions(+), 2 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 383e394..b37d26d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -120,6 +120,7 @@ if(PANDOC)
add_man_page(1 osmium-check-refs)
add_man_page(1 osmium-fileinfo)
add_man_page(1 osmium-merge-changes)
+ add_man_page(1 osmium-renumber)
add_man_page(1 osmium-time-filter)
add_man_page(5 osmium-file-formats)
diff --git a/man/osmium-renumber.md b/man/osmium-renumber.md
new file mode 100644
index 0000000..0151814
--- /dev/null
+++ b/man/osmium-renumber.md
@@ -0,0 +1,86 @@
+
+# NAME
+
+osmium-renumber - renumber object IDs
+
+
+# SYNOPSIS
+
+**osmium renumber** \[*OPTIONS*\] *INPUT-FILE*
+
+
+# DESCRIPTION
+
+The objects (nodes, ways, and relations) in an OSM file often have very large
+IDs. This can make some kinds of postprocessing difficult. This command will
+renumber all objects using IDs starting at 1. Referential integrity will be
+kept.
+
+This command can only be run on OSM files sorted in the usual way (nodes first,
+then ways, then IDs). It will read the input file twice, so it will not work
+with STDIN.
+
+This command needs quite a bit of main memory to keep the mapping between old
+and new IDs. It is intended for small extracts. Don't try to run this on a full
+planet!
+
+You must never upload the data generated by this command to OSM! This would
+really confuse the OSM database because it knows the objects under different
+IDs.
+
+
+# OPTIONS
+
+-f, --output-format=FORMAT
+: The format of the output file. Can be used to set the output file format
+ if it can't be autodetected from the output file name.
+ **See osmium-file-formats**(5) or the libosmium manual for details.
+
+-F, --input-format=FORMAT
+: The format of the input file. Can be used to set the input format if it
+ can't be autodetected from the file name. See **osmium-file-formats**(5)
+ or the libosmium manual for details.
+
+--generator=NAME
+: The name and version of the program generating the output file. It will be
+ added to the header of the output file. Default is "*osmium/*" and the version
+ of osmium.
+
+-o, --output=FILE
+: Name of the output file. Default is '-' (*stdout*).
+
+-O, --overwrite
+: Allow an existing output file to be overwritten. Normally **osmium** will
+ refuse to write over an existing file.
+
+--output-header OPTION
+: Add output header option. This option can be given several times. See the
+ *libosmium manual* for a list of allowed header options.
+
+-v, --verbose
+: Set verbose mode. The program will output information about what it is
+ doing to *stderr*.
+
+
+# DIAGNOSTICS
+
+**osmium renumber** exits with code 0 if everything went alright, it exits
+with code 2 if there was a problem with the command line arguments,
+and with exit code 1 if some other error occurred.
+
+
+# EXAMPLES
+
+Renumber a PBF file and output to a compressed XML file:
+
+ osmium renumber -o ch.osm.bz2 switzerland.osm.pbf
+
+Renumbering Switzerland currently (summer 2015) takes only about a minute and
+needs a bit more than 2 GB RAM.
+
+
+# SEE ALSO
+
+* [Osmium website](http://osmcode.org/osmium)
+* [Libosmium manual](http://osmcode.org/libosmium/manual/libosmium-manual.html)
+
diff --git a/src/command_renumber.cpp b/src/command_renumber.cpp
new file mode 100644
index 0000000..a1288b9
--- /dev/null
+++ b/src/command_renumber.cpp
@@ -0,0 +1,184 @@
+/*
+
+Osmium -- OpenStreetMap data manipulation command line tool
+http://osmcode.org/osmium
+
+Copyright (C) 2013-2015 Jochen Topf <jochen at topf.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <iostream>
+#include <iterator>
+
+#include <boost/program_options.hpp>
+
+#include <osmium/index/index.hpp>
+#include <osmium/io/any_input.hpp>
+#include <osmium/io/any_output.hpp>
+
+#include "command_renumber.hpp"
+
+bool CommandRenumber::setup(const std::vector<std::string>& arguments) {
+ namespace po = boost::program_options;
+ po::variables_map vm;
+
+ po::options_description cmdline("Allowed options");
+ cmdline.add_options()
+ ("verbose,v", "Set verbose mode")
+ ("output,o", po::value<std::string>(), "Output file")
+ ("output-format,f", po::value<std::string>(), "Format of output file")
+ ("input-format,F", po::value<std::string>(), "Format of input files")
+ ("generator", po::value<std::string>(), "Generator setting for file header")
+ ("output-header", po::value<std::vector<std::string>>(), "Add output header")
+ ("overwrite,O", "Allow existing output file to be overwritten")
+ ;
+
+ po::options_description hidden("Hidden options");
+ hidden.add_options()
+ ("input-filename", po::value<std::string>(), "Input file")
+ ;
+
+ po::options_description desc("Allowed options");
+ desc.add(cmdline).add(hidden);
+
+ po::positional_options_description positional;
+ positional.add("input-filename", 1);
+
+ po::store(po::command_line_parser(arguments).options(desc).positional(positional).run(), vm);
+ po::notify(vm);
+
+ if (vm.count("verbose")) {
+ m_vout.verbose(true);
+ }
+
+ if (vm.count("generator")) {
+ m_generator = vm["generator"].as<std::string>();
+ }
+
+ if (vm.count("output-header")) {
+ m_output_headers = vm["output-header"].as<std::vector<std::string>>();
+ }
+
+ setup_input_file(vm);
+ setup_output_file(vm);
+
+ m_vout << "Started osmium renumber\n";
+
+ m_vout << "Command line options and default settings:\n";
+ m_vout << " generator: " << m_generator << "\n";
+ m_vout << " input filename: " << m_input_filename << "\n";
+ m_vout << " output filename: " << m_output_filename << "\n";
+ m_vout << " input format: " << m_input_format << "\n";
+ m_vout << " output format: " << m_output_format << "\n";
+ m_vout << " output header: \n";
+ for (const auto& h : m_output_headers) {
+ m_vout << " " << h << "\n";
+ }
+
+ return true;
+}
+
+osmium::object_id_type CommandRenumber::lookup(int n, osmium::object_id_type id) {
+ osmium::object_id_type result;
+
+ try {
+ result = m_id_index[n].get(id);
+ } catch (osmium::not_found& e) {
+ m_id_index[n].set(id, ++m_last_id[n]);
+ result = m_last_id[n];
+ }
+
+ return result;
+}
+
+
+void CommandRenumber::renumber(osmium::memory::Buffer& buffer) {
+ for (auto it = buffer.begin<osmium::OSMObject>(); it != buffer.end<osmium::OSMObject>(); ++it) {
+ switch (it->type()) {
+ case osmium::item_type::node:
+ m_id_index[0].set(it->id(), ++m_last_id[0]);
+ it->set_id(m_last_id[0]);
+ break;
+ case osmium::item_type::way:
+ m_id_index[1].set(it->id(), ++m_last_id[1]);
+ it->set_id(m_last_id[1]);
+ for (auto& ref : static_cast<osmium::Way&>(*it).nodes()) {
+ ref.set_ref(lookup(0, ref.ref()));
+ }
+ break;
+ case osmium::item_type::relation:
+ it->set_id(m_id_index[2].get(it->id()));
+ for (auto& member : static_cast<osmium::Relation&>(*it).members()) {
+ int n = uint16_t(member.type()) - 1;
+ assert(n >= 0 && n <= 2);
+ member.set_ref(lookup(n, member.ref()));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+bool CommandRenumber::run() {
+ try {
+ m_vout << "First pass through input file (reading relations)...\n";
+ osmium::io::Reader reader_pass1(m_input_file, osmium::osm_entity_bits::relation);
+
+ osmium::io::Header header = reader_pass1.header();
+ header.set("generator", m_generator);
+ header.set("xml_josm_upload", "false");
+ for (const auto& h : m_output_headers) {
+ header.set(h);
+ }
+ osmium::io::Writer writer(m_output_file, header, m_output_overwrite);
+
+ osmium::io::InputIterator<osmium::io::Reader, osmium::Relation> it { reader_pass1 };
+ osmium::io::InputIterator<osmium::io::Reader, osmium::Relation> end {};
+
+ for (; it != end; ++it) {
+ m_id_index[2].set(it->id(), ++m_last_id[2]);
+ }
+
+ reader_pass1.close();
+
+ m_vout << "Second pass through input file...\n";
+ osmium::io::Reader reader_pass2(m_input_file);
+ while (osmium::memory::Buffer buffer = reader_pass2.read()) {
+ renumber(buffer);
+ writer(std::move(buffer));
+ }
+ reader_pass2.close();
+
+ writer.close();
+ } catch (std::exception& e) {
+ std::cerr << e.what() << "\n";
+ return false;
+ }
+
+ m_vout << "Done.\n";
+
+ return true;
+}
+
+namespace {
+
+ const bool register_renumber_command = CommandFactory::add("renumber", "Renumber IDs in OSM file", []() {
+ return new CommandRenumber();
+ });
+
+}
+
diff --git a/src/command_renumber.hpp b/src/command_renumber.hpp
new file mode 100644
index 0000000..31ac347
--- /dev/null
+++ b/src/command_renumber.hpp
@@ -0,0 +1,60 @@
+#ifndef COMMAND_RENUMBER_HPP
+#define COMMAND_RENUMBER_HPP
+
+/*
+
+Osmium -- OpenStreetMap data manipulation command line tool
+http://osmcode.org/osmium
+
+Copyright (C) 2013-2015 Jochen Topf <jochen at topf.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <string>
+#include <vector>
+
+#include <osmium/index/map/sparse_mem_map.hpp>
+#include <osmium/memory/buffer.hpp>
+#include <osmium/osm/entity_bits.hpp>
+#include <osmium/osm/types.hpp>
+
+#include "osmc.hpp"
+
+typedef osmium::index::map::SparseMemMap<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type> remap_index_type;
+
+class CommandRenumber : public Command, with_single_osm_input, with_osm_output {
+
+ std::vector<std::string> m_output_headers;
+
+ remap_index_type m_id_index[3];
+ osmium::object_id_type m_last_id[3] = {0, 0, 0};
+
+public:
+
+ CommandRenumber() = default;
+
+ bool setup(const std::vector<std::string>& arguments) override final;
+
+ osmium::object_id_type lookup(int n, osmium::object_id_type id);
+
+ void renumber(osmium::memory::Buffer& buffer);
+
+ bool run() override final;
+
+}; // class CommandRenumber
+
+
+#endif // COMMAND_RENUMBER_HPP
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 49af1c5..ce34004 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -35,6 +35,7 @@ add_subdirectory(cat)
add_subdirectory(check-refs)
add_subdirectory(fileinfo)
add_subdirectory(help)
+add_subdirectory(renumber)
add_subdirectory(time-filter)
diff --git a/test/renumber/CMakeLists.txt b/test/renumber/CMakeLists.txt
new file mode 100644
index 0000000..2da8098
--- /dev/null
+++ b/test/renumber/CMakeLists.txt
@@ -0,0 +1,15 @@
+#-----------------------------------------------------------------------------
+#
+# CMake Config
+#
+# Osmium Tool Tests - renumber
+#
+#-----------------------------------------------------------------------------
+
+function(check_renumber _name _input _output)
+ check_output(renumber-${_name} "renumber --generator=test -f osm renumber/${_input}" "renumber/${_output}")
+endfunction()
+
+check_renumber(sorted input-sorted.osm output-sorted.osm)
+
+#-----------------------------------------------------------------------------
diff --git a/test/renumber/input-sorted.osm b/test/renumber/input-sorted.osm
new file mode 100644
index 0000000..2f7500b
--- /dev/null
+++ b/test/renumber/input-sorted.osm
@@ -0,0 +1,22 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<osm version="0.6" upload="false" generator="testdata">
+ <node id="10" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1" lat="1" lon="1"/>
+ <node id="11" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1" lat="2" lon="1"/>
+ <node id="12" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1" lat="3" lon="1"/>
+ <node id="13" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1" lat="4" lon="1"/>
+ <way id="20" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1">
+ <nd ref="10"/>
+ <nd ref="11"/>
+ <nd ref="12"/>
+ <tag k="foo" v="bar"/>
+ </way>
+ <way id="21" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1">
+ <nd ref="12"/>
+ <nd ref="13"/>
+ <tag k="xyz" v="abc"/>
+ </way>
+ <relation id="30" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1">
+ <member type="node" ref="12" role="m1"/>
+ <member type="way" ref="20" role="m2"/>
+ </relation>
+</osm>
diff --git a/test/renumber/output-sorted.osm b/test/renumber/output-sorted.osm
new file mode 100644
index 0000000..dbf1173
--- /dev/null
+++ b/test/renumber/output-sorted.osm
@@ -0,0 +1,22 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<osm version="0.6" upload="false" generator="test">
+ <node id="1" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1" lat="1" lon="1"/>
+ <node id="2" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1" lat="2" lon="1"/>
+ <node id="3" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1" lat="3" lon="1"/>
+ <node id="4" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1" lat="4" lon="1"/>
+ <way id="1" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1">
+ <nd ref="1"/>
+ <nd ref="2"/>
+ <nd ref="3"/>
+ <tag k="foo" v="bar"/>
+ </way>
+ <way id="2" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1">
+ <nd ref="3"/>
+ <nd ref="4"/>
+ <tag k="xyz" v="abc"/>
+ </way>
+ <relation id="1" version="1" timestamp="2015-01-01T01:00:00Z" uid="1" user="test" changeset="1">
+ <member type="node" ref="3" role="m1"/>
+ <member type="way" ref="1" role="m2"/>
+ </relation>
+</osm>
diff --git a/zsh_completion/_osmium b/zsh_completion/_osmium
index a7f58d4..76d8397 100644
--- a/zsh_completion/_osmium
+++ b/zsh_completion/_osmium
@@ -17,7 +17,7 @@ osmium_file_glob="'*.(osm|osh|osc|pbf|osm.pbf) *.(osm|osh|osc).(bz2|gz)'"
_osmium() {
local -a osmium_commands
- osmium_commands=(apply-changes cat check-refs fileinfo help merge-changes time-filter)
+ osmium_commands=(apply-changes cat check-refs fileinfo help merge-changes renumber time-filter)
if (( CURRENT > 2 )); then
# Remember the subcommand name
local cmd=${words[2]}
@@ -112,6 +112,22 @@ _osmium-merge-changes() {
"*::input OSM files:_files -g ${osmium_file_glob}"
}
+_osmium-renumber() {
+ _arguments : \
+ '--generator[generator setting for output file header]:generator:' \
+ '(--input-format)-F[format of input OSM file]:OSM file format:_osmium_file_formats' \
+ '(-F)--input-format[format of input OSM file]:OSM file format:_osmium_file_formats' \
+ "(--output)-o[output file name]:output OSM file:_files -g ${osmium_file_glob}" \
+ "(-o)--output[output file name]:output OSM file:_files -g ${osmium_file_glob}" \
+ '(--output-format)-f[format of output OSM file]:OSM file format:_osmium_file_formats' \
+ '(-f)--output-format[format of output OSM file]:OSM file format:_osmium_file_formats' \
+ '(--overwrite)-O[allow overwriting of existing output file]' \
+ '(-O)--overwrite[allow overwriting of existing output file]' \
+ '(--verbose)-v[set verbose mode]' \
+ '(-v)--verbose[set verbose mode]' \
+ "1::input OSM file:_files -g ${osmium_file_glob}"
+}
+
_osmium-time-filter() {
_arguments : \
'--generator[generator setting for output file header]:generator:' \
@@ -154,7 +170,7 @@ _osmium_object_type() {
_osmium-help() {
local -a osmium_help_topics
- osmium_help_topics=(apply-changes cat check-refs fileinfo help merge-changes time-filter file-formats)
+ osmium_help_topics=(apply-changes cat check-refs fileinfo help merge-changes renumber time-filter file-formats)
_describe -t osmium-help-topics 'osmium help topics' osmium_help_topics
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/osmium-tool.git
More information about the Pkg-grass-devel
mailing list