[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