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 <joc...@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 <joc...@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 <joc...@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 _______________________________________________ Pkg-grass-devel mailing list Pkg-grass-devel@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel