pax_global_header00006660000000000000000000000064147414306720014522gustar00rootroot0000000000000052 comment=02b70f2c0df142f09ca24ffa633b6d3d1ec1e3eb osmium-tool-1.17.0/000077500000000000000000000000001474143067200140745ustar00rootroot00000000000000osmium-tool-1.17.0/.clang-tidy000066400000000000000000000073361474143067200161410ustar00rootroot00000000000000--- Checks: '*,-abseil-*,-altera-*,-android-cloexec-*,-boost-use-ranges,-bugprone-branch-clone,-bugprone-chained-comparison,-bugprone-easily-swappable-parameters,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-vararg,-fuchsia-*,-hicpp-avoid-c-arrays,-hicpp-no-array-decay,-hicpp-vararg,-llvmlibc-*,-misc-no-recursion,-modernize-avoid-c-arrays,-modernize-use-nodiscard,-modernize-use-trailing-return-type,-readability-convert-member-functions-to-static,-readability-function-cognitive-complexity,-readability-identifier-length,-readability-implicit-bool-conversion,-readability-magic-numbers' # # For a list of check options, see: # https://clang.llvm.org/extra/clang-tidy/checks/list.html # # Disabled checks: # # abseil-* # We are not using abseil. # # altera-* # Doesn't apply. # # android-cloexec-* # O_CLOEXEC isn't available on Windows making this non-portable. # # boost-use-ranges # Would introduce extra dependency on boost. # # bugprone-branch-clone # There are several cases in this code where the code seems much more # readable with branch clones than without. # # bugprone-chained-comparison # These are generated by our test framework. # # bugprone-easily-swappable-parameters # Not much we can do about those except inventing new types for everything # and anything. # # cppcoreguidelines-avoid-c-arrays # hicpp-avoid-c-arrays # modernize-avoid-c-arrays # Makes sense for some array, but especially for char arrays using # std::array isn't a good solution. # # cppcoreguidelines-avoid-magic-numbers # readability-magic-numbers # Generally good advice, but there are too many places where this is # useful, for instance in tests. # # cppcoreguidelines-macro-usage # There are cases where we actually need macros. # # cppcoreguidelines-owning-memory # Don't want to add dependency on gsl library. # # cppcoreguidelines-pro-bounds-array-to-pointer-decay # hicpp-no-array-decay # Limited use and many false positives including for all asserts. # # cppcoreguidelines-pro-bounds-pointer-arithmetic # Difficult to get by without it... # # cppcoreguidelines-pro-type-static-cast-downcast # This is needed and totally okay if we are sure about the types. # # cppcoreguidelines-pro-type-vararg # We need some of these functions at least and for some functions it isn't # even clear that those are vararg functions. # # fuchsia-* # Much too strict. # # hicpp-vararg # Too strict, sometimes calling vararg functions is necessary. # # llvmlibc-* # Not applicable. # # misc-no-recursion # Nothing wrong about recursion. # # modernize-use-nodiscard # Maybe good for a library, but overkill for an application. # # modernize-use-trailing-return-type # I am not quite that modern. # # readability-convert-member-functions-to-static # Not a bad idea, but it is overzealous when there are member functions # overwritten in child classes and some of them can't be static. # # readability-function-cognitive-complexity # Some functions need to be larger. # # readability-identifier-length # Short identifiers are sometimes okay. # # readability-implicit-bool-conversion # I don't think this makes the code more readable. # #WarningsAsErrors: '*' CheckOptions: - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic value: true - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic value: true ... osmium-tool-1.17.0/.gitattributes000066400000000000000000000002711474143067200167670ustar00rootroot00000000000000*.osm -crlf *.osc -crlf *.opl -crlf *.osh -crlf *.pg -crlf *-result.txt -crlf test/export/*.geojson -crlf test/export/*.geojsonseq -crlf test/export/*.txt -crlf test/diff/output* -crlf osmium-tool-1.17.0/.github/000077500000000000000000000000001474143067200154345ustar00rootroot00000000000000osmium-tool-1.17.0/.github/FUNDING.yml000066400000000000000000000000541474143067200172500ustar00rootroot00000000000000custom: "https://osmcode.org/sponsors.html" osmium-tool-1.17.0/.github/ISSUE_TEMPLATE/000077500000000000000000000000001474143067200176175ustar00rootroot00000000000000osmium-tool-1.17.0/.github/ISSUE_TEMPLATE/bug-report.md000066400000000000000000000026001474143067200222250ustar00rootroot00000000000000--- name: Report problems with the software about: You found a (possible) bug in osmium-tool title: '' labels: '' assignees: '' --- ## What version of osmium-tool are you using? ## What operating system version are you using? ## Tell us something about your system ## What did you do exactly? ## What did you expect to happen? ## What did happen instead? ## What did you do to try analyzing the problem? osmium-tool-1.17.0/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000002261474143067200216070ustar00rootroot00000000000000contact_links: - name: community.osm.org url: https://community.openstreetmap.org/ about: Ask questions and get support from the community. osmium-tool-1.17.0/.github/actions/000077500000000000000000000000001474143067200170745ustar00rootroot00000000000000osmium-tool-1.17.0/.github/actions/build/000077500000000000000000000000001474143067200201735ustar00rootroot00000000000000osmium-tool-1.17.0/.github/actions/build/action.yml000066400000000000000000000002501474143067200221700ustar00rootroot00000000000000name: Build runs: using: composite steps: - name: Build run: cmake --build . --config Release --verbose shell: bash working-directory: build osmium-tool-1.17.0/.github/actions/cmake-windows/000077500000000000000000000000001474143067200216445ustar00rootroot00000000000000osmium-tool-1.17.0/.github/actions/cmake-windows/action.yml000066400000000000000000000006621474143067200236500ustar00rootroot00000000000000name: Windows CMake runs: using: composite steps: - name: Create build directory run: mkdir build shell: bash - name: Configure run: | cmake -LA .. \ -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake \ -DOsmium_DEBUG=TRUE \ -DPROTOZERO_INCLUDE_DIR=${GITHUB_WORKSPACE}/../protozero/include shell: bash working-directory: build osmium-tool-1.17.0/.github/actions/cmake/000077500000000000000000000000001474143067200201545ustar00rootroot00000000000000osmium-tool-1.17.0/.github/actions/cmake/action.yml000066400000000000000000000004631474143067200221570ustar00rootroot00000000000000name: CMake runs: using: composite steps: - name: Create build directory run: mkdir build shell: bash - name: Configure run: | cmake -LA .. \ ${CMAKE_OPTS} \ -DCMAKE_BUILD_TYPE=${BUILD_TYPE} shell: bash working-directory: build osmium-tool-1.17.0/.github/actions/ctest/000077500000000000000000000000001474143067200202165ustar00rootroot00000000000000osmium-tool-1.17.0/.github/actions/ctest/action.yml000066400000000000000000000002401474143067200222120ustar00rootroot00000000000000name: Test runs: using: composite steps: - name: Test run: ctest --output-on-failure -C Release shell: bash working-directory: build osmium-tool-1.17.0/.github/actions/install-from-git/000077500000000000000000000000001474143067200222645ustar00rootroot00000000000000osmium-tool-1.17.0/.github/actions/install-from-git/action.yml000066400000000000000000000004671474143067200242730ustar00rootroot00000000000000name: Install Prerequisites from git runs: using: composite steps: - name: Install from git run: | git clone --quiet --depth 1 https://github.com/osmcode/libosmium.git ../libosmium git clone --quiet --depth 1 https://github.com/mapbox/protozero.git ../protozero shell: bash osmium-tool-1.17.0/.github/actions/install-ubuntu/000077500000000000000000000000001474143067200220625ustar00rootroot00000000000000osmium-tool-1.17.0/.github/actions/install-ubuntu/action.yml000066400000000000000000000006001474143067200240560ustar00rootroot00000000000000name: Install apt packages on Ubuntu/Debian runs: using: composite steps: - name: Install packages run: | sudo apt-get update -qq sudo apt-get install -yq \ libboost-dev \ libboost-program-options-dev \ libbz2-dev \ liblz4-dev \ nlohmann-json3-dev \ pandoc shell: bash osmium-tool-1.17.0/.github/workflows/000077500000000000000000000000001474143067200174715ustar00rootroot00000000000000osmium-tool-1.17.0/.github/workflows/ci.yml000066400000000000000000000150431474143067200206120ustar00rootroot00000000000000name: CI on: [ push, pull_request ] jobs: linux: runs-on: ubuntu-latest timeout-minutes: 30 strategy: fail-fast: false matrix: image: - "ubuntu:20.04" # gcc 9.3.0, clang 10.0.0, cmake 3.16.3 - "ubuntu:22.04" # gcc 12.2.0, clang 15.0.7, cmake 3.24.2 - "ubuntu:24.04" # gcc 14.2.0, clang 18.1.3, cmake 3.28.3 - "debian:bullseye" # gcc 10.2.1, clang 11.0.1, cmake 3.18.4 - "debian:bookworm" # gcc 12.2.0, clang 15.0.6, cmake 3.25.1 - "debian:testing" - "debian:experimental" - "fedora:39" - "fedora:40" - "fedora:41" build_type: [Dev] cpp_compiler: [g++] cpp_version: [c++14] include: - image: "ubuntu:24.04" CXXFLAGS: -Wno-stringop-overread -Wno-array-bounds - image: "debian:bullseye" cpp_version: c++17 - image: "debian:bullseye" cpp_version: c++20 - image: "debian:bullseye" c_compiler: clang cpp_compiler: clang++ - image: "debian:bullseye" c_compiler: clang cpp_compiler: clang++ cpp_version: c++17 - image: "debian:bullseye" c_compiler: clang cpp_compiler: clang++ cpp_version: c++20 - image: "debian:bullseye" build_type: RelWithDebInfo - image: "debian:bookworm" CXXFLAGS: -Wno-stringop-overread -Wno-array-bounds - image: "debian:bookworm" cpp_version: c++17 CXXFLAGS: -Wno-stringop-overread -Wno-array-bounds - image: "debian:bookworm" cpp_version: c++20 CXXFLAGS: -Wno-stringop-overread -Wno-array-bounds - image: "debian:bookworm" c_compiler: clang cpp_compiler: clang++ - image: "debian:bookworm" c_compiler: clang cpp_compiler: clang++ cpp_version: c++17 - image: "debian:bookworm" c_compiler: clang cpp_compiler: clang++ cpp_version: c++20 - image: "debian:bookworm" build_type: RelWithDebInfo CXXFLAGS: -Wno-stringop-overread -Wno-array-bounds - image: "debian:testing" CXXFLAGS: -Wno-stringop-overread -Wno-array-bounds - image: "debian:testing" c_compiler: clang cpp_compiler: clang++ - image: "debian:experimental" CXXFLAGS: -Wno-stringop-overread -Wno-array-bounds - image: "debian:experimental" c_compiler: clang cpp_compiler: clang++ - image: "fedora:39" CXXFLAGS: -Wno-stringop-overread -Wno-array-bounds - image: "fedora:40" CMAKE_OPTS: -DRUN_TESTS_WITH_BINARY_COMPARE=OFF CXXFLAGS: -Wno-stringop-overread -Wno-array-bounds - image: "fedora:41" CMAKE_OPTS: -DRUN_TESTS_WITH_BINARY_COMPARE=OFF CXXFLAGS: -Wno-stringop-overread -Wno-array-bounds container: image: ${{ matrix.image }} env: BUILD_TYPE: ${{ matrix.build_type }} CMAKE_OPTS: ${{ matrix.CMAKE_OPTS }} CC: ${{ matrix.c_compiler }} CXX: ${{ matrix.cpp_compiler }} CXXFLAGS: ${{ matrix.CXXFLAGS }} LDFLAGS: ${{ matrix.LDFLAGS }} CPP_VERSION: ${{ matrix.cpp_version }} APT_LISTCHANGES_FRONTEND: none DEBIAN_FRONTEND: noninteractive steps: - name: Prepare container (apt) shell: bash if: startsWith(matrix.image, 'debian:') || startsWith(matrix.image, 'ubuntu:') run: | apt-get update -qq apt-get install -yq \ clang \ cmake \ g++ \ git \ libboost-dev \ libboost-program-options-dev \ libbz2-dev \ libexpat1-dev \ liblz4-dev \ make \ nlohmann-json3-dev \ pandoc \ zlib1g-dev - name: Install compiler shell: bash if: matrix.cpp_compiler == 'clang++-14' run: apt-get install -yq --no-install-suggests --no-install-recommends clang-14 - name: Prepare container (dnf) shell: bash if: startsWith(matrix.image, 'fedora:') run: | dnf install --quiet --assumeyes \ boost-devel \ bzip2-devel \ cmake \ expat-devel \ gcc-c++ \ git \ json-devel \ lz4-devel \ make \ pandoc \ zlib-devel - uses: actions/checkout@v4 - uses: ./.github/actions/install-from-git - uses: ./.github/actions/cmake - uses: ./.github/actions/build - uses: ./.github/actions/ctest ubuntu-latest: runs-on: ubuntu-24.04 timeout-minutes: 30 env: CC: clang-18 CXX: clang++-18 BUILD_TYPE: Dev steps: - uses: actions/checkout@v4 - uses: ./.github/actions/install-ubuntu - uses: ./.github/actions/install-from-git - uses: ./.github/actions/cmake - uses: ./.github/actions/build - uses: ./.github/actions/ctest macos: runs-on: ${{ matrix.os }} timeout-minutes: 30 strategy: fail-fast: false matrix: os: - macos-14 - macos-15 build_type: [Dev] include: - os: macos-14 build_type: Release env: CC: clang CXX: clang++ BUILD_TYPE: ${{ matrix.build_type }} steps: - run: brew install boost nlohmann-json - uses: actions/checkout@v4 - uses: ./.github/actions/install-from-git - uses: ./.github/actions/cmake - uses: ./.github/actions/build - uses: ./.github/actions/ctest windows: runs-on: ${{ matrix.os }} timeout-minutes: 30 strategy: fail-fast: false matrix: os: - windows-2019 - windows-2022 - windows-2025 steps: - run: | vcpkg install \ boost-iterator:x64-windows \ boost-program-options:x64-windows \ boost-variant:x64-windows \ bzip2:x64-windows \ expat:x64-windows \ lz4:x64-windows \ nlohmann-json:x64-windows \ zlib:x64-windows shell: bash - uses: actions/checkout@v4 - uses: ./.github/actions/install-from-git - uses: ./.github/actions/cmake-windows - uses: ./.github/actions/build - uses: ./.github/actions/ctest osmium-tool-1.17.0/.github/workflows/clang-tidy.yml000066400000000000000000000033321474143067200222500ustar00rootroot00000000000000name: clang-tidy on: workflow_dispatch jobs: clang-tidy: runs-on: ubuntu-latest strategy: fail-fast: false matrix: image: ["debian:bookworm", "debian:testing", "debian:experimental"] include: - image: "debian:bookworm" clang: 15 - image: "debian:testing" clang: 19 - image: "debian:experimental" clang: 20 container: image: ${{ matrix.image }} env: BUILD_TYPE: Dev CC: clang-${{ matrix.clang }} CXX: clang++-${{ matrix.clang }} CPP_VERSION: c++14 APT_LISTCHANGES_FRONTEND: none DEBIAN_FRONTEND: noninteractive steps: - name: Prepare container (apt) run: | apt-get update -qq apt-get install -yq \ clang-${{ matrix.clang }} \ clang-tidy-${{ matrix.clang }} \ cmake \ git \ libboost-dev \ libboost-program-options-dev \ libbz2-dev \ libexpat1-dev \ liblz4-dev \ make \ nlohmann-json3-dev \ zlib1g-dev shell: bash - uses: actions/checkout@v4 - uses: ./.github/actions/install-from-git - uses: ./.github/actions/cmake - name: Run clang-tidy run: make clang-tidy | tee osmium-tool-${{ github.sha }}-clang-tidy-${{ matrix.clang }}.log shell: bash working-directory: build - name: Upload clang-tidy log uses: actions/upload-artifact@v4 if: always() with: name: osmium-tool-${{ github.sha }}-clang-tidy-${{ matrix.clang }}-log path: build/osmium-tool-${{ github.sha }}-clang-tidy-${{ matrix.clang }}.log osmium-tool-1.17.0/.gitignore000066400000000000000000000000621474143067200160620ustar00rootroot00000000000000.*.swp .ycm_extra_conf.pyc /build /libosmium-deps osmium-tool-1.17.0/CHANGELOG.md000066400000000000000000000706111474143067200157120ustar00rootroot00000000000000 # Change Log All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). ## [unreleased] - ### Added ### Changed ### Fixed ## [1.17.0] - 2025-01-14 ### Added - Add options to the "diff" command to ignore changeset, uid, and/or user attributes. - More tests. ### Changed - Needs at least libosmium version 2.20.0. - Switch from RapidJSON to NLohman JSON. RapidJSON hasn't seen an update in a long time, so we are using a different JSON library. - Removed "spaten" output format. - Open writer in some commands earlier, so we see potential errors earlier. - Lots of small code cleanups. ### Fixed - Fix reading from STDIN for sort command. - Make tests using binary files optional, because they don't work with zlib-ng that some distributions use. Use `-DRUN_TESTS_WITH_BINARY_COMPARE=OFF` to switch off those tests. ## [1.16.0] - 2023-09-20 ### Added - Add "tags" strategy option for smart extract strategy. This checks relations for the specified keys/tags. For a relation to be completed it has to match the keys/tags. ### Changed - Limit the number of extracts possible with osmium extract to 500. Prevents us from running out of file descriptors. ### Fixed - Extract with a polygon could fail in some circumstances. - Compile problem on Windows due to our use of `GetObject()` function from RapidJSON. ## [1.15.0] - 2023-01-19 ### Changed - Now requires libosmium version 2.17.0 or newer. - Remove the long-deprecated `--remove-deleted/--simplify` option on the `apply-changes` command. - Remove the long-deprecated `--omit-rs` option on the `export` command. - Remove the long-deprecated `--history` option on the `getid` command. - Update included Catch to v2.13.10. - Various small code cleanups. ### Fixed - Fix for polygon extracts. Sometimes objects outside the polygon used for extraction could end up in the output. - Correctly detect relative paths on Windows. - Fixes cross-compiling for mingw. ## [1.14.0] - 2022-02-07 ### Added - Add `--keep-member-nodes` option to `add-locations-to-ways` command. When this is set, all nodes referenced directly from relations are kept in the output. If this is used, the input file is read twice an a bit more memory is needed. Osmium will run around 15% longer than without this option. - Add `-S relations=false` option to `complete_ways` extract strategy. If you don't need any relations you can set this when using `osmium extract` and the extract will be done more quickly. - New `--clean` option to `osmium extract` command to clean attributes. ### Changed - Switch to C++14 and CMake 3.5.0 as a minimum requirements. - Switch to [Catch version 2](https://github.com/catchorg/Catch2/tree/v2.x) testing framework. ### Fixed - Fix possible crash when pager set for `osmium show` command was less then 4 characters long. - Fixed hangup in `osmium show` when a non-existing pager was used. - Fixed some tests. - Fix/improve error detection in export code. More errors are detected now which makes a difference when the `-e` or `-E` options are used. ## [1.13.2] - 2021-10-05 ### Added - New `osmium removeid` command to remove all objects with the specified IDs from an OSM file. (This is, in a way, the opposite of the `osmium getid` command.) - New `osmium-output-headers(5)` man page with details about the settings supported by the `--output-header` command line option. - New `-g header.boxes` output option to `osmium fileinfo` to get the bounding box(es) set in the header. - New option `--attributes` for the export command to specified attributes that should show up in the output files. (This needed a config file before.) - New option `--buffer-data` for `osmium cat` command to buffer all read data in memory before writing it out again. Can be used for benchmarking. ### Changed - The `osmium merge` command now checks that the input files are ordered correctly and warns or stops if this is not the case. - Improved messages about files read in verbose mode for `osmium cat`. ### Fixed - Fixed relation member recursion in tags-filter so that objects referenced from matching relations are also in the output. - Fix point-in-polygon-check in extract command. More nodes directly on the boundary should now be inside the polygon. This fixes a problem with extracts on the antimeridian. - When an output file name for the extract command contains multiple dots (.), the file type could not always be deduced correctly. This improves detection for .json and .poly files. - Do not show progress when any of the inputs is stdin. Because we don't know how large the input file is we can't display a reliable progress indicator. - Allow `none` index type on `osmium export`. ## [1.13.1] - 2021-02-01 ### Changed - Update `osmium-file-formats` man page to include newer file format options. ### Fixed - The `extract` command did not work correctly on history files. Sometimes deleted objects were not detected as such and the resulting file was not a correct history file. - Open input file only once in `tags-filter` command if `-R`, `--omit-referenced` is used. This way it works when reading from STDIN. ## [1.13.0] - 2021-01-08 ### Added - Add support for negative IDs in add-locations-to-ways command. - Show setting of `-i`, `--invert-match` option on tags-filter command. - Show bytes read and written in verbose mode in `osmium cat` output. ### Changed - Now depends on libosmium 2.16.0 or greater. - Has support for PBF lz4 compression which is enabled by default if the library is found. Disable by setting CMake option `WITH_LZ4` to `OFF`. - An OSM file header can now be set based on the input file header in extract command from the config file. Set the header to the special `null` value for this. - The `fileinfo` command now shows a **Metadata** section as described in the man page. ### Fixed - When using the `-I`, `--id-osm-file` option in the `tags-filter` command, not only the objects in the specified file were marked but also the nodes referenced from ways and the members referenced from relations. This had two results: a) When not using `-r`, `--add-referenced`: too many objects ended up in the resulting file. b) When using `-t`, `--remove-tags`: tags from those member objects were not removed. - When change files have been created from extracts it is possible that they contain objects with the same type, id, version, and timestamp. In that case we still want to get the last object available. This is now done correctly. - Various man page fixes. ## [1.12.1] - 2020-06-27 ### Changed * Require libosmium 2.15.6 which has an important fix related to multipolygons assembly (needed for "osmium export"). ## [1.12.0] - 2020-04-21 ### Added * New `osmium tags-count` command. * New `--clean` option to `osmium cat` command to clean attributes. ### Fixed * Allow index types with file name in export command. ## [1.11.1] - 2019-11-20 ### Added * Introduce a generic facility for setting output format options. They can be set on the command line (`--format-option`/`-x`) or in the `format_options` section in the config file. Settings can be any OPTION=VALUE type string. There are two new settings: For the geojsonseq format, the option `print_record_separator=false` replaces the command line option `--omit-rs`/`-r` which is now deprecated. The `tags_format` option for the Pg output format allows using the `hstore` type for tags instead of `json(b)`. ### Changed * Open output file earlier in tags-filter command, so we see it immediately in case this fails. ### Fixed * When tags-filter is used with `--remove-tags`, matching ways got their tags removed if they are also referenced from relations. This was clearly wrong. ## [1.11.0] - 2019-09-16 ### Added * New option `--remove-tags`/`-t` to `getid` command. When used the tags of all objects are removed that are not explicitly requested but are only included to complete references. * Add `create-locations-index` and `query-locations-index` commands. These are used to create, update, query and dump node location indexes on disk. These indexes store the location of nodes, typically to add them to ways and relations later. It is the same format used by osm2pgsql (they call it "flat node store") and by the `add-locations-to-ways` command. * Support for new [Spaten](https://thomas.skowron.eu/spaten/) export format. * Add special syntax for `--output-header` to copy header from input. Sometimes it is useful to copy header fields from the input to the output, for instance the `osmosis_replication_timestamp` field. This can now be done for some commands (currently only `extract`) by using the special syntax `--output-header=OPTION!`, i.e. using an exclamation mark instead of setting a value. ### Changed * Better checking of coordinates in extract boundary polygons/bboxes. * Compile with NDEBUG in RelWithDebInfo mode. * Various code cleanups based on problems found with clang-tidy. * Updated Catch to version 1.12.2. * Mark PBF output of extract, renumber, and sort commands as sorted. Uses the new header option `sorting` of the libosmium library which is not in a released version yet. This sets the `Sort.Type_then_ID` header property in the PBF file. ### Fixed * Only check if way is closed after check that it contains nodes. * `get_start_id()` is not `noexcept`. * Man pages correctly show options starting with double dash and other small man page fixes. * Allow file-based location index types (`dense_file_array` and `sparse_file_array`) that need a file name. Using them was not possible because of an overzealous check that didn't recognize the file name. ## [1.10.0] - 2018-12-10 ### Added * The `fileinfo` command now has an `--object-type`/`-t` option like some other commands. * Extended `fileinfo` command to show internal buffer counts and sizes. * Add `--strategy` option to `sort` command. New `multipass` strategy which reads the input file(s) three times making the sort a bit slower, but also using less memory. * New option `--remove-tags`/`-t` to `tags-filter` command. When used the tags of all objects that are not matching the filter expression but are included as references are removed. * New option for smart extract strategy: `complete-partial-relations=X` will complete all relations with at least X percent of their members already in the extract. * New export format "pg" creates a file in the PostgreSQL COPY text format with the GEOMETRY as WKB and the tags in JSON(B) format. This can be imported into a PostgreSQL/PostGIS database very quickly. ### Changed * Show better error message if output directory is missing for `extract` command. ### Fixed * Several fixes for the `tags-filter` command which could lead to wrong results. ## [1.9.1] - 2018-08-18 ### Changed * Improved `export` command man page. ### Fixed * Regression: Default for `linear_tags` and `area_tags` should be `true`. It was before v1.9.0 and it is documented this way. ## [1.9.0] - 2018-08-11 ### Added - Add area matching to `tags-filter`. The `tags-filter` command can now match "areas" using the "a/" prefix. Areas in this sense are all closed ways with 4 or more nodes and all relations with tag "type=multipolygon" or "type=boundary". - Add `--geometry-types` option to the `export` command allowing you to restrict the geometry types written out. - Also print out smallest node, way, and relation ID in `fileinfo` command. - In the `renumber` command, the start IDs for nodes, ways, and relations can now be set together or separately with the `--start-id` option. Negative IDs are now also allowed. Also there is a new `--show-index` function that prints out the ID mappings in the index. - More tests and updated documentation. - Add `-C`, `--print-default-config` option to the `export` command writing out the default configuration to stdout. - New `getparents` command to get the ways used by specified nodes or relations having specified members. ### Changed - Newest version of libosmium (2.14.2) and protozoro (1.6.3) are now required. - Calculation of CRC32 in the fileinfo command is now optional. Calculating the CRC32 is very expensive and going without it makes the program much much faster. Use --crc/-c to enable it. It will also be automatically enabled for JSON output to stay compatible with earlier versions of Osmium which might be used in an automated context (you can disable this with `--no-crc`). It is also enabled if `-g data.crc32` is specified. If it is enabled we are using the CRC32 implementation from zlib which is faster than the one from boost we used before. This is possible through some changes in libosmium. - Treat ways with same node end locations as closed in `export` command instead of looking at the IDs. This is more consistent with what the libosmium `MultipolygonManager` does. - In the `export` command, the decision whether a way is treated as a linestring or polygon has changed. See the man page for details. - Create linestring geometries for untagged ways if `-n` or `--keep-untagged` option is set. It doesn't matter whether they are closed or not, they are only written out as linestrings. ### Fixed - Show error for ways with less than 2 nodes if --show-errors is set. - Attributes (such as id, version, timestamp, etc.) can appear in the properties of the output with arbitrary configurable names. These could overlap with tag keys which we don't want. This change removes tags with those keys on the assumption that the names chosen for the attributes are sufficiently different (something like "@id") from normal tag keys that this will not happen very often and those tags are useless anyway. - Make `--(no)-progress` option work in `sort` command. ## [1.8.0] - 2018-03-31 ### Added - Support for negative IDs in export command. - Lots of tests with missing metadata (Thanks to Michael Reichert). - Add metadata options to the extended output of fileinfo command (Thanks to Michael Reichert). - Add progress bars to many commands. - Add `--redact` option to the `apply-changes` command to redact (patch) history files. The change files can contain any version of any object which will replace that version of that object from the input. This allows changing the history! This mode is for special use only, for instance to remove copyrighted or private data. ### Changed - Needs libosmium 2.14.0. - Update included `catch.hpp` to version 1.12.1. - Removed Makefile. Undocumented and possibly confusing way of building. As documented, use CMake directly instead. - Allow bbox setting with any two opposing corners, instead of insisting on bottom-left and top-right corner. This affects the changeset-filter and extract commands. - Allow GeoJSON input file to have a FeatureCollection instead of a Feature. Only the first feature of this collection is used. ### Fixed - Bug in the derive-changes command if it is used without `--keep-details`. A deletion of any type of object was written as a deletion of a node. (Thanks to Michael Reichert.) - Fix assertion failure in diff command. - Throw exception instead of using assert to catch broken rings. - Disable progress bar if STDOUT isn't a tty. - Show error when there are no extracts specified in extract command. - Improve STDIN handling in extract command. STDIN can now be used with the `simple` strategy, with other strategies it will give you a nice error message. - Lots of code cleanups based on `clang-tidy` warnings making the code more robust. - Only install manpage directories, not CMake files. (Thanks Bas Couwenberg.) ## [1.7.1] - 2017-08-25 ### Added - Extended some man pages. ### Changed - Allow any OSM file header option with `fileinfo -g`. There is no final list of possible options, so any option should be allowed. - Needs libosmium 2.13.1. ### Fixed - Specifying extracts in config files was broken. The `extract` command was not reading config files correctly and all resulting OSM files were empty. Specifying an extract on the command line using `--bbox` or `--polygon` was still working. - Allow zero-length index files in renumber. ## [1.7.0] - 2017-08-15 ### Added - New `export` command for exporting OSM data into GeoJSON format. The OSM data model with its nodes, ways, and relations is very different from the data model usually used for geodata with features having point, linestring, or polygon geometries. The export command transforms OSM data into a more usual GIS data model. Nodes will be translated into points and ways into linestrings or polygons (if they are closed ways). Multipolygon and boundary relations will be translated into multipolygons. This transformation is not loss-less, especially information in non-multipolygon, non-boundary relations is lost. All tags are preserved in this process. Note that most GIS formats (such as Shapefiles, etc.) do not support arbitrary tags. Transformation into other GIS formats will need extra steps mapping tags to a limited list of attributes. This is outside the scope of this command. - New `--bbox/-B` option to `changeset-filter` command. Only changesets with bounding boxes overlapping this bounding box are copied to the output. - Support for the new `flex_mem` index type for node location indexes. It is used by default in the `add_locations_to_ways` and `export` commands. The new man page `osmium-index-types` documents this and other available indexes. ### Changed - The order of objects in an OSM file expected by some commands as well as the order created by the `sort` command has changed when negative IDs are involved. (Negative IDs are sometimes used for objects that have not yet been uploaded to the OSM server.) The negative IDs are ordered now before the positive ones, both in order of their absolute value. This is the same ordering as JOSM uses. - The commands `check-refs`, `fileinfo`, and `renumber` now also work with negative object IDs. - Allow leading spaces in ID files for `getid` command. - Various error messages and man pages have been clarified. - Updated minimum libosmium version required to 2.13.0. - Update version of Catch unit test framework to 1.9.7. ### Fixed - Libosmium fix: Changesets with more than 2^16 characters in comments now work. - Libosmium fix: Changeset bounding boxes are now always output to OSM files (any format) if at least one of the corners is defined. This is needed to handle broken data from the main OSM database which contains such cases. This now also works when reading OPL files. ## [1.6.1] - 2017-04-10 ### Changed - Clarify differences between `diff` and `derive-changes` commands in man pages. - Needs current libosmium 2.12.1 now. ### Fixed - Use empty header for apply-changes instead of the one from input file. - Call 'less' with -R when using ANSI colors with 'show' command. - Do not show progress options on show command. ## [1.6.0] - 2017-03-07 ### Added - New `tags-filter` command for filtering OSM files based on tag keys and values. - Add option `--locations-on-ways` to `apply-changes` for updating files created with `add-locations-to-ways`. - Add optional `output_header` on extracts in config file. (#47) - Add `--change-file-format` to `apply-changes` format for setting format of change files. - Add `--set-bounds` option to `extract` command. ### Changed - Now requires libosmium 2.12. - Deprecated `--history` option on `getid` command in favour of `--with-history` for consistency with other commands. - Use new `RelationsMapIndex` from libosmium for `getid` instead of `std::multimap`. - Update included version of Catch unit test framework to 1.8.1 which required some changes in the tests. - Use `osmium::util::file_size` instead of our own `filesize()` function. - Miscellaneous code cleanups and improved warning messages and man pages. ### Fixed - Add `-pthread` compiler and linker options on Linux/OSX. This should fix a problem where some linker versions will not link binaries correctly when the `--as-needed` option is used. - Typo in GeoJSON parser which broke MultiPolygon support. - Wrong description of -S option in extract man page. - Windows build problem related to forced build for old Windows versions. - All but the first polygon in a GeoJSON multipolygon were ignored by the `extract` command. - Zsh command line completion for some commands. ## [1.5.1] - 2017-01-19 ### Changed - Build with warnings in all build types, not only "Dev". - Better error messages for command line errors. ### Fixed - Make `--overwrite` and `--fsync` work in `derive_changes` command. - A dereference of end iterator in `derive_changes`. - You can not specify the special file name "-" (to read from STDIN) several times for commands reading multiple files. ## [1.5.0] - 2017-01-18 ### Added - New `extract` command to cut out geographical regions from an OSM file using a bounding box or (multi)polygon. ## [1.4.1] - 2016-11-20 ### Added - Add hint to error message about `--overwrite` option when trying to open an existing file. - Check the required libosmium version in CMake build. ### Changed - Add --ignore-missing-nodes to `add-locations-to-ways` subcommand. If this is not set, the command will now fail if there are missing nodes needed for ways. - The `check-refs` and `getid` subcommands now use the IdSet class from the newest libosmium making them more efficient (especially on very large input files). - Improved error messages for low-level errors. - Now requires at least libosmium 2.10.2 and protozero 1.4.5. ### Fixed - Consistently handle `--output-header` option in all commands that create standard OSM files. - Handling of some output options was not correct in `diff` command. They do now what is documented and it is documented what they do. - Progress bar and output from verbose mode will now be kept separate. ## [1.4.0] - 2016-09-15 ### Added - The new manual is a more gentle introduction into the capabilities of Osmium Tool. Numerous man page additions. - New `merge` command to merge any number of sorted OSM files. - New `derive-changes` command to create change file from two OSM data files. - New `diff` command to show differences between OSM files. - The `renumber` command can now optionally only renumber some object types. - Version information is now printed including the git commit id and always shown in verbose mode. - Added `iwyu` target to CMake config. - Progress bars will be shown on some commands. (This is configurable at run time with the `--progress` and `--no-progress` options.) ### Changed - The `apply-changes` subcommand now detects whether it is updating a normal OSM file or an OSM history file based on file name suffix (can be forced with `--with-history`). The options `--simplify` and `--remove-deleted` are now deprecated (a warning will be written to stderr). For normal OSM files, output is always simplified and deleted objects are removed, for OSM history files, all versions of all objects are kept. - Also check ordering of changesets in `osmium fileinfo -e`. - The `getid` options `-i` and `-I` can now be used multiple times. - More consistent warning messages. - Compiles much faster due to include optimizations. - Update the included RapidJSON to version 1.1.0. ### Fixed - CMake now creates `compile_commands.json`. - Wrapper script now works with quoted arguments. ## [1.3.1] - 2016-06-08 ### Added - Check that input files are correctly ordered in the `renumber` and `check-refs` commands. - Most commands now show the memory used in verbose mode. - New option `-h`/`--help` on most commands shows command line options. - New `--default-type` option to getid command. - The `getid` command can now recursively add all referenced objects. - New `show` command to quickly see OSM file contents. - New `add-locations-to-ways` command. ### Changed - Much faster and more memory efficient implementation of the `renumber` command. - The `getid` command can now read IDs from *stdin*. - Also show libosmium version when running `version` subcommand. ## [1.3.0] - 2015-11-17 ### Added - Add new `sort` subcommand for sorting OSM data files, history files, and change files. - Add new `changeset-filter` subcommand. - New option `--fsync` on all subcommands that write an OSM file. Will call fsync after writing any file. ### Changed - Uses new libosmium version now (use at least libosmium version 2.5.3). ## [1.2.1] - 2015-08-31 ### Changed - Uses new libosmium version now (use at least libosmium version 2.4.1). ### Fixed - Several Windows line ending issues were fixed. Consistently uses files in binary mode now with LF line endings. - CRC calculation fixed in libosmium. ## [1.2.0] - 2015-08-18 ### Added - Added lots of tests. ### Changed - Uses new libosmium version now (use at least libosmium version 2.3.0). - Many corrections and updates in manual pages. - Change CRC32 implementation. The new implementation uses the newly added CRC functions from libosmium. This should make the CRC independent of host architecture and endianness. - Lots of refactoring code cleanups. ### Fixed - Remove license that's not applicable from LICENSE-rapidjson.txt. - Renumbering didn't work properly in some cases. - Fix error checking in renumber command. ## [1.1.1] - 2015-07-04 ### Fixed - Osmium fileinfo --show-variables didn't work properly. - Improved zsh autocompletion ## [1.1.0] - 2015-07-04 ### Added - New getid subcommand to filter by node/way/relation IDs. - New renumber subcommand to renumber IDs in OSM files. - New check-refs subcommand to check referential integrity in OSM files. - Improved testing framework and added some functional tests. - Fileinfo subcommand can now output a single variable using `-g`. - Fileinfo subcommand can now output all data in JSON format using the RapidJSON library (which is included in the code). - Fileinfo subcommand now also shows largest ID of each type. ### Changed - Lots of refactoring to handle command line parsing for different subcommands in a uniform manner. Now pretty much all command line options concerning file input and output are consistent across subcommand. - Uses newest libosmium. ### Fixed - Time-fiter subcommand: Fixed case where objects are updated twice in the same second. - Some corrections in man pages. ## [1.0.1] - 2015-03-31 ### Changed - Minor updates to documentation and build system [unreleased]: https://github.com/osmcode/osmium-tool/compare/v1.17.0...HEAD [1.17.0]: https://github.com/osmcode/osmium-tool/compare/v1.16.0...v1.17.0 [1.16.0]: https://github.com/osmcode/osmium-tool/compare/v1.15.0...v1.16.0 [1.15.0]: https://github.com/osmcode/osmium-tool/compare/v1.14.0...v1.15.0 [1.14.0]: https://github.com/osmcode/osmium-tool/compare/v1.13.2...v1.14.0 [1.13.2]: https://github.com/osmcode/osmium-tool/compare/v1.13.1...v1.13.2 [1.13.1]: https://github.com/osmcode/osmium-tool/compare/v1.13.0...v1.13.1 [1.13.0]: https://github.com/osmcode/osmium-tool/compare/v1.12.1...v1.13.0 [1.12.1]: https://github.com/osmcode/osmium-tool/compare/v1.12.0...v1.12.1 [1.12.0]: https://github.com/osmcode/osmium-tool/compare/v1.11.1...v1.12.0 [1.11.1]: https://github.com/osmcode/osmium-tool/compare/v1.11.0...v1.11.1 [1.11.0]: https://github.com/osmcode/osmium-tool/compare/v1.10.0...v1.11.0 [1.10.0]: https://github.com/osmcode/osmium-tool/compare/v1.9.1...v1.10.0 [1.9.1]: https://github.com/osmcode/osmium-tool/compare/v1.9.0...v1.9.1 [1.9.0]: https://github.com/osmcode/osmium-tool/compare/v1.8.0...v1.9.0 [1.8.0]: https://github.com/osmcode/osmium-tool/compare/v1.7.1...v1.8.0 [1.7.1]: https://github.com/osmcode/osmium-tool/compare/v1.7.0...v1.7.1 [1.7.0]: https://github.com/osmcode/osmium-tool/compare/v1.6.1...v1.7.0 [1.6.1]: https://github.com/osmcode/osmium-tool/compare/v1.6.0...v1.6.1 [1.6.0]: https://github.com/osmcode/osmium-tool/compare/v1.5.1...v1.6.0 [1.5.1]: https://github.com/osmcode/osmium-tool/compare/v1.5.0...v1.5.1 [1.5.0]: https://github.com/osmcode/osmium-tool/compare/v1.4.1...v1.5.0 [1.4.1]: https://github.com/osmcode/osmium-tool/compare/v1.4.0...v1.4.1 [1.4.0]: https://github.com/osmcode/osmium-tool/compare/v1.3.1...v1.4.0 [1.3.1]: https://github.com/osmcode/osmium-tool/compare/v1.3.0...v1.3.1 [1.3.0]: https://github.com/osmcode/osmium-tool/compare/v1.2.1...v1.3.0 [1.2.1]: https://github.com/osmcode/osmium-tool/compare/v1.2.0...v1.2.1 [1.2.0]: https://github.com/osmcode/osmium-tool/compare/v1.1.0...v1.2.0 [1.1.1]: https://github.com/osmcode/osmium-tool/compare/v1.1.0...v1.1.1 [1.1.0]: https://github.com/osmcode/osmium-tool/compare/v1.0.1...v1.1.0 [1.0.1]: https://github.com/osmcode/osmium-tool/compare/v1.0.0...v1.0.1 osmium-tool-1.17.0/CMakeLists.txt000066400000000000000000000233751474143067200166460ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool # #----------------------------------------------------------------------------- cmake_minimum_required(VERSION 3.10) project(osmium VERSION 1.17.0 LANGUAGES CXX C) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") #----------------------------------------------------------------------------- # # Project version # #----------------------------------------------------------------------------- # It is important that this setting remains before the "project" call. set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel;Dev" CACHE STRING "List of available configuration types" FORCE) set(AUTHOR "Jochen Topf ") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) option(WITH_LZ4 "Build with lz4 support for PBF files" ON) option(BUILD_TESTING "Build the tests" ON) # Some tests compare with binary files which might be different on your # setup. Setting this to OFF disables those test. # See https://github.com/osmcode/osmium-tool/issues/274 option(RUN_TESTS_WITH_BINARY_COMPARE "Run tests that do binary comparisons" ON) #----------------------------------------------------------------------------- # # Find external dependencies # #----------------------------------------------------------------------------- find_package(Boost 1.55.0 REQUIRED COMPONENTS program_options) include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) find_package(Osmium 2.20.0 REQUIRED COMPONENTS io) include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS}) find_package(nlohmann_json) find_path(NLOHMANN_INCLUDE_DIR nlohmann/json.hpp) include_directories(SYSTEM ${NLOHMANN_INCLUDE_DIR}) if(WITH_LZ4) find_package(LZ4) if(LZ4_FOUND) message(STATUS "lz4 library found, compiling with it") add_definitions(-DOSMIUM_WITH_LZ4) include_directories(SYSTEM ${LZ4_INCLUDE_DIRS}) list(APPEND OSMIUM_LIBRARIES ${LZ4_LIBRARIES}) else() message(WARNING "lz4 library not found, compiling without it") endif() else() message(STATUS "Building without lz4 support: Set WITH_LZ4=ON to change this") endif() #----------------------------------------------------------------------------- # # Optional "cppcheck" target that checks C++ code # #----------------------------------------------------------------------------- message(STATUS "Looking for cppcheck") find_program(CPPCHECK cppcheck) if(CPPCHECK) message(STATUS "Looking for cppcheck - found") set(CPPCHECK_OPTIONS --enable=warning,style,performance,portability,information,missingInclude) # cpp doesn't find system includes for some reason, suppress that report set(CPPCHECK_OPTIONS ${CPPCHECK_OPTIONS} --suppress=missingIncludeSystem) add_custom_target(cppcheck ${CPPCHECK} --std=c++14 ${CPPCHECK_OPTIONS} ${CMAKE_SOURCE_DIR}/src/*pp) else() message(STATUS "Looking for cppcheck - not found") message(STATUS " Build target 'cppcheck' will not be available") endif() #----------------------------------------------------------------------------- # # Optional "iwyu" target to check headers # https://include-what-you-use.org/ # #----------------------------------------------------------------------------- find_program(IWYU_TOOL NAMES iwyu_tool iwyu_tool.py) if(IWYU_TOOL) message(STATUS "Looking for iwyu_tool.py - found") add_custom_target(iwyu ${IWYU_TOOL} -p ${CMAKE_BINARY_DIR} -- --mapping_file=${CMAKE_SOURCE_DIR}/iwyu.imp) else() message(STATUS "Looking for iwyu_tool.py - not found") message(STATUS " Make target 'iwyu' will not be available") endif() #----------------------------------------------------------------------------- # # Decide which C++ version to use (Minimum/default: C++14). # #----------------------------------------------------------------------------- if(NOT MSVC) if(NOT USE_CPP_VERSION) set(USE_CPP_VERSION c++14) endif() message(STATUS "Use C++ version: ${USE_CPP_VERSION}") add_compile_options(-std=${USE_CPP_VERSION}) endif() #----------------------------------------------------------------------------- # # Compiler and Linker flags # #----------------------------------------------------------------------------- if(MSVC) set(DEV_COMPILE_OPTIONS "/Ox") set(RWD_COMPILE_OPTIONS "/Ox /DNDEBUG") else() set(DEV_COMPILE_OPTIONS "-O3 -g") set(RWD_COMPILE_OPTIONS "-O3 -g -DNDEBUG") endif() if(WIN32) add_definitions(-DWIN32 -D_WIN32 -DMSWIN32 -DBGDWIN32) endif() set(CMAKE_CXX_FLAGS_DEV "${DEV_COMPILE_OPTIONS}" CACHE STRING "Flags used by the compiler during developer builds." FORCE) set(CMAKE_EXE_LINKER_FLAGS_DEV "" CACHE STRING "Flags used by the linker during developer builds." FORCE) mark_as_advanced( CMAKE_CXX_FLAGS_DEV CMAKE_EXE_LINKER_FLAGS_DEV ) set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${RWD_COMPILE_OPTIONS}" CACHE STRING "Flags used by the compiler during RELWITHDEBINFO builds." FORCE) #----------------------------------------------------------------------------- # # Build Type # #----------------------------------------------------------------------------- add_definitions(${OSMIUM_WARNING_OPTIONS}) # In 'Dev' mode: compile with very strict warnings and turn them into errors. if(CMAKE_BUILD_TYPE STREQUAL "Dev") if(NOT MSVC) add_definitions(-Werror) endif() endif() # Force RelWithDebInfo build type if none was given if(CMAKE_BUILD_TYPE) set(build_type ${CMAKE_BUILD_TYPE}) else() set(build_type "RelWithDebInfo") endif() set(CMAKE_BUILD_TYPE ${build_type} CACHE STRING "Choose the type of build, options are: ${CMAKE_CONFIGURATION_TYPES}." FORCE) message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}") #----------------------------------------------------------------------------- # # Version # #----------------------------------------------------------------------------- find_package(Git) if(GIT_FOUND) execute_process(COMMAND "${GIT_EXECUTABLE}" describe --tags --dirty=-changed WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE VERSION_FROM_GIT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if(VERSION_FROM_GIT) set(VERSION_FROM_GIT " (${VERSION_FROM_GIT})") endif() endif() configure_file( ${PROJECT_SOURCE_DIR}/src/version.cpp.in ${PROJECT_BINARY_DIR}/src/version.cpp ) #----------------------------------------------------------------------------- configure_file( ${PROJECT_SOURCE_DIR}/osmium-wrapper.in ${PROJECT_BINARY_DIR}/osmium ) include_directories(SYSTEM include) include_directories(${PROJECT_BINARY_DIR}/src) #----------------------------------------------------------------------------- SET(OSMIUM_COMMANDS add-locations-to-ways apply-changes cat changeset-filter check-refs create-locations-index derive-changes diff export extract fileinfo getid getparents merge merge-changes query-locations-index removeid renumber show sort tags-count tags-filter time-filter ) set(OSMIUM_SOURCE_FILES cmd.cpp cmd_factory.cpp id_file.cpp io.cpp util.cpp command_help.cpp option_clean.cpp export/export_format_json.cpp export/export_format_pg.cpp export/export_format_text.cpp export/export_handler.cpp extract/extract_bbox.cpp extract/extract.cpp extract/extract_polygon.cpp extract/geojson_file_parser.cpp extract/geometry_util.cpp extract/osm_file_parser.cpp extract/poly_file_parser.cpp extract/strategy_complete_ways.cpp extract/strategy_complete_ways_with_history.cpp extract/strategy_simple.cpp extract/strategy_smart.cpp ) foreach(_command ${OSMIUM_COMMANDS}) string(REPLACE "-" "_" _ucmd ${_command}) list(APPEND OSMIUM_SOURCE_FILES "command_${_ucmd}.cpp") endforeach() add_subdirectory(man) add_subdirectory(src) #----------------------------------------------------------------------------- # # Tests # #----------------------------------------------------------------------------- if(BUILD_TESTING) enable_testing() add_subdirectory(test) endif() #----------------------------------------------------------------------------- # # Optional "clang-tidy" target # #----------------------------------------------------------------------------- message(STATUS "Looking for clang-tidy") find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-20 clang-tidy-19 clang-tidy-18 clang-tidy-17 clang-tidy-16 clang-tidy-15 clang-tidy-14) if(CLANG_TIDY) message(STATUS "Looking for clang-tidy - found ${CLANG_TIDY}") file(GLOB _unit_tests RELATIVE "${CMAKE_SOURCE_DIR}/src" "${CMAKE_SOURCE_DIR}/test/*/*.cpp") add_custom_target(clang-tidy ${CLANG_TIDY} -p ${CMAKE_BINARY_DIR} ${OSMIUM_SOURCE_FILES} ${_unit_tests} WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src" ) else() message(STATUS "Looking for clang-tidy - not found") message(STATUS " Build target 'clang-tidy' will not be available.") endif() #----------------------------------------------------------------------------- # # Test install # # Does a local install and checks that the files we expect to be installed # are installed and no extra files are installed. If this fails make sure # the list of files in cmake/test_install.cmake is correct. Only enables # if the WITH_EXTRA_TESTS option is set, because this test fails on some # platforms even if everything is correct. # #----------------------------------------------------------------------------- option(WITH_EXTRA_TESTS "Run extra tests (usually only for developers)") if(WITH_EXTRA_TESTS) add_test(NAME testinstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/test_install.cmake) endif() #----------------------------------------------------------------------------- osmium-tool-1.17.0/CONTRIBUTING.md000066400000000000000000000012071474143067200163250ustar00rootroot00000000000000 Some rules for contributing to this project: * Please open a separate issue for each problem, question, or comment you have. Do not re-use existing issues for other topics, even if they are similar. This keeps issues small and manageable and makes it much easier to follow through and make sure each problem is taken care of. If you are reporting a problem: * Describe exactly what you were trying to achieve, what you did, what you expected to happen and what did happen instead. Include relevant information about the platform, OS version etc. you are using. Include shell commands you typed in, log files, errors messages etc. osmium-tool-1.17.0/LICENSE.txt000066400000000000000000001045231474143067200157240ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . osmium-tool-1.17.0/README.md000066400000000000000000000107651474143067200153640ustar00rootroot00000000000000 # Osmium Command Line Tool A multipurpose command line tool for working with OpenStreetMap data based on the Osmium library. Official web site: https://osmcode.org/osmium-tool/ [![Build Status](https://github.com/osmcode/osmium-tool/actions/workflows/ci.yml/badge.svg)](https://github.com/osmcode/osmium-tool/actions) ## Prerequisites You need a C++14 compliant compiler. You also need the following libraries: Libosmium (>= 2.16.0) https://osmcode.org/libosmium Debian/Ubuntu: libosmium2-dev Fedora/CentOS: libosmium-devel Protozero (>= 1.6.3) https://github.com/mapbox/protozero Debian/Ubuntu: libprotozero-dev Fedora/CentOS: protozero-devel NLohmann JSON (>= 3.0) https://json.nlohmann.me/ Debian/Ubuntu: nlohmann-json3-dev boost-program-options (>= 1.55) https://www.boost.org/doc/libs/1_55_0/doc/html/program_options.html Debian/Ubuntu: libboost-program-options-dev Fedora/CentOS: boost-devel openSUSE: boost-devel (use 'libboost_program_options-devel' for modern OS versions) vcpkg: boost-program-options bz2lib http://www.bzip.org/ Debian/Ubuntu: libbz2-dev Fedora/CentOS: bzip2-devel openSUSE: libbz2-devel vcpkg: bzip2 zlib https://www.zlib.net/ Debian/Ubuntu: zlib1g-dev Fedora/CentOS: zlib-devel openSUSE: zlib-devel vcpkg: zlib LZ4 (optional) https://lz4.github.io/lz4/ Debian/Ubuntu: liblz4-dev vcpkg: lz4 Only needed for LZ4 PBF compression. Expat https://libexpat.github.io/ Debian/Ubuntu: libexpat1-dev Fedora/CentOS: expat-devel openSUSE: libexpat-devel vcpkg: expat cmake https://cmake.org/ Debian/Ubuntu: cmake Fedora/CentOS: cmake openSUSE: cmake Pandoc (Needed to build documentation, optional) https://pandoc.org/ Debian/Ubuntu: pandoc Fedora/CentOS: pandoc openSUSE: pandoc On Linux systems most of these libraries are available through your package manager, see the list above for the names of the packages. But make sure to check the versions. If the packaged version available is not new enough, you'll have to install from source. Most likely this is the case for Protozero and Libosmium. On macOS many of the libraries above will be available through Homebrew. On Windows you can install the libraries with vcpkg. When building the tool, CMake will automatically look for these libraries in the usual places on your system. In addition it will look for the Libosmium and Protozero libraries in the same directory where this Osmium repository is. So if you are building from the Git repository and want to use the newest Libosmium, Protozero, and Osmium, clone all of them into the same directory: mkdir work cd work git clone https://github.com/mapbox/protozero git clone https://github.com/osmcode/libosmium git clone https://github.com/osmcode/osmium-tool ## Building Osmium uses CMake for its builds. On Linux and macOS you can build as follows: cd osmium-tool mkdir build cd build cmake .. ccmake . ## optional: change CMake settings if needed make To set the build type call cmake with `-DCMAKE_BUILD_TYPE=type`. Possible values are empty, Debug, Release, RelWithDebInfo, MinSizeRel, and Dev. The default is RelWithDebInfo. Please read the CMake documentation and get familiar with the `cmake` and `ccmake` tools which have many more options. If you have trouble with compiling, look into the files in `.github/workflows` and `.github/actions` that run the CI builds to give you some pointers. ## Documentation See the [Osmium Tool website](https://osmcode.org/osmium-tool/) and [Osmium Tool Manual](https://osmcode.org/osmium-tool/manual.html). There are man pages in the 'man' directory. To build them you need 'pandoc'. If the `pandoc` command was found during the CMake config step, the manpages will be built automatically. ## Tests Call `ctest` in the build directory to run the tests after build. More extensive tests of the libosmium I/O system can also be run. See `test/io/Makefile.in` for instructions. ## License Copyright (C) 2013-2025 Jochen Topf (jochen@topf.org) This program is available under the GNU GENERAL PUBLIC LICENSE Version 3. See the file LICENSE.txt for the complete text of the license. ## Authors This program was written and is maintained by Jochen Topf (jochen@topf.org). osmium-tool-1.17.0/cmake/000077500000000000000000000000001474143067200151545ustar00rootroot00000000000000osmium-tool-1.17.0/cmake/FindLZ4.cmake000066400000000000000000000025321474143067200173720ustar00rootroot00000000000000find_path(LZ4_INCLUDE_DIR NAMES lz4.h DOC "lz4 include directory") mark_as_advanced(LZ4_INCLUDE_DIR) find_library(LZ4_LIBRARY NAMES lz4 liblz4 DOC "lz4 library") mark_as_advanced(LZ4_LIBRARY) if (LZ4_INCLUDE_DIR) file(STRINGS "${LZ4_INCLUDE_DIR}/lz4.h" _lz4_version_lines REGEX "#define[ \t]+LZ4_VERSION_(MAJOR|MINOR|RELEASE)") string(REGEX REPLACE ".*LZ4_VERSION_MAJOR *\([0-9]*\).*" "\\1" _lz4_version_major "${_lz4_version_lines}") string(REGEX REPLACE ".*LZ4_VERSION_MINOR *\([0-9]*\).*" "\\1" _lz4_version_minor "${_lz4_version_lines}") string(REGEX REPLACE ".*LZ4_VERSION_RELEASE *\([0-9]*\).*" "\\1" _lz4_version_release "${_lz4_version_lines}") set(LZ4_VERSION "${_lz4_version_major}.${_lz4_version_minor}.${_lz4_version_release}") unset(_lz4_version_major) unset(_lz4_version_minor) unset(_lz4_version_release) unset(_lz4_version_lines) endif () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LZ4 REQUIRED_VARS LZ4_LIBRARY LZ4_INCLUDE_DIR VERSION_VAR LZ4_VERSION) if (LZ4_FOUND) set(LZ4_INCLUDE_DIRS "${LZ4_INCLUDE_DIR}") set(LZ4_LIBRARIES "${LZ4_LIBRARY}") if (NOT TARGET LZ4::LZ4) add_library(LZ4::LZ4 UNKNOWN IMPORTED) set_target_properties(LZ4::LZ4 PROPERTIES IMPORTED_LOCATION "${LZ4_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${LZ4_INCLUDE_DIR}") endif () endif () osmium-tool-1.17.0/cmake/FindOsmium.cmake000066400000000000000000000256771474143067200202510ustar00rootroot00000000000000#---------------------------------------------------------------------- # # FindOsmium.cmake # # Find the Libosmium headers and, optionally, several components needed # for different Libosmium functions. # #---------------------------------------------------------------------- # # Usage: # # Copy this file somewhere into your project directory, where cmake can # find it. Usually this will be a directory called "cmake" which you can # add to the CMake module search path with the following line in your # CMakeLists.txt: # # list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") # # Then add the following in your CMakeLists.txt: # # find_package(Osmium [version] REQUIRED COMPONENTS ) # include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS}) # # The version number is optional. If it is not set, any version of # libosmium will do. # # For the substitute a space separated list of one or more of the # following components: # # pbf - include libraries needed for PBF input and output # xml - include libraries needed for XML input and output # io - include libraries needed for any type of input/output # geos - include if you want to use any of the GEOS functions # gdal - include if you want to use any of the OGR functions # lz4 - include support for LZ4 compression of PBF files # # You can check for success with something like this: # # if(NOT OSMIUM_FOUND) # message(WARNING "Libosmium not found!\n") # endif() # #---------------------------------------------------------------------- # # Variables: # # OSMIUM_FOUND - True if Osmium found. # OSMIUM_INCLUDE_DIRS - Where to find include files. # OSMIUM_XML_LIBRARIES - Libraries needed for XML I/O. # OSMIUM_PBF_LIBRARIES - Libraries needed for PBF I/O. # OSMIUM_IO_LIBRARIES - Libraries needed for XML or PBF I/O. # OSMIUM_LIBRARIES - All libraries Osmium uses somewhere. # #---------------------------------------------------------------------- # This is the list of directories where we look for osmium includes. set(_osmium_include_path ../libosmium ~/Library/Frameworks /Library/Frameworks /opt/local # DarwinPorts /opt ) # Look for the header file. find_path(OSMIUM_INCLUDE_DIR osmium/version.hpp PATH_SUFFIXES include PATHS ${_osmium_include_path} ) # Check libosmium version number if(Osmium_FIND_VERSION) if(NOT EXISTS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp") message(FATAL_ERROR "Missing ${OSMIUM_INCLUDE_DIR}/osmium/version.hpp. Either your libosmium version is too old, or libosmium wasn't found in the place you said.") endif() file(STRINGS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp" _libosmium_version_define REGEX "#define LIBOSMIUM_VERSION_STRING") if("${_libosmium_version_define}" MATCHES "#define LIBOSMIUM_VERSION_STRING \"([0-9.]+)\"") set(_libosmium_version "${CMAKE_MATCH_1}") else() set(_libosmium_version "unknown") endif() endif() set(OSMIUM_INCLUDE_DIRS "${OSMIUM_INCLUDE_DIR}") #---------------------------------------------------------------------- # # Check for optional components # #---------------------------------------------------------------------- if(Osmium_FIND_COMPONENTS) foreach(_component ${Osmium_FIND_COMPONENTS}) string(TOUPPER ${_component} _component_uppercase) set(Osmium_USE_${_component_uppercase} TRUE) endforeach() endif() #---------------------------------------------------------------------- # Component 'io' is an alias for 'pbf' and 'xml' if(Osmium_USE_IO) set(Osmium_USE_PBF TRUE) set(Osmium_USE_XML TRUE) endif() #---------------------------------------------------------------------- # Component 'ogr' is an alias for 'gdal' if(Osmium_USE_OGR) set(Osmium_USE_GDAL TRUE) endif() #---------------------------------------------------------------------- # Component 'pbf' if(Osmium_USE_PBF) find_package(ZLIB) find_package(Threads) find_package(Protozero 1.6.3) if(Osmium_USE_LZ4) find_package(LZ4 REQUIRED) add_definitions(-DOSMIUM_WITH_LZ4) endif() list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND PROTOZERO_INCLUDE_DIR) if(ZLIB_FOUND AND Threads_FOUND AND PROTOZERO_FOUND) list(APPEND OSMIUM_PBF_LIBRARIES ${ZLIB_LIBRARIES} ${LZ4_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) list(APPEND OSMIUM_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR} ${LZ4_INCLUDE_DIRS} ${PROTOZERO_INCLUDE_DIR} ) else() message(WARNING "Osmium: Can not find some libraries for PBF input/output, please install them or configure the paths.") endif() endif() #---------------------------------------------------------------------- # Component 'xml' if(Osmium_USE_XML) find_package(EXPAT) find_package(BZip2) find_package(ZLIB) find_package(Threads) list(APPEND OSMIUM_EXTRA_FIND_VARS EXPAT_FOUND BZIP2_FOUND ZLIB_FOUND Threads_FOUND) if(EXPAT_FOUND AND BZIP2_FOUND AND ZLIB_FOUND AND Threads_FOUND) list(APPEND OSMIUM_XML_LIBRARIES ${EXPAT_LIBRARIES} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) list(APPEND OSMIUM_INCLUDE_DIRS ${EXPAT_INCLUDE_DIR} ${BZIP2_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) else() message(WARNING "Osmium: Can not find some libraries for XML input/output, please install them or configure the paths.") endif() endif() #---------------------------------------------------------------------- list(APPEND OSMIUM_IO_LIBRARIES ${OSMIUM_PBF_LIBRARIES} ${OSMIUM_XML_LIBRARIES} ) list(APPEND OSMIUM_LIBRARIES ${OSMIUM_IO_LIBRARIES} ) #---------------------------------------------------------------------- # Component 'geos' if(Osmium_USE_GEOS) find_path(GEOS_INCLUDE_DIR geos/geom.h) find_library(GEOS_LIBRARY NAMES geos) list(APPEND OSMIUM_EXTRA_FIND_VARS GEOS_INCLUDE_DIR GEOS_LIBRARY) if(GEOS_INCLUDE_DIR AND GEOS_LIBRARY) SET(GEOS_FOUND 1) list(APPEND OSMIUM_LIBRARIES ${GEOS_LIBRARY}) list(APPEND OSMIUM_INCLUDE_DIRS ${GEOS_INCLUDE_DIR}) else() message(WARNING "Osmium: GEOS library is required but not found, please install it or configure the paths.") endif() endif() #---------------------------------------------------------------------- # Component 'gdal' (alias 'ogr') if(Osmium_USE_GDAL) find_package(GDAL) list(APPEND OSMIUM_EXTRA_FIND_VARS GDAL_FOUND) if(GDAL_FOUND) list(APPEND OSMIUM_LIBRARIES ${GDAL_LIBRARIES}) list(APPEND OSMIUM_INCLUDE_DIRS ${GDAL_INCLUDE_DIRS}) else() message(WARNING "Osmium: GDAL library is required but not found, please install it or configure the paths.") endif() endif() #---------------------------------------------------------------------- list(REMOVE_DUPLICATES OSMIUM_INCLUDE_DIRS) if(OSMIUM_XML_LIBRARIES) list(REMOVE_DUPLICATES OSMIUM_XML_LIBRARIES) endif() if(OSMIUM_PBF_LIBRARIES) list(REMOVE_DUPLICATES OSMIUM_PBF_LIBRARIES) endif() if(OSMIUM_IO_LIBRARIES) list(REMOVE_DUPLICATES OSMIUM_IO_LIBRARIES) endif() if(OSMIUM_LIBRARIES) list(REMOVE_DUPLICATES OSMIUM_LIBRARIES) endif() #---------------------------------------------------------------------- # # Check that all required libraries are available # #---------------------------------------------------------------------- if(OSMIUM_EXTRA_FIND_VARS) list(REMOVE_DUPLICATES OSMIUM_EXTRA_FIND_VARS) endif() # Handle the QUIETLY and REQUIRED arguments and the optional version check # and set OSMIUM_FOUND to TRUE if all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Osmium REQUIRED_VARS OSMIUM_INCLUDE_DIR ${OSMIUM_EXTRA_FIND_VARS} VERSION_VAR _libosmium_version) unset(OSMIUM_EXTRA_FIND_VARS) #---------------------------------------------------------------------- # # A function for setting the -pthread option in compilers/linkers # #---------------------------------------------------------------------- function(set_pthread_on_target _target) if(NOT MSVC) set_target_properties(${_target} PROPERTIES COMPILE_FLAGS "-pthread") if(NOT APPLE) set_target_properties(${_target} PROPERTIES LINK_FLAGS "-pthread") endif() endif() endfunction() #---------------------------------------------------------------------- # # Add compiler flags # #---------------------------------------------------------------------- add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64) if(MSVC) add_definitions(-wd4996) # Disable warning C4068: "unknown pragma" because we want it to ignore # pragmas for other compilers. add_definitions(-wd4068) # Disable warning C4715: "not all control paths return a value" because # it generates too many false positives. add_definitions(-wd4715) # Disable warning C4351: new behavior: elements of array '...' will be # default initialized. The new behaviour is correct and we don't support # old compilers anyway. add_definitions(-wd4351) # Disable warning C4503: "decorated name length exceeded, name was truncated" # there are more than 150 of generated names in libosmium longer than 4096 symbols supported in MSVC add_definitions(-wd4503) add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS) endif() if(APPLE AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # following only available from cmake 2.8.12: # add_compile_options(-stdlib=libc++) # so using this instead: add_definitions(-stdlib=libc++) set(LDFLAGS ${LDFLAGS} -stdlib=libc++) endif() #---------------------------------------------------------------------- # This is a set of recommended warning options that can be added when compiling # libosmium code. if(MSVC) set(OSMIUM_WARNING_OPTIONS "/W3 /wd4514" CACHE STRING "Recommended warning options for libosmium") else() set(OSMIUM_WARNING_OPTIONS "-Wall -Wextra -pedantic -Wredundant-decls -Wdisabled-optimization -Wctor-dtor-privacy -Wnon-virtual-dtor -Woverloaded-virtual -Wsign-promo -Wold-style-cast" CACHE STRING "Recommended warning options for libosmium") endif() set(OSMIUM_DRACONIC_CLANG_OPTIONS "-Wdocumentation -Wunused-exception-parameter -Wmissing-declarations -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-unused-macros -Wno-exit-time-destructors -Wno-global-constructors -Wno-padded -Wno-switch-enum -Wno-missing-prototypes -Wno-weak-vtables -Wno-cast-align -Wno-float-equal") if(Osmium_DEBUG) message(STATUS "OSMIUM_XML_LIBRARIES=${OSMIUM_XML_LIBRARIES}") message(STATUS "OSMIUM_PBF_LIBRARIES=${OSMIUM_PBF_LIBRARIES}") message(STATUS "OSMIUM_IO_LIBRARIES=${OSMIUM_IO_LIBRARIES}") message(STATUS "OSMIUM_LIBRARIES=${OSMIUM_LIBRARIES}") message(STATUS "OSMIUM_INCLUDE_DIRS=${OSMIUM_INCLUDE_DIRS}") endif() osmium-tool-1.17.0/cmake/FindProtozero.cmake000066400000000000000000000037601474143067200207700ustar00rootroot00000000000000#---------------------------------------------------------------------- # # FindProtozero.cmake # # Find the protozero headers. # #---------------------------------------------------------------------- # # Usage: # # Copy this file somewhere into your project directory, where cmake can # find it. Usually this will be a directory called "cmake" which you can # add to the CMake module search path with the following line in your # CMakeLists.txt: # # list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") # # Then add the following in your CMakeLists.txt: # # find_package(Protozero [version] [REQUIRED]) # include_directories(SYSTEM ${PROTOZERO_INCLUDE_DIR}) # # The version number is optional. If it is not set, any version of # protozero will do. # # if(NOT PROTOZERO_FOUND) # message(WARNING "Protozero not found!\n") # endif() # #---------------------------------------------------------------------- # # Variables: # # PROTOZERO_FOUND - True if Protozero was found. # PROTOZERO_INCLUDE_DIR - Where to find include files. # #---------------------------------------------------------------------- # find include path find_path(PROTOZERO_INCLUDE_DIR protozero/version.hpp PATH_SUFFIXES include PATHS ${CMAKE_SOURCE_DIR}/../protozero ) # Check version number if(Protozero_FIND_VERSION) file(STRINGS "${PROTOZERO_INCLUDE_DIR}/protozero/version.hpp" _version_define REGEX "#define PROTOZERO_VERSION_STRING") if("${_version_define}" MATCHES "#define PROTOZERO_VERSION_STRING \"([0-9.]+)\"") set(_version "${CMAKE_MATCH_1}") else() set(_version "unknown") endif() endif() #set(PROTOZERO_INCLUDE_DIRS "${PROTOZERO_INCLUDE_DIR}") include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Protozero REQUIRED_VARS PROTOZERO_INCLUDE_DIR VERSION_VAR _version) #---------------------------------------------------------------------- osmium-tool-1.17.0/cmake/run_test_compare_output.cmake000066400000000000000000000042371474143067200231550ustar00rootroot00000000000000# # First, if variable 'tmpdir' ist set, this directory will be removed with # all its content and recreated. # # Then runs a test command given in the variable 'cmd' in directory 'dir'. # Checks that the return code is the same as variable 'return_code'. # Checks that there is nothing on stderr. # If the variable 'cmd2' is set, the command will be run and checked in the # same manner. # Compares output on stdout with reference file in variable 'reference'. # if(NOT cmd) message(FATAL_ERROR "Variable 'cmd' not defined") endif() if(NOT dir) message(FATAL_ERROR "Variable 'dir' not defined") endif() if(NOT reference) message(FATAL_ERROR "Variable 'reference' not defined") endif() if(NOT output) message(FATAL_ERROR "Variable 'output' not defined") endif() if(tmpdir) file(REMOVE_RECURSE ${tmpdir}) file(MAKE_DIRECTORY ${tmpdir}) endif() message("Executing: ${cmd}") separate_arguments(cmd) execute_process( COMMAND ${cmd} WORKING_DIRECTORY ${dir} RESULT_VARIABLE result OUTPUT_FILE ${output} ERROR_VARIABLE stderr ) if(NOT ("$ENV{osmium_cmake_stderr}" STREQUAL "ignore")) if(NOT (stderr STREQUAL "")) message(SEND_ERROR "Command tested wrote to stderr: ${stderr}") endif() endif() if(NOT result EQUAL ${return_code}) message(FATAL_ERROR "Error when calling '${cmd}': ${result} (should be ${return_code})") endif() if(cmd2) message("Executing: ${cmd2}") separate_arguments(cmd2) execute_process( COMMAND ${cmd2} WORKING_DIRECTORY ${dir} RESULT_VARIABLE result OUTPUT_FILE ${output} ERROR_VARIABLE stderr ) if(NOT (stderr STREQUAL "")) message(SEND_ERROR "Command tested wrote to stderr: ${stderr}") endif() if(result) message(FATAL_ERROR "Error when calling '${cmd}': ${result}") endif() endif() set(compare "${CMAKE_COMMAND};-E;compare_files;${reference};${output}") message("Executing: ${compare}") execute_process( COMMAND ${compare} RESULT_VARIABLE result ) if(result AND NOT result EQUAL 0) message(SEND_ERROR "Test output does not match '${reference}'. Output is in '${output}'. Result: ${result}.") endif() osmium-tool-1.17.0/cmake/run_test_compare_output_return.cmake000066400000000000000000000041601474143067200245470ustar00rootroot00000000000000# # First, if variable 'tmpdir' ist set, this directory will be removed with # all its content and recreated. # # Then runs a test command given in the variable 'cmd' in directory 'dir'. # Checks that the return code is 0. # Checks that there is nothing on stderr. # If the variable 'cmd2' is set, the command will be run and checked in the # same manner. # Compares output on stdout with reference file in variable 'reference'. # if(NOT cmd) message(FATAL_ERROR "Variable 'cmd' not defined") endif() if(NOT dir) message(FATAL_ERROR "Variable 'dir' not defined") endif() if(NOT reference) message(FATAL_ERROR "Variable 'reference' not defined") endif() if(NOT output) message(FATAL_ERROR "Variable 'output' not defined") endif() if(tmpdir) file(REMOVE_RECURSE ${tmpdir}) file(MAKE_DIRECTORY ${tmpdir}) endif() message("Executing: ${cmd}") separate_arguments(cmd) execute_process( COMMAND ${cmd} WORKING_DIRECTORY ${dir} RESULT_VARIABLE result OUTPUT_FILE ${output} ERROR_VARIABLE stderr ) if(NOT ("$ENV{osmium_cmake_stderr}" STREQUAL "ignore")) if(NOT (stderr STREQUAL "")) message(SEND_ERROR "Command tested wrote to stderr: ${stderr}") endif() endif() if(NOT result EQUAL ${return_code}) message(FATAL_ERROR "Error when calling '${cmd}': ${result} (should be ${return_code})") endif() if(cmd2) message("Executing: ${cmd2}") separate_arguments(cmd2) execute_process( COMMAND ${cmd2} WORKING_DIRECTORY ${dir} RESULT_VARIABLE result OUTPUT_FILE ${output} ERROR_VARIABLE stderr ) if(NOT (stderr STREQUAL "")) message(SEND_ERROR "Command tested wrote to stderr: ${stderr}") endif() if(result) message(FATAL_ERROR "Error when calling '${cmd}': ${result}") endif() endif() set(compare "${CMAKE_COMMAND} -E compare_files ${reference} ${output}") message("Executing: ${compare}") separate_arguments(compare) execute_process( COMMAND ${compare} RESULT_VARIABLE result ) if(result) message(SEND_ERROR "Test output does not match '${reference}'. Output is in '${output}'.") endif() osmium-tool-1.17.0/cmake/test_install.cmake000066400000000000000000000037331474143067200206710ustar00rootroot00000000000000 set(OSMIUM_INSTALL_FILES share/man/man1/osmium-add-locations-to-ways.1 share/man/man1/osmium-apply-changes.1 share/man/man1/osmium-cat.1 share/man/man1/osmium-changeset-filter.1 share/man/man1/osmium-check-refs.1 share/man/man1/osmium-create-locations-index.1 share/man/man1/osmium-derive-changes.1 share/man/man1/osmium-diff.1 share/man/man1/osmium-export.1 share/man/man1/osmium-extract.1 share/man/man1/osmium-fileinfo.1 share/man/man1/osmium-getid.1 share/man/man1/osmium-getparents.1 share/man/man1/osmium-merge-changes.1 share/man/man1/osmium-merge.1 share/man/man1/osmium-query-locations-index.1 share/man/man1/osmium-removeid.1 share/man/man1/osmium-renumber.1 share/man/man1/osmium-show.1 share/man/man1/osmium-sort.1 share/man/man1/osmium-tags-count.1 share/man/man1/osmium-tags-filter.1 share/man/man1/osmium-time-filter.1 share/man/man1/osmium.1 share/man/man5/osmium-file-formats.5 share/man/man5/osmium-index-types.5 share/man/man5/osmium-output-headers.5 bin/osmium ) execute_process(COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/test_install -P ${CMAKE_BINARY_DIR}/cmake_install.cmake) file(READ ${CMAKE_BINARY_DIR}/install_manifest.txt _manifest) string(REPLACE "\n" ";" _files "${_manifest}") string(REPLACE "${CMAKE_BINARY_DIR}/test_install/" "" _file_list "${_files}") list(SORT OSMIUM_INSTALL_FILES) list(SORT _file_list) if(NOT "${OSMIUM_INSTALL_FILES}" STREQUAL "${_file_list}") foreach(_file IN LISTS OSMIUM_INSTALL_FILES) list(FIND _file_list ${_file} _result) if(${_result} EQUAL -1) message(STATUS "Missing file in install: ${_file}") else() list(REMOVE_ITEM _file_list ${_file}) endif() endforeach() if(NOT "${_file_list}" STREQUAL "") message(STATUS "Installed files that should not be: ${_file_list}") endif() message(FATAL_ERROR "Install broken") endif() osmium-tool-1.17.0/export-example-config/000077500000000000000000000000001474143067200203115ustar00rootroot00000000000000osmium-tool-1.17.0/export-example-config/default-config.json000066400000000000000000000007101474143067200240710ustar00rootroot00000000000000 { "attributes": { "type": false, "id": false, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "format_options": { }, "linear_tags": true, "area_tags": true, "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/export-example-config/example-config.json000066400000000000000000000007771474143067200241150ustar00rootroot00000000000000{ "attributes": { "type": true, "id": "@id", "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": ["highway", "barrier", "natural=coastline"], "area_tags": ["aeroway", "amenity", "building", "landuse", "leisure", "man_made", "natural!=coastline"], "exclude_tags": ["created_by", "source", "source:*"], "include_tags": [] } osmium-tool-1.17.0/extract-example-config/000077500000000000000000000000001474143067200204425ustar00rootroot00000000000000osmium-tool-1.17.0/extract-example-config/README.md000066400000000000000000000012751474143067200217260ustar00rootroot00000000000000 # Example config for creating extracts These example files show the different ways the extent of extracts to be created with the `osmium extract` command can be specified. The config file `extracts.json` contains a list of all extracts that should be created. In this case several different parts of Germany. You can [download a Germany extract](https://download.geofabrik.de/europe/germany.html) and then try this out: osmium extract -v -c examples-extract.json germany-latest.osm.pbf All resulting files will be written to the `/tmp/` directory because of the `directory` setting in the config file. You can override this on the command line with the `-d DIR` or `--directory=DIR` option. osmium-tool-1.17.0/extract-example-config/berlin-feature-collection.geojson000066400000000000000000000076551474143067200271020ustar00rootroot00000000000000{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "Berlin" }, "geometry": { "type": "Polygon", "coordinates": [[ [13.73096, 52.39455], [13.71644, 52.39650], [13.69940, 52.38719], [13.70683, 52.37793], [13.69538, 52.36414], [13.67929, 52.36490], [13.65020, 52.33446], [13.63535, 52.33825], [13.62978, 52.34713], [13.63782, 52.36773], [13.62606, 52.37642], [13.60378, 52.36905], [13.58738, 52.38813], [13.56448, 52.38530], [13.53044, 52.38605], [13.52982, 52.39436], [13.51776, 52.39852], [13.47892, 52.39210], [13.46283, 52.41758], [13.42229, 52.40796], [13.43343, 52.38530], [13.42198, 52.37340], [13.38392, 52.37548], [13.38268, 52.38530], [13.36721, 52.38605], [13.36566, 52.39266], [13.33750, 52.40560], [13.31089, 52.39502], [13.29325, 52.40956], [13.27066, 52.40069], [13.24560, 52.40239], [13.23941, 52.41749], [13.17412, 52.40465], [13.17350, 52.39125], [13.15833, 52.38728], [13.12832, 52.38407], [13.08469, 52.40824], [13.08283, 52.42202], [13.11284, 52.44032], [13.09861, 52.45126], [13.11037, 52.48048], [13.15493, 52.50799], [13.13977, 52.51514], [13.11161, 52.51213], [13.11192, 52.53689], [13.12553, 52.55872], [13.13915, 52.55778], [13.14627, 52.57771], [13.12986, 52.57527], [13.12027, 52.58204], [13.12213, 52.59031], [13.14379, 52.59520], [13.15098, 52.60013], [13.16667, 52.60209], [13.20798, 52.59137], [13.19296, 52.60658], [13.21549, 52.63134], [13.25823, 52.63177], [13.25609, 52.64306], [13.27826, 52.64458], [13.27683, 52.66345], [13.30938, 52.66237], [13.31511, 52.65694], [13.30688, 52.65261], [13.31439, 52.64306], [13.31403, 52.63090], [13.33871, 52.62591], [13.36840, 52.62960], [13.38217, 52.64002], [13.39219, 52.64978], [13.39970, 52.64978], [13.41570, 52.64475], [13.42690, 52.63962], [13.43611, 52.65155], [13.46162, 52.65223], [13.46262, 52.65491], [13.44520, 52.66200], [13.45739, 52.67211], [13.46461, 52.67083], [13.47319, 52.67830], [13.49261, 52.67166], [13.48999, 52.65921], [13.52813, 52.64623], [13.52223, 52.62719], [13.51005, 52.62382], [13.50216, 52.60630], [13.51041, 52.59455], [13.52850, 52.59542], [13.55305, 52.59025], [13.58531, 52.57272], [13.59176, 52.55148], [13.64139, 52.54418], [13.63888, 52.53306], [13.66003, 52.53284], [13.66343, 52.52499], [13.64256, 52.51431], [13.63378, 52.49315], [13.61711, 52.47853], [13.62715, 52.47591], [13.64399, 52.48202], [13.66818, 52.47634], [13.69273, 52.46728], [13.70007, 52.47274], [13.72014, 52.46499], [13.73179, 52.45440], [13.76136, 52.44883], [13.76100, 52.43868], [13.75096, 52.43835], [13.73699, 52.41464], [13.74415, 52.40912], [13.73096, 52.39455] ]] } } ] } osmium-tool-1.17.0/extract-example-config/berlin.geojson000066400000000000000000000075441474143067200233150ustar00rootroot00000000000000{ "type": "Feature", "properties": { "name": "Berlin" }, "geometry": { "type": "Polygon", "coordinates": [[ [13.73096, 52.39455], [13.71644, 52.39650], [13.69940, 52.38719], [13.70683, 52.37793], [13.69538, 52.36414], [13.67929, 52.36490], [13.65020, 52.33446], [13.63535, 52.33825], [13.62978, 52.34713], [13.63782, 52.36773], [13.62606, 52.37642], [13.60378, 52.36905], [13.58738, 52.38813], [13.56448, 52.38530], [13.53044, 52.38605], [13.52982, 52.39436], [13.51776, 52.39852], [13.47892, 52.39210], [13.46283, 52.41758], [13.42229, 52.40796], [13.43343, 52.38530], [13.42198, 52.37340], [13.38392, 52.37548], [13.38268, 52.38530], [13.36721, 52.38605], [13.36566, 52.39266], [13.33750, 52.40560], [13.31089, 52.39502], [13.29325, 52.40956], [13.27066, 52.40069], [13.24560, 52.40239], [13.23941, 52.41749], [13.17412, 52.40465], [13.17350, 52.39125], [13.15833, 52.38728], [13.12832, 52.38407], [13.08469, 52.40824], [13.08283, 52.42202], [13.11284, 52.44032], [13.09861, 52.45126], [13.11037, 52.48048], [13.15493, 52.50799], [13.13977, 52.51514], [13.11161, 52.51213], [13.11192, 52.53689], [13.12553, 52.55872], [13.13915, 52.55778], [13.14627, 52.57771], [13.12986, 52.57527], [13.12027, 52.58204], [13.12213, 52.59031], [13.14379, 52.59520], [13.15098, 52.60013], [13.16667, 52.60209], [13.20798, 52.59137], [13.19296, 52.60658], [13.21549, 52.63134], [13.25823, 52.63177], [13.25609, 52.64306], [13.27826, 52.64458], [13.27683, 52.66345], [13.30938, 52.66237], [13.31511, 52.65694], [13.30688, 52.65261], [13.31439, 52.64306], [13.31403, 52.63090], [13.33871, 52.62591], [13.36840, 52.62960], [13.38217, 52.64002], [13.39219, 52.64978], [13.39970, 52.64978], [13.41570, 52.64475], [13.42690, 52.63962], [13.43611, 52.65155], [13.46162, 52.65223], [13.46262, 52.65491], [13.44520, 52.66200], [13.45739, 52.67211], [13.46461, 52.67083], [13.47319, 52.67830], [13.49261, 52.67166], [13.48999, 52.65921], [13.52813, 52.64623], [13.52223, 52.62719], [13.51005, 52.62382], [13.50216, 52.60630], [13.51041, 52.59455], [13.52850, 52.59542], [13.55305, 52.59025], [13.58531, 52.57272], [13.59176, 52.55148], [13.64139, 52.54418], [13.63888, 52.53306], [13.66003, 52.53284], [13.66343, 52.52499], [13.64256, 52.51431], [13.63378, 52.49315], [13.61711, 52.47853], [13.62715, 52.47591], [13.64399, 52.48202], [13.66818, 52.47634], [13.69273, 52.46728], [13.70007, 52.47274], [13.72014, 52.46499], [13.73179, 52.45440], [13.76136, 52.44883], [13.76100, 52.43868], [13.75096, 52.43835], [13.73699, 52.41464], [13.74415, 52.40912], [13.73096, 52.39455] ]] } } osmium-tool-1.17.0/extract-example-config/berlin.poly000066400000000000000000000066021474143067200226260ustar00rootroot00000000000000berlin 1 1.373096E+01 5.239455E+01 1.371644E+01 5.239650E+01 1.369940E+01 5.238719E+01 1.370683E+01 5.237793E+01 1.369538E+01 5.236414E+01 1.367929E+01 5.236490E+01 1.365020E+01 5.233446E+01 1.363535E+01 5.233825E+01 1.362978E+01 5.234713E+01 1.363782E+01 5.236773E+01 1.362606E+01 5.237642E+01 1.360378E+01 5.236905E+01 1.358738E+01 5.238813E+01 1.356448E+01 5.238530E+01 1.353044E+01 5.238605E+01 1.352982E+01 5.239436E+01 1.351776E+01 5.239852E+01 1.347892E+01 5.239210E+01 1.346283E+01 5.241758E+01 1.342229E+01 5.240796E+01 1.343343E+01 5.238530E+01 1.342198E+01 5.237340E+01 1.338392E+01 5.237548E+01 1.338268E+01 5.238530E+01 1.336721E+01 5.238605E+01 1.336566E+01 5.239266E+01 1.333750E+01 5.240560E+01 1.331089E+01 5.239502E+01 1.329325E+01 5.240956E+01 1.327066E+01 5.240069E+01 1.324560E+01 5.240239E+01 1.323941E+01 5.241749E+01 1.317412E+01 5.240465E+01 1.317350E+01 5.239125E+01 1.315833E+01 5.238728E+01 1.312832E+01 5.238407E+01 1.308469E+01 5.240824E+01 1.308283E+01 5.242202E+01 1.311284E+01 5.244032E+01 1.309861E+01 5.245126E+01 1.311037E+01 5.248048E+01 1.315493E+01 5.250799E+01 1.313977E+01 5.251514E+01 1.311161E+01 5.251213E+01 1.311192E+01 5.253689E+01 1.312553E+01 5.255872E+01 1.313915E+01 5.255778E+01 1.314627E+01 5.257771E+01 1.312986E+01 5.257527E+01 1.312027E+01 5.258204E+01 1.312213E+01 5.259031E+01 1.314379E+01 5.259520E+01 1.315098E+01 5.260013E+01 1.316667E+01 5.260209E+01 1.320798E+01 5.259137E+01 1.319296E+01 5.260658E+01 1.321549E+01 5.263134E+01 1.325823E+01 5.263177E+01 1.325609E+01 5.264306E+01 1.327826E+01 5.264458E+01 1.327683E+01 5.266345E+01 1.330938E+01 5.266237E+01 1.331511E+01 5.265694E+01 1.330688E+01 5.265261E+01 1.331439E+01 5.264306E+01 1.331403E+01 5.263090E+01 1.333871E+01 5.262591E+01 1.336840E+01 5.262960E+01 1.338217E+01 5.264002E+01 1.339219E+01 5.264978E+01 1.339970E+01 5.264978E+01 1.341570E+01 5.264475E+01 1.342690E+01 5.263962E+01 1.343611E+01 5.265155E+01 1.346162E+01 5.265223E+01 1.346262E+01 5.265491E+01 1.344520E+01 5.266200E+01 1.345739E+01 5.267211E+01 1.346461E+01 5.267083E+01 1.347319E+01 5.267830E+01 1.349261E+01 5.267166E+01 1.348999E+01 5.265921E+01 1.352813E+01 5.264623E+01 1.352223E+01 5.262719E+01 1.351005E+01 5.262382E+01 1.350216E+01 5.260630E+01 1.351041E+01 5.259455E+01 1.352850E+01 5.259542E+01 1.355305E+01 5.259025E+01 1.358531E+01 5.257272E+01 1.359176E+01 5.255148E+01 1.364139E+01 5.254418E+01 1.363888E+01 5.253306E+01 1.366003E+01 5.253284E+01 1.366343E+01 5.252499E+01 1.364256E+01 5.251431E+01 1.363378E+01 5.249315E+01 1.361711E+01 5.247853E+01 1.362715E+01 5.247591E+01 1.364399E+01 5.248202E+01 1.366818E+01 5.247634E+01 1.369273E+01 5.246728E+01 1.370007E+01 5.247274E+01 1.372014E+01 5.246499E+01 1.373179E+01 5.245440E+01 1.376136E+01 5.244883E+01 1.376100E+01 5.243868E+01 1.375096E+01 5.243835E+01 1.373699E+01 5.241464E+01 1.374415E+01 5.240912E+01 1.373096E+01 5.239455E+01 END END osmium-tool-1.17.0/extract-example-config/brandenburg.poly000066400000000000000000000202651474143067200236450ustar00rootroot00000000000000brandenburg 1 1.441545E+01 5.335626E+01 1.442177E+01 5.334259E+01 1.442438E+01 5.330853E+01 1.443556E+01 5.328224E+01 1.445028E+01 5.327896E+01 1.445852E+01 5.326018E+01 1.445867E+01 5.325950E+01 1.441916E+01 5.321890E+01 1.441332E+01 5.320919E+01 1.440992E+01 5.320568E+01 1.438822E+01 5.319557E+01 1.438151E+01 5.316430E+01 1.439742E+01 5.314588E+01 1.439749E+01 5.314562E+01 1.435989E+01 5.304827E+01 1.432616E+01 5.303146E+01 1.422813E+01 5.298549E+01 1.417930E+01 5.297135E+01 1.415209E+01 5.295518E+01 1.415917E+01 5.294373E+01 1.415730E+01 5.293272E+01 1.417021E+01 5.290097E+01 1.417420E+01 5.288214E+01 1.416930E+01 5.286883E+01 1.414617E+01 5.285209E+01 1.413270E+01 5.284332E+01 1.414575E+01 5.283296E+01 1.416212E+01 5.283086E+01 1.416317E+01 5.283033E+01 1.419051E+01 5.282722E+01 1.421769E+01 5.282373E+01 1.431225E+01 5.276656E+01 1.436309E+01 5.275281E+01 1.444839E+01 5.268275E+01 1.446853E+01 5.267235E+01 1.447787E+01 5.265942E+01 1.454210E+01 5.263904E+01 1.461005E+01 5.260747E+01 1.464806E+01 5.257506E+01 1.465434E+01 5.256837E+01 1.462299E+01 5.252690E+01 1.461805E+01 5.252054E+01 1.461815E+01 5.252049E+01 1.461727E+01 5.251933E+01 1.465200E+01 5.249693E+01 1.458605E+01 5.243059E+01 1.455463E+01 5.242273E+01 1.455299E+01 5.241025E+01 1.455144E+01 5.240951E+01 1.455257E+01 5.240699E+01 1.455099E+01 5.239495E+01 1.457981E+01 5.234623E+01 1.459682E+01 5.230829E+01 1.460039E+01 5.228483E+01 1.464619E+01 5.227555E+01 1.470427E+01 5.226275E+01 1.472857E+01 5.222906E+01 1.470984E+01 5.210710E+01 1.474099E+01 5.209762E+01 1.477307E+01 5.206171E+01 1.477481E+01 5.205944E+01 1.472869E+01 5.200424E+01 1.472844E+01 5.199795E+01 1.472809E+01 5.199750E+01 1.472681E+01 5.195713E+01 1.472507E+01 5.191376E+01 1.460713E+01 5.183235E+01 1.461182E+01 5.183035E+01 1.460812E+01 5.182766E+01 1.465952E+01 5.180085E+01 1.467236E+01 5.174483E+01 1.468006E+01 5.173953E+01 1.468176E+01 5.173411E+01 1.474087E+01 5.169769E+01 1.475505E+01 5.168793E+01 1.477871E+01 5.161530E+01 1.477770E+01 5.161427E+01 1.474431E+01 5.158065E+01 1.470138E+01 5.157814E+01 1.467680E+01 5.154666E+01 1.460047E+01 5.153708E+01 1.457992E+01 5.155990E+01 1.452708E+01 5.154210E+01 1.445223E+01 5.153069E+01 1.436783E+01 5.151288E+01 1.436013E+01 5.149552E+01 1.432343E+01 5.149552E+01 1.432196E+01 5.151060E+01 1.417189E+01 5.153297E+01 1.416491E+01 5.151311E+01 1.413446E+01 5.151356E+01 1.411960E+01 5.147313E+01 1.402236E+01 5.136810E+01 1.397466E+01 5.137199E+01 1.397392E+01 5.138940E+01 1.392108E+01 5.137153E+01 1.377577E+01 5.135252E+01 1.354919E+01 5.136237E+01 1.342957E+01 5.142808E+01 1.328609E+01 5.137520E+01 1.322353E+01 5.138768E+01 1.317436E+01 5.142773E+01 1.317820E+01 5.154040E+01 1.307596E+01 5.159534E+01 1.302394E+01 5.165302E+01 1.314162E+01 5.171829E+01 1.310569E+01 5.185316E+01 1.302518E+01 5.186272E+01 1.266842E+01 5.198572E+01 1.262506E+01 5.196741E+01 1.250800E+01 5.197198E+01 1.233086E+01 5.202918E+01 1.216859E+01 5.216730E+01 1.225778E+01 5.234398E+01 1.225034E+01 5.242790E+01 1.228131E+01 5.246263E+01 1.210789E+01 5.250488E+01 1.214133E+01 5.264039E+01 1.219088E+01 5.265354E+01 1.215124E+01 5.272562E+01 1.219584E+01 5.281032E+01 1.217850E+01 5.284325E+01 1.209426E+01 5.282753E+01 1.206453E+01 5.285971E+01 1.196667E+01 5.285522E+01 1.177590E+01 5.290008E+01 1.177900E+01 5.293145E+01 1.143711E+01 5.304107E+01 1.133677E+01 5.301350E+01 1.122404E+01 5.309466E+01 1.125006E+01 5.315041E+01 1.150772E+01 5.316304E+01 1.150524E+01 5.322909E+01 1.170096E+01 5.327282E+01 1.175547E+01 5.325503E+01 1.197348E+01 5.332612E+01 1.201065E+01 5.338859E+01 1.224972E+01 5.337972E+01 1.251110E+01 5.328578E+01 1.269939E+01 5.327319E+01 1.280220E+01 5.323205E+01 1.301279E+01 5.321500E+01 1.308835E+01 5.326170E+01 1.344759E+01 5.332168E+01 1.350952E+01 5.341850E+01 1.372259E+01 5.352541E+01 1.375851E+01 5.357840E+01 1.382788E+01 5.357546E+01 1.390964E+01 5.351731E+01 1.394680E+01 5.346056E+01 1.407191E+01 5.344876E+01 1.411899E+01 5.346498E+01 1.424782E+01 5.345392E+01 1.426144E+01 5.337640E+01 1.414624E+01 5.329059E+01 1.423791E+01 5.328689E+01 1.429860E+01 5.333056E+01 1.441545E+01 5.335626E+01 END !berlin 1.373096E+01 5.239455E+01 1.371644E+01 5.239650E+01 1.369940E+01 5.238719E+01 1.370683E+01 5.237793E+01 1.369538E+01 5.236414E+01 1.367929E+01 5.236490E+01 1.365020E+01 5.233446E+01 1.363535E+01 5.233825E+01 1.362978E+01 5.234713E+01 1.363782E+01 5.236773E+01 1.362606E+01 5.237642E+01 1.360378E+01 5.236905E+01 1.358738E+01 5.238813E+01 1.356448E+01 5.238530E+01 1.353044E+01 5.238605E+01 1.352982E+01 5.239436E+01 1.351776E+01 5.239852E+01 1.347892E+01 5.239210E+01 1.346283E+01 5.241758E+01 1.342229E+01 5.240796E+01 1.343343E+01 5.238530E+01 1.342198E+01 5.237340E+01 1.338392E+01 5.237548E+01 1.338268E+01 5.238530E+01 1.336721E+01 5.238605E+01 1.336566E+01 5.239266E+01 1.333750E+01 5.240560E+01 1.331089E+01 5.239502E+01 1.329325E+01 5.240956E+01 1.327066E+01 5.240069E+01 1.324560E+01 5.240239E+01 1.323941E+01 5.241749E+01 1.317412E+01 5.240465E+01 1.317350E+01 5.239125E+01 1.315833E+01 5.238728E+01 1.312832E+01 5.238407E+01 1.308469E+01 5.240824E+01 1.308283E+01 5.242202E+01 1.311284E+01 5.244032E+01 1.309861E+01 5.245126E+01 1.311037E+01 5.248048E+01 1.315493E+01 5.250799E+01 1.313977E+01 5.251514E+01 1.311161E+01 5.251213E+01 1.311192E+01 5.253689E+01 1.312553E+01 5.255872E+01 1.313915E+01 5.255778E+01 1.314627E+01 5.257771E+01 1.312986E+01 5.257527E+01 1.312027E+01 5.258204E+01 1.312213E+01 5.259031E+01 1.314379E+01 5.259520E+01 1.315098E+01 5.260013E+01 1.316667E+01 5.260209E+01 1.320798E+01 5.259137E+01 1.319296E+01 5.260658E+01 1.321549E+01 5.263134E+01 1.325823E+01 5.263177E+01 1.325609E+01 5.264306E+01 1.327826E+01 5.264458E+01 1.327683E+01 5.266345E+01 1.330938E+01 5.266237E+01 1.331511E+01 5.265694E+01 1.330688E+01 5.265261E+01 1.331439E+01 5.264306E+01 1.331403E+01 5.263090E+01 1.333871E+01 5.262591E+01 1.336840E+01 5.262960E+01 1.338217E+01 5.264002E+01 1.339219E+01 5.264978E+01 1.339970E+01 5.264978E+01 1.341570E+01 5.264475E+01 1.342690E+01 5.263962E+01 1.343611E+01 5.265155E+01 1.346162E+01 5.265223E+01 1.346262E+01 5.265491E+01 1.344520E+01 5.266200E+01 1.345739E+01 5.267211E+01 1.346461E+01 5.267083E+01 1.347319E+01 5.267830E+01 1.349261E+01 5.267166E+01 1.348999E+01 5.265921E+01 1.352813E+01 5.264623E+01 1.352223E+01 5.262719E+01 1.351005E+01 5.262382E+01 1.350216E+01 5.260630E+01 1.351041E+01 5.259455E+01 1.352850E+01 5.259542E+01 1.355305E+01 5.259025E+01 1.358531E+01 5.257272E+01 1.359176E+01 5.255148E+01 1.364139E+01 5.254418E+01 1.363888E+01 5.253306E+01 1.366003E+01 5.253284E+01 1.366343E+01 5.252499E+01 1.364256E+01 5.251431E+01 1.363378E+01 5.249315E+01 1.361711E+01 5.247853E+01 1.362715E+01 5.247591E+01 1.364399E+01 5.248202E+01 1.366818E+01 5.247634E+01 1.369273E+01 5.246728E+01 1.370007E+01 5.247274E+01 1.372014E+01 5.246499E+01 1.373179E+01 5.245440E+01 1.376136E+01 5.244883E+01 1.376100E+01 5.243868E+01 1.375096E+01 5.243835E+01 1.373699E+01 5.241464E+01 1.374415E+01 5.240912E+01 1.373096E+01 5.239455E+01 END END osmium-tool-1.17.0/extract-example-config/extracts.json000066400000000000000000000112111474143067200231660ustar00rootroot00000000000000{ "directory": "/tmp/foobar", "extracts": [ { "output": "dresden.osm.pbf", "output_format": "pbf", "description": "City of Dresden specified using a bounding box (object format)", "bbox": { "left": 13.57, "right": 13.97, "top": 51.18, "bottom": 50.97 } }, { "output": "munich.osm.pbf", "description": "City of Munich specified using a bounding box (array format)", "bbox": [11.35, 48.05, 11.73, 48.25] }, { "output": "berlin.osm.pbf", "description": "Berlin area specified using a GeoJSON file", "polygon": { "file_name": "berlin.geojson", "file_type": "geojson" } }, { "output": "brandenburg.osm.pbf", "description": "Brandenburg area without Berlin specified using a poly file with hole", "multipolygon": { "file_name": "brandenburg.poly" } }, { "output": "karlsruhe.osm.pbf", "description": "City of Karlsruhe specified using an OSM file", "polygon": { "file_name": "karlsruhe.osm.bz2", "file_type": "osm" } }, { "output": "hamburg.osm.pbf", "description": "City of Hamburg specified using an inline polygon description", "polygon": [[ [9.613465, 53.58071], [9.647599, 53.59655], [9.649288, 53.61059], [9.710458, 53.62282], [9.748647, 53.62482], [9.755407, 53.63184], [9.779739, 53.63144], [9.780077, 53.62041], [9.803734, 53.61340], [9.810156, 53.60498], [9.802720, 53.60237], [9.821984, 53.59114], [9.836178, 53.60137], [9.850034, 53.60578], [9.868622, 53.62402], [9.886112, 53.63481], [9.900712, 53.66354], [9.976046, 53.65593], [9.983638, 53.68637], [10.04788, 53.68845], [10.05897, 53.71541], [10.07883, 53.72889], [10.11328, 53.72232], [10.16292, 53.74650], [10.20263, 53.73511], [10.19037, 53.70193], [10.17343, 53.70193], [10.16117, 53.67980], [10.19621, 53.66665], [10.20964, 53.64485], [10.23417, 53.63793], [10.22483, 53.61957], [10.21431, 53.61957], [10.20322, 53.61091], [10.21023, 53.57902], [10.16467, 53.57625], [10.15825, 53.56827], [10.16876, 53.56030], [10.16818, 53.55197], [10.16000, 53.54573], [10.18803, 53.51830], [10.21373, 53.52733], [10.24643, 53.49364], [10.30542, 53.45715], [10.33637, 53.45298], [10.32381, 53.42863], [10.26775, 53.41297], [10.24672, 53.38581], [10.16789, 53.38929], [10.10073, 53.42167], [10.06452, 53.44776], [9.982178, 53.40496], [9.945679, 53.41784], [9.915895, 53.40879], [9.892536, 53.41645], [9.907135, 53.44046], [9.896624, 53.44672], [9.871512, 53.43524], [9.872680, 53.42584], [9.855160, 53.42306], [9.788586, 53.46723], [9.787418, 53.48704], [9.773986, 53.48739], [9.750627, 53.50893], [9.754714, 53.54850], [9.693980, 53.55267], [9.613465, 53.58071] ]] }, { "output": "cologne.osm.pbf", "description": "City of Cologne suburbs without city center specified using an inline multipolygon description", "multipolygon": [[[ [6.847, 50.987], [6.910, 51.007], [7.037, 50.953], [6.967, 50.880], [6.842, 50.925], [6.847, 50.987] ],[ [6.967, 50.954], [6.969, 50.920], [6.932, 50.928], [6.934, 50.950], [6.967, 50.954] ]]] } ] } osmium-tool-1.17.0/extract-example-config/hamburg.poly000066400000000000000000000040571474143067200230020ustar00rootroot00000000000000hamburg 1 9.613465E+00 5.358071E+01 9.647599E+00 5.359655E+01 9.649288E+00 5.361059E+01 9.710458E+00 5.362282E+01 9.748647E+00 5.362482E+01 9.755407E+00 5.363184E+01 9.779739E+00 5.363144E+01 9.780077E+00 5.362041E+01 9.803734E+00 5.361340E+01 9.810156E+00 5.360498E+01 9.802720E+00 5.360237E+01 9.821984E+00 5.359114E+01 9.836178E+00 5.360137E+01 9.850034E+00 5.360578E+01 9.868622E+00 5.362402E+01 9.886112E+00 5.363481E+01 9.900712E+00 5.366354E+01 9.976046E+00 5.365593E+01 9.983638E+00 5.368637E+01 1.004788E+01 5.368845E+01 1.005897E+01 5.371541E+01 1.007883E+01 5.372889E+01 1.011328E+01 5.372232E+01 1.016292E+01 5.374650E+01 1.020263E+01 5.373511E+01 1.019037E+01 5.370193E+01 1.017343E+01 5.370193E+01 1.016117E+01 5.367980E+01 1.019621E+01 5.366665E+01 1.020964E+01 5.364485E+01 1.023417E+01 5.363793E+01 1.022483E+01 5.361957E+01 1.021431E+01 5.361957E+01 1.020322E+01 5.361091E+01 1.021023E+01 5.357902E+01 1.016467E+01 5.357625E+01 1.015825E+01 5.356827E+01 1.016876E+01 5.356030E+01 1.016818E+01 5.355197E+01 1.016000E+01 5.354573E+01 1.018803E+01 5.351830E+01 1.021373E+01 5.352733E+01 1.024643E+01 5.349364E+01 1.030542E+01 5.345715E+01 1.033637E+01 5.345298E+01 1.032381E+01 5.342863E+01 1.026775E+01 5.341297E+01 1.024672E+01 5.338581E+01 1.016789E+01 5.338929E+01 1.010073E+01 5.342167E+01 1.006452E+01 5.344776E+01 9.982178E+00 5.340496E+01 9.945679E+00 5.341784E+01 9.915895E+00 5.340879E+01 9.892536E+00 5.341645E+01 9.907135E+00 5.344046E+01 9.896624E+00 5.344672E+01 9.871512E+00 5.343524E+01 9.872680E+00 5.342584E+01 9.855160E+00 5.342306E+01 9.788586E+00 5.346723E+01 9.787418E+00 5.348704E+01 9.773986E+00 5.348739E+01 9.750627E+00 5.350893E+01 9.754714E+00 5.354850E+01 9.693980E+00 5.355267E+01 9.613465E+00 5.358071E+01 END END osmium-tool-1.17.0/extract-example-config/karlsruhe.osm.bz2000066400000000000000000000404321474143067200236610ustar00rootroot00000000000000BZh61AY&SYm³Òz_Yé'ÓóÓG<Ë/<Úr2˜u{8²1<£UdݽzÄ£{¦¹Í‹]Âj ‚èvG¤jÉŽ5€Î †ÜáV‰ÙVcÛZc‰[XíRÞÑÔQò{ÓFdh2vîž<5Ћ¸°NÚ¼c:ŸnÃG=ÊN¯£Ós®^õ«sp!;\ÛÐN7tª–«Øê‰eÞfºN£Ç††­Z;˜=ZøÞZéJAT>FbÒvC„”[K'k Yr!+£Q+ÜBª§Ü§8xnººÜ½J±“ν&cy·S%-²]íµ]–™ Ï6èÐ{r»ak"W®üë¤Ëöþƒ~ƒ·TdŸ¾’Ä{ôIÁ¶”1½ëÏ,Å0èÄLwUxuEÚµe®s!²M…XŽn8Ø[¸é'vWœ5iiš©6…$&á·â¸cIÎõDé%(ø9ºêÁ3›S-BŒCbž¡B ¸cfäj*TÄç_sihÉ´3™Lµ·yG0æ½DίZ¥9o-­›.ß«v9`V§`x»U§/¥°+u5š+9çfrnLÄZº×WV✌©okMŒu©‡ y™v C}jõÁáLس®Ë=V®qEV»FAÛs°V¬º‹Lç×Ñnù뾚C™5ʾ!çPtyõ¼0¯eÑo ʵÃêƒÄ ÒHJ ÈnÌ©@A›í—ëFï#²´0œ»DfÌPrŒZ¢—-§ÚL¥—ÐãLr•5ÑJ:¦× Í1#IKS—=ò\‹Ržê‘bÌh’Wj‚zù*0êy¶ª7U”bÐO ,ÔÁÏvÌêî&Ù¨• ]R•t’4 …$vRIuYx¶lå\úÅg"TâšœGS-$Žik¼˜FŠÕGfÕšN’Pwuº8õݺzEåØ{„ë¼õ§u©J•mfÞíÃb;Ȫ¯Ø² Rî$Uv(½ ø%Q’©-Of%yER¢jÐÛ˜pãV5dº­T¨f^ÄÖxÑJåÞ<»‰i†ÞìÍPY}aÃí ‘/]Ú¼³ìË–4·l`·E[mhKMáÁ‚žcNŽ'—¯r²ÉÀ"Ý{±+UTÒBÑ!ö,ÒèF3Ÿ^%´.Öš«oq î*’åÍ'.{*f[5·y¤‰—¦/V±J²ô: +·/(UÍÃtŠUH‡#Ç.ËjÂN Ó˜]-Äfᔪflœî8˧ްåeÌn“iKšS;×D½ë¹¹u$á‚Öž¹2ÊÆ¯§:Qm)gòä(‚ õŸ…»sSOÃKãfÓW&Š'§Zc¥Ïm‘P§wìzv¬»ÙºÜ¶»½¾×>ùîr]ÙÃ,»Z¯è[·Ý÷=ÝWw«°ïpŠ—ímM=<î†<%å°tèª)âx…áAð׈(Ï‚iÀ3Ï\nò¯Lêƒ7{Nâ®]‘›SELÃ)] µ7UTÕ¯]•’ò§¦µ½œñÄ ·œé”©)Í ]TG íó7rwnõqç6¢¼ÂØxcêW«/dJ¦A…-ÊÍT ³X“´îÒ«º©[ƒzô¥nå×$¯³¼.ʳIð}Y@6R>ë®sX¾×ê­åEvÝ^Èù¦H®»p#wÁ¨˜·[ט;%æ>ƒ·ØãÚì³Ú–ÛÌÃõ•ÓOH]V=XŸ&d`îÍÝ#pB1ܼ•Õ‹ƒŒWiªÚ\‹êb¢;żîT¯ÜE5 L-]õsÆß¨åM¡N´§tòAUlî”…ÝÙvæC±S’®—BX©B êUÃYX’˜k–¼Îì–vTí˜ò›w—úž w‡5Gnªî 99Ö§ò0t2¬uŠgEe¦8ó»]ËÊ·r[xºÌkK*»*\0fîó1^£±´Ð†¢žO JF®ª˜8¾××1õwbÌ4­w@r²³9c'²¨V*œž-«ìÑ›”Œ|²ª0޼ÈsU7œØckÉØ/¦<®5Ø©^Z$(fÝX(o* ž9ΑŒÕÉÈ zl0Dºx¼íÍЫ¾žgEâÕD'=Y±á㘗[+²¾×à¶Â’ 2HHðo_Ηuî6|þ°ûññ@´ŠŸ“ŠÆ3±ëè<èß RŸ‡ƒu¬ = ÷›ÛóùÂx8ù½èÌúНQê|êÆqT‹Pk^^˺ êXRtêZbáËO.1nšWZ^£ Œ*dUq1K[-¤l´VêËrRËvÊ¥Flö²´®0®3©fÏ+Æän”˜)\õm´îkVMbÍïÄ™RßKx·-G]l‚öI+on­Öï]î¼æÊá;€]E €¦jVagÊ‚Âp­"³%Õfù ³/0È,å HeÒÃR´ë‚”މ˜-ù»ÉWry1˜­£­š/)^ÝÒ[Q¹[X*f 5Y½DÚÕ´³&¯$ 1˜eŒ7©YÂÙ-e,Ê­Ý5VŽ`ª“mÀ°¡ÈF™t]°q*Í)pÛ•xñ¬˜˜&$’™”Ö]ž<1¨L:†â,Tñ§XT¬²êaÔ¼ªM9œ9d'6Ü/DbÜ[Z•KÒ·kÚ4ÔNªÐÜšâ @’R¨¡„¦¢(N]¦Ô¨…\Éx ɨ¡ÖfS´Š}^À‚ h¥È§ )Û@{hð{Žpy9çù<«Ï1üËùÂy«Š¼•è8«&ý0ªë¥ Z¼º‚]ÁÛ—kC{3¬ê5vrtHõgZ˜ŽÒ t«dt4ë’6÷0íޑ˃®9‡•m)Bâ&Ç<йÐJíÛëΆáw¶6B›pí\A{W/à~jy§·ß³ñU—{¹êƒñQ*™"‡LË„§ññ{Öï‚-pÔª´®àÅáÌ}¤¿„ Ù¥SÂÈ" ^dÊC¨høw&ÚÚ-$iŸ%Ó'Ö˜gh?¼6Šôìie"‰%Dšë/£êD—· £8ØÓyG+>Sç”÷5Ñ"­' Õ§è°ƒ !âåLLACãLkM8÷QÔLðÍŸL%Zü¸Dûà‡}ìh¤{Ÿ6kšE}–û.;qT¥½wÑ ‡Ò*Š*õðê@‰Ä4“À¶Ø½%œpŠu¯¦\®'ܸŒ1ÔÒé¿|„.†Å‹R9KbÇFŒbh˜E®„ 5é Ò‹¢£Ýió-¶az>-­×²\ø=ÓAHV‡¬vóMÒY•,&)1qNzw+w»:Á(ÄÀsœ»¡ŽâÜÏ6ÁÆ„rqëQ„¨YÊvðÚdfÙvuPØô!läÛçk¶ZXRvÜ‹ ’G…|@›$†ºòiŒ…ºT¿ ›kr´ŒÄ+'Z0 Á¾ëΧÕKµÔE ˆ'™¨ZC>˜8Y %ÇS©èí³ï#ÇÖ½â”1I)ƽߌ›öYëg¨Ÿ¸“+tÊÇ×öV«`†‘D”«¤×ÂÓÒU^§ ’€g”DÂåîˆf·T¦2=Cµ÷%›‚>ȱ¹$ò‚¾ IÈRÀšäͨ=‰o·nšfF-/Eô/±uBù|2uPü6Ï>¡—ññôÒáÑvZÙµ2Çk—ÖIä0§Ò϶ë6ŸTª®oª$ë*„»‰Ú÷‡Å»0e:}H.²;ÃqÌZ)ˆZN3$˜á[PÛ¨s…ç ”…c ¢È\“ƒYõ6ûMHWLMa•…làƒ¨úkÆ“ò) ‡&ŽE‹Äš]zS¬hQ\ýGIï‡H^O—ÂŽ5‹ï®l_8“8Úûlæ3enô>w®EI‚”Íc¦ú6¢ Ž$GPH{Š/ç°Í㊼¯µý‰äñê”)ñ®2GQP{^VÒÙmí`ìk²`Æ--Ú­rS vŸÅÝã8S´qæ÷ÇQ"•ÚˆH(Å)-É,8G!üùÆU!J"hÏLÐ!y? ¡!r.·6jKÀ¼q(§–íN šÛ8`„† µGi¥Ù†—É‹ÕìƒEVøÚÒŸÊ_‹b,±W%õ#ä­–Z9cS ²lnáB³6lQ*­ÌΔÇzž«3|É]À³WHõ9ìÀX))“Dö{zŠª›Ý`w‘Ó‘=br ÷]N&AjÝÍQKnðiÅm÷/|4g¡=Ù[(2¸ÖñxJïÑú?•ÂPÚüIsï’°Yáúe ×^x{·OÆ„îžq•ñí6gIäŒ~>uó«Ü»÷qÕà›(ö/|EEày¼ßè"w`ÚåQLËš‰©ªqI¹©6uT¯’ñŸ@%H”ê~ážqPüÆv|¬üÃ?U†…vfÁY“*d";6æÒ ÎKáÞ6,e1aãI‰aýiÕ‚Üí˜kw3ráÇÕÁZ»éG —2Ý Ã»W,÷uí+OÊ´àˆÃÑÕÖÜNéÝÙTSjl*”ÔB[j!§»:Ã{vVõ3À¸ès뙬îÕâÓŠ¡Âꬌ®ìq‘cŽ-â’ÍÝÇÛ玪ì´ð]Z|xúGË(‘y:„Ø \{+“…ì¬Ê8/lI81ofoi=eÂì¢_e·ª»Ë»9K7;2;Rùð+yr†)שª¡Ð°f>ÌÊî½³ÂÐÞ‡UÚé@öÓĘ*VЗH"ûÝæ8Uvnc«Î¾7Ôwßùݬñäˆ:kDž䋳6Zvá›2‚bq$žQ¢ZüT1×a{<¼±a"0¨]Ž¢¦Ç”)íå¨ùb(w½,†`µƒÅÐwÔ^´f/!ªFù)ÊM¶Ës4yw<©›$S‘7œæ±±‹FËn‹®]T5BV»ã£Øz›Ù9Õ%}ê=Fi5 aŸ…b9z²Å@ *¹_#m3>h¹í*¾¶¹p©ÑöÒ=vš¹>˜E"ÚMu1ñ†hÁ¢ÆmÞ…3ä;ÖWRé«;¼jK» ån䔯¦uñå:æªâ²ÀU€èÉDÕh„u™šÕp״̧¤ÐùTRõµ=ÃÎg £Û(±¹–QÅi>g**¾ˆ“¦O΂áì…ߪÚM°­.#‹˜ÁAHºíÌ2Ûí^£b¬Ñmœ:\lÁÏH´Dó‘ÈÚWRM¤¡¹Ÿ!–{Ìë .dõ Ȥť³®µ{Çš9žÁqž†„g%ÃŒD|gËÔ±ð˜A÷*ÓÛ‹´û@^n©K~'MŒ+“{¿]Æ_d"¢÷+=µi8ß‚F‡›­xOz£o·!º²ììÌN¸&Ð@ŠY‘Þ¼B÷ª¬r)•%Ï"õö$ZõYBüD\—™ _y§ñ&¡"OBP‘»Í:’ª²¬ÌÎâéîö®ØK%V»nbV&íy+’†f›JÕ(Ûƒ\6Ù'* ‰³Ôçµ°’àj…UâÞSn蜆ˆåa»»aJZm{N—)ñǸõÑ/ZñC­b™j¿›ê{YS•ª›“†Üè©ïÜrJØ5oUåÈÑ*ÜÒ˜ƒªÌëVŒNÁí^m5‹!uœÕïP¡’M*]ÉU mš£ÑZ= ±Û ƒŽmDën*hãÚ«ÕUWHÖ»Í8àãçy3AÆ.±ìOIÃƘ¾^ç·«S<ß[²ÂØYQs©fëo0†ŽC)°våØoÚÛJL§/P[aÅ\!‰%W‘¶ŠU9ŒKÔ#A„ëgl^l´‹~JYv‘jµ9ì…ÖñÃÂÄ míÙ‚!Yi¤ 6!G0Gè"ñŸ,ÃìáG¡W!Ù/âÄãUXÇL¢Š-ÓÖýr¦„Q“Îv•DJ¹¬ã®®!@'¨´ŽÈ¤å¥S€½s®BŒy‡uHö®^nK/ÛÒÂy ßg‰÷§ŠÒ)å¨~˜mõL+<äá˜íîÌ‹9TÆë<‘î'sŒ˜˜I¨¤—”hQ;CWîyQšç/Ö ß^(pö¨ËÑ•ceNÝ®éq”¯˜–Ç("o†u”D‰\¸{P¦Òܾ8½€yž! Ý\M Chœ}UÄt ( Ulèѵ¦…‰ën·a ¼iÌqÌØÜê;Ð"l“]=‹ ±ºž´Q9(Bœ¼â‚ôpG(""a€ @r "\ÁnÊQø¡Œ¤JA± "‰t)•nŠ–‚  ’ Ö¤1¨ðZE¼¬%¢+”Bë¡ZŠ’*¸Àp @(!h.PBЮU¥ø\‰XV,Zˆ‘F%Ì8Æ" È‚ÄDZ"ÔDï¯iTã•L©’øªQÈ‚9 Pƒ!$ &V”rŠ€± ˜Á âRQñˆ«û·--²”g—,ãW„'{ìŲ́wˆÞbØk#2V_ž°mº5ˆ;C/yÀÃ{È–åææË¨ˆ¸U¯Ž–VÞ{ºixu}2"S’ô·=Bò¨Ó ˆÛ.Êă±fšJ¶½áL¹s¼b&6GŘõÉ´•ÐÅœYØêxø#È{9Ë›í€âö)£ES€h]‰BÁºG[[Ùè&}oíŠì-M7VšW‘jéÞTÙF­­F¾®i`Îd”†Œëx0QEˆ!ô²£¼á¥æ+ ÜÝ=ðçé%ØýÚMk•ñ¨s„Ýdñ ½ù$ظ„/””3Ø”-g³ŽˆøÓãßÞr*Q¢Fº‘íæ>¡r¬" ߆Ö8“ ‹ÚDw‘ª|Ù˰[R©9ž«¥™mÄŒ—â2ÙŸ+Vð™±ZA(xcœHÛ/=óŸ\}õÏxXiR–3¬Š÷Aüª "þpE †Žiæxu¨7;ʤ÷¼òȆ!ÁѳÄ!pÅŠ NÇ*ÔzŽ*³Þ‡Û¨½ YÙÊÁ!{¡D Æ41_ ÷2¬=$xÎÚ9‘ê¡9ÏÌ'1™öS}~ú½Ÿ;.?ƒI˜£ç®¶hªÐ=ò¯fG?%>gÉÍ~Qñ¤“ùM4ÐÊØøcÁ‘“l¹šEv€y}ŒÝÎÄÜYp ›ãA£zIÖk˜±õìòݽ‘K†XÞ,îuK¸‚Ë=w½–±®uZ¦‡Æ”V㬴&‡¶ÍÑLêÒiõ»Ì[m¢ G[·B•¾46&œÝ1Rf•˲ nÞvíÆÉSk qQ^GÞ½ÈÁv·¬(c¢êM‘ƒvD Å–ÍÇ—;³rg/r’1hÒZ,Ûe™aª¨]¾áÅC„çv5£†öÕs¦ÊÌL3ŽlŠ*Ú×HΈÖH$Fdiw’ó7žÕï[nÄ™kSî«¥žêkÄÆŽä0¶ÝbIE`Pç!²uRˆÈ)&á´Š*ÙùÏÒ§c-cñéõGᧇ×Buö½ ¿¤•Ã1räÎÏGðwí´D`éâûé¸ÓMføu=¸Ësô¬(À-Öþüª*ïï%k…ø8E¨øŸ’ìýúø~4?Â?Ãêw…Ù«Á”ÙbƒÆ~“YCæ…ž“îõתS«IÇô~7×ÇÛH>‘)4ñØgaÖ ª‹%auQoïgȬý†dsgåLÔÍ»º A¿0ÔVüGÅGãÌßÎ<‚߉&TÉ[¾™£)›ù1˜Â±»„8Ÿ *wõuü½ySw*òvìß»ÔdïX‘G„}LâË´¶°À„}úøêU>áA†32%Ƶô’!£±” G6T™^üN‚8\DPpƇ…—(‘øãtdmr~£C"‘÷#ä83œ£ñƒ# ÔH?ÝûL ͒Ɉ;—€¯ŽÀêÏÒÈÞ¹ƒT}ò™Ñ9é Gâ¯zž%õ«²^e,s‹+qb‘±Q÷CD ò*zRRœÎW·í(A7E”R9Ç×!h¥ ”AjöËs"D4R=î$›É ïOH2-~&AcHJÞëÑLÔÉg¶TÄ$$#ô‘ m'% J!ì¢AˆJƒŸ¿*ƒ ”‡òb@P†!xQ"¬üi¥áF_ïœö~=~DZƒêd~Ñ_›rP‘”Ã=4MäÈ™j |Ù”‚ÑÝED\_B1”—*’³J1¡yW5(²„ó! üxe”„† ŒGã»õÏÌ9[€h'ÈùûiÓÈ%D$£¡å²)Õ!ˆ 0¦HᆸeþsIü0£>?3ê4“Qß“>>e4˜ZÌ$C¦6ÃÅVþü;÷½ã 6$ÆÏC¢b+pYs. (dM²‰uüð^#„IŒ)G~øÍ?.#Dƒ(ÞEµßÇoñ•iÝp¯Ïzž÷–w¯&èÞž> .Э‘† ®õz÷&ªQãÃ8ˆ‘¥Ý‘gá±…þõP1ŽD4GÍÁB m·%˜„ƒðˆ0ó-Ü"°YŒ°b+Ò|oàÒ$Ü.€ý{eç¼&G øüt„#aÁ(¾g"&<ÏOhˆìørRv~Ë«ïzÈUž£!â³ Ïs˜GñtLÏíTEV(.]¯˜K7~¾“BÐH¾fšÈg†r!XÈò"Ñ¡¤¨gÂGÇXäRÆ›ŽD_ß< >FüT¾ñ$£QK8Æ,¹ŒAˆB"žÂìŒPts- áhƒ}ôá2õâ°œæZ<(‰í©Ç.fÉ0GàQˆ­—ªÓüýV[ò 9ÁËò(—[ïÒNߨ²fíçΤµÓ›E;ßHש;¬0í/ðC?být ?3ÎK³îEÕ™†Îï´U¢?5|,)݆èÊãL¢Ù„ž®÷ =Æœd# ´V£FH¥“ëoïXr ”d"óæÆßÔ|†…dV1yŠYÈt*WpEš„‰„E>3$,Ær"y†âôú 2#±I âÕÏÞíò¼SGmÝefö£©WUj¥ºg° ¦-  :\±ƒMgÚâ5r ;×B9“b1ÒyHÛ!öI€Œœ( ä|H_¥HÑEÛ¾m3ã²ÎùÄü¼J“xae˜ä>G¤UtVb~Û ñ¬eÑDýe‰‘§HD #Ìg‘ó‰Ò1’sûPÉ>>¿ Ö¾û·(¹‡1Õ:ÚÑØ¬ªËŠªâjnõ.Ä32­¼Ä/N½}†ËW][•4v«œ]ìËž]ÜçmTo¢eTîÞ¦"2øv 9’ùnÖ°ÅšQf RJèwSy_rÛ‘Ôó5¬P¶»VEÕžMW&ot91Ì.Õš†MíÝyUì]Ø)¦Õní\⽬5㜙ÎÚÞÄ4<îwE)ð»íÜ»<;6‰i\š©ªò·|Mж,¨2ÂHvecq·†³#W&míÍ—ud8¤xTÒˆ³÷ªìòG«c• h”Ö_Æ}iXÌ¿™­{Š"3æ#œ´Ú]@yˆ/ÆÉ¿Œ¨ø\ŒÆq;'‘äR*™Äóê§Š&Çåï¯ |c¡E ë’f”†NÍ æI,³ID²gd~ú@urZ Fš†!Sg̸EÕ’R†e•PÊÊ£‹?0(œ‚öI"„¢Í¦yo:œu6Æ+NŸ½(ë-gÚ7fK3ï}&“YCfÌJ'Ì×Q".nuyÞ˜† ò9|4ï1’,QÃµÙÆUÃXqE@±…K)/SqGÚ G˜Ê„DÄOfYöžÂ¶lñ`ÆÈ-x/æP¢(—ñób».„{5Ø®¦¯¼LúM&ŒÎü'HOo¬“¹”˜$A7oMÛð Õ¼DC‘ 6¦³/%™SdÑWCéÏfA²³ç×TFÝΉ­3ѧµO+ä‹E] .lwÀqg£¬ä!r–æôJJÜ–.*vâÜŸ‹8ŸZ“©pèäu³(Ÿ®ŸÖáòñÀë°´3Æ)âÝDtîÕ·dÌÄéöü× ×¹Ú2x˜jîÜ"È91'éR”¹¡Œ¯˜çSk±ª²Ç—sälœ{)º7¨'7²‰YñÅÑñö“÷Š(üK:±LìŸ\ÇÙúJsÅ~'g ›kÜäWg$~٩ί¢‡ÔùÏÁc¶‡AB”˜bÉŽ³„Z°¢zîs¹»+’sqhîž4D"hGÞ1(`Ð!°U ëf®ëœ…¬5Y÷c•Éõ|\3Ãm¸oÉH}ƒ)4¡N)Å»Œh^ÎNÊ•¸?§Å`(ø[·&¿º„·šE”&Åî¢}á_‹Ešh¢Ó„|©‰z¾^™Ti±Q ¯+¶yžŠóìC+Dx#hNœ]FÇŽ‚è0Æ`À=ÜÔÙèÁ6Ì8üþf%”jýã ™g×uAeÕwÒ»å c£HëOJAƒ¡ ëZKÜ+ƒíq™ìžT\7ê’O¾¥‹N¬? ™fÇÊÞD¤g ¶ÚsBñ7d’èOMÙ_*÷F?vä7V:¡ŠÄ‘'ZÙʨÁ%ÐÂõyû; :>ÄÎt³,˜1Aš¯Œ³Ñ\,®+cèÈíìbrÒh(X©°;-Φw‡·R1Ž3¾. òhõåñ¾nðæuTO 9eIÒhI€N3¬‹Ë~ΊVVOèZïAW[~z¤î÷¹‹rájU6e¸¬¤»Våº%| uåd¶¶Üý°äÆ™!d$Ež/ŽÝÐ #"qäsÆ3®b$,²Ú?1ó'4ŽæušÌJ»Fâ ø2fÝÙ†z Fã:Ûsã¼&ñ ’üxe~Âã~‘Ȇ‘§ß“+ì¯ßtÎbØM°ìîËP»³›“Ü!îÊMr¡UФ£ÎðsœW’“ô~"W…b„Ìø“?"˜»ñ%ˆ¦™^¢Mª/‘îÓåõ¹.äjµ~ݦi«‡)$ék{{Eh‰DÑ?Ç/ÞܰXY·ð™F†²Mi‰ùG`«søþ+nýÛƒÁKù„-Êêåѵ@h;ÖP‡RnÈ)sº°Þ½Ì¡»‘ä烿½q¿±¡*õ ï”éì–$FĨaeQù>{t•èÌ0a÷ŒíIÍ—Ž ØÕ¡Ó¸:=‰3)Kc™NpŠ(—zHo™„ÑkÞLYaˆu¨¼'F?o™Û¶Ø¼)^®)Ì¿|‡8ψ$>«=XË ÆW»s ¶tjèSÖ2Ãnu¦2#fëXûf^1v]~S$$çWijŸJ]¦°žáÓj^e‚AÌ+ŠŽ÷Û¹*» ¤ÊEJ™«½Y|)]9@8ë–m!Ê/rŸ`ºR++o•ÒŠv0Ušuê0ª=&j0¹£— `["]‰ím$ Çkp8´:Bb‘å0ÖWÈZ‡VoBCaì ˆ · ÞÖ“MKqJÊ‘éãůžÇ14¦j0vµv‡z„ &Î2xÆ€cYDültOsQ¢!àÄ;ìwPûXâ&3Ç3<£¼HöÌCçÓ=–=¶Qˆ_²œŽ‚1©$߈2K3ÊC]eP—c`¡hPOÁƒŽù½g‡9Ç ã`Ùí{\œ]†Œì€x¤7ÈæU'1&³™Á>ÃJ‰Tažö“v\{Eš™rHga%i‹z0âKד{86“­C„‰¨“ÆQë4y ›n‚Pð“jÖJ’g1½ÕïUf@ÎVW,ÛéDž˜²Íf¾K¯#Qǯ²ÏE0CÆO³ ƒ“˵À\wa² ™¶åàÚK6ãÁVUÈÀDìGàáÉ_’A ï¤Ü‘7¥£ElYG…—l `Úˆ±öîqrйWGÕä:jÓU*Yfž¤)Ôæ’th…’±@†Œ‡èÍ|O¼ÕÌ_¸Ã ŒâÁã Ä#Õ’{ÝÏ*Ë/|É0äqÎph¥XfL¹ºÝÇ)»DäÕ4O £ÓtPQé÷ðž–{¶O¾Ñªç…¦Ü”÷YgÄdûнÛͯ̕žÒ½+'.Ò[°ÎÐÚ¸¤ˆ©¶ &í¶*úè%ÚN°åŠÖôòÛG÷1õ¹3GÕ; cFÚ¹tq91B%]­ÆLP˳O-ue3gÖ>j«WbU¼&l¹¶+3j> Fój2{€î;7KÎ.ñËØïÕMA×^•‡®uU>²ùˆ8æµø‡¼ØégÆ]”2º\1qÚz2Û‰8 Û¢ö¦ÓMЙÙÓ+No,´Væä—Sé:ïCÜ…§pæ¶–Z_úçouÏ¥º”„mí ŸXÁ×Cl fÞ‹@ñ»Ã źæU`îSoÕd‡@# +nÒ¶æÊ;®UjAˆsàùaŽV¢Íf!¾–1ŒC½—g‡Ò7»ŠÚA:ì8z ®8·UÊ—>öWYR´Þ:¹”i¢bÕ<åTŠ$Ü­/"Žñ|©8ÙÍy”R$œ“nË Úpç’è^±žÃ{ªJ‡æ´õt.ìÂÊ£uݦ ­Š½m"_Hµ‘&ÝíÙ6ô¹^PPû™´ìb++¤öK:ˆëÃæ{8Âa—®:ݦ,YU8éöög8gq·«^ºaÔEb´ë=¶ý ‘‚”,$XH0W–ðÜÃ) NÄp4À®ÛÐ03c{¼è`l~Xõ{}Î_S8w3̨³ÃÊñÌÇDÉ܎˰.’‘Àn[mζ²à·V§gw5F—N š{°5F¦6èWU03ZVÌΖ{ÝI$´‘Ñ!2½}½Ûg£|Sò3f”mÛÇYr𯉓“úeN Mu{oH/˜:ä:Û'fUJ& Vö§³|:–uáYìê¾µ®‹òØíu÷$âr;-,¬ƒVÐ63=$–ÇémvP¦gdb‰ÁˆQïdùB›ªàñÅψ˜µœŸ™Ü7–[ç4¥IQªÊ«O­?g0XHôs5œ6Þ Ò¢£.aŽ+9‰­HàÓ ‘{ä¬öD­±wȨe*¨´“´: Þ:4‚` ëÛ›¬ûJÚ‚Å£.)•÷¦\¢¨»IŽY­)¢ærX ëK ¢‰<€Ë¯RŸ:&ÓœŸ ¼XÉÙR¥pÅYdL#”Z|æ,æcWËrк°Î Vv<£–08¥bæX™4™9&ñ©žcJóF-Ø;ªÙTOe(éõH¨U¸º738^Á%[tdÜÆvãy bÁö›ö9YDª#';;”3#L‹E·–V:›°DÅ(Ó°`D¦•;éÝW×aá$àŽ…Úáð‡º1»]z³,f5wÔ[>Ҝ±]IEª”‘|w_…Be{Öe'TÍÝ–±\Ö‡cP¼¦…¼¹MT_±“s­ªöø·ã¤ôÊJ$¬<¨¡0›MIêmçS:¶^Ê´˜¥úò½ÓkqxÁÆpä3zúÑ8„j »y°‹ŒPX{Øë{ˆ¾3¸Ð›‘–@„xË5Ï9âðWg nˆJ)Š51Q6Ë›¼§6K>/½L4ª-MRTŠê2fÛj–¡`“»…[Ñrô] PÄÅòë t²2æ0q”VS‘Ç@’êÇ9)Š6Gáч…ÛÝS3^¶wGè ÷´SÔœ/«»ÎuP^›Ÿ<Á'–ݲßKø’Á2ž»ê­ñs(x2kJIQŽI…®û®e”%‡’§6f}ìŠ5¹ò¢Jcݳ4µ§©Áf©ð„Uv{ØÇ—D.f˜±šC;ᢅ²0ué¸E+ì<ÌÅÛB˜²¨§t3ëMö•+È]ÓW¢ºt{Ø ‹¸Uc ¸®âaæï†ìÈ¥gPM±²–߯5©SQ¢à(Ô&CÓ´ÍR‚A…Œ%n‘Œ HéCƒ ©û-ö%X¬Ž\Ò25ãUSº~”0êÈTJŽÎ\édcÅm3žÊ1Fõ¥Vj÷=àƒ½R)ìsØ>/IB¹ØFŽÄEtFP(VD+ñpÙŠŒŽô¤¥ B8NÄå4mm¹£­fÓ—.©äòH÷…` ÕŽ1û1–ŸFÙ2¨cfW#Ã9·=è~6[Îà©¾í ¸ ÔõäfPéÜw¤­ë‰ ’oÊýÄ’aáb36½â»Ž(»s¦âºK{DÃ¥ÊÛ¥gr§‹[ ´`†™5¸±ÈÖHaVapaʉ‡Ép†Ü¤T]è¨Â“¦gƒjŠšb5^SNqA4æ½Ruo{¼–÷žÄܼ“ÄÇ[0@€÷_>l"†yk«¶á–5çmgyÇGw×N0ãAçr×G %%‚*À´†Ì0¤-Á/F A•2°¹mò&…ÑpY½§JÜÚÅ7Œ¬–ŸA[Öó&¦ƒÜ¸3”-½±¯&$¿kº %hŸ7’‹^Ûw¢éEa(x{qÙ}ˆ)³8åîeVa•„ÃXNHiUO).Öô¶g¼DÁÃZØì$hÉ`%ØÖtó}-qhnKTÎ[ÙW]Cpo-¼¦î- ӋÖf9­#H)HT^¾b«´¥§«T¥r mÍ—K^™»TØT¡ei‹ƒQ¡wy]ÍÕ¼«;18”ÓY¦¬óӖݳL°TšÙQA^Ü>@C*5©.]È"Ô–øQ ra›iëlg+Ï`™ ©Áp:;_eUª”uÕêN¹U’àa9‡FñæâÙ ¼ŠƒÌt$Q½xR¼3s‘9"Ò ÉM>äãŠÊ?È8PD@oÒ“ü¸ýûìÞíœîU¯°’{ñÜ8ðz°"]êÓpm3ÊyP}pç¥.Ù2£„åWö*dÕGFŒ¾ÐÅ ©aQhäTmEMºç|ðÓÔHGš½7¸ÕE²Cƒˆ)Sª³P!„* ”á9F§¶P¬"' íG°dîJ¦wM=”bÍÓ•8æ1…:ÁX› ¹cg´/a¡F†6õh°¹‚l:5G<©E,†\ÚJ$²v;`ø PÞÌú•;/.B šÑDhèјȨK+a©Úí8؇yhµN æ%SˆÛ2“­‹„|LòD­3ÆݱN¹9ž=’vB¬ãi;â’ëÞì4õò$†t ß:-Œ),¦00Uè½0³;®ò×!Ý $¼ô}°šLF’vÌY®cS6ÍZ•‰Bòa+GppïNi*¶ÛƒÁ ™ÞÁfÕŽ¢'’ ⡼0±6¨œ[y¡yáŒÃlSÓÄ¢´D×±>’ãîñÝ«n­6åL±@ÖmRlX§T%Ød_lÅ ¶û;Öô=)sÌ•`ù{ÉS=ÄǬÃY“<Ï<(ÐÓÜ»åØpƒm—¦¸vPÊèê†vF0•íîÛLG¤Dü) ¯sÆ}i¨LE;÷9Ì3Ø¥ŒPç $q™@wÅ€ ««™w‡j‚}÷›’á×I^fÛÑMÑÎÍcá¶Í£°¡‹:Ò~*Ö.ç,ÁÔ|!l¾¶Ûî,Á% ­ /w!%õJχƒ&>*ˆò û>É Ìß?P³²]þðŠ =#óã!‘b÷´“hf)9TÅØÍDj@‰#˜! ´4uôöÂqMF$g¡WM ½ßdãu:%9bvŽ×i ûÜC> Ç«A ãí¤ýì”qÌ>PZ¤—Ô’â{(G8kÙçg‰6Mñ3‘O¼”˜(“hê%H˜…¢sæm»TzßÈ¢×Ü´™ž$´eL lé\0“ç‰Õ ¾Ò⑆r¯¼w?ܨb4ÛÌ}éK²µ^ù§‰­Ú•‡1[ùW.õ_;dGÚAçv?…P|ºÙ÷ɈøGÊela†à}ÄòŸG&Ž*"…/½­›;cç­>ÅÅÃ%Z=Ä!(&´Œ³31ªŸiDEï/ŠÈžVkO±8Sè’/ wŽE2{‰a—ñ?…Ç•DÝ–Þ(¡g*2nK÷–ý‘íÆÍ"[ìÈ(—İR‰S(”DÞuqhïL Dôæê`–#’g–ϽZQ\þcùÜL±YC²aˆ[Ìœ.ÃjðP²AûfØ4†>|Qõ¶À=Ag v·GÕuó\¶ÎwÝi µvo‰8‰É8¤ƒ·L}â- Pøöu q–ØÚµ¸Ÿ®ÄÐÙ4¥'½w˜Ã>Í}ßmýÏ/÷QlÈô0™›2^åfù½„ ú¥Å·ŒB¯>4PRÉQa_ 2z»æuà¸õ<àï˜ü2€ëL˜#¹I°T( ”*R¥Tåñ«ouX BZÖ€@€B€@ @ @€  B!@ˆ‚€ªµˆ ­Jª’KŠª•$‹— J©Ä!Lä•*¤‘k•*d‚¤T’1")•YìDRˆ E#T ú\ ‡$@I @‘P‘’FE‘$‘dPd$QP$I$dA‘Id€*¡J•%ª¢*‰|T¤ DW¬ˆ…Ý?séôûÙwÞÿ¿\ÑN¾v·Yï÷çÝÅõ¯2…QJ<·9Òçà"ƒ©ã")Ýï[¢zü¼¿GڽɚTRlŠòDRšDX\ŠtQMU­â†ÏT²"€B¨¥õªž@1¶Žàf*Z ½JS6ãS„ð88ô` Zëè ("”n¢©C!E® BÆÊ`¢•›8TÕ'ÔЪ\uaÔˆÆ PRNú)Ž$"!! ¹eHŠT×H*¢\QØàŠkÛce⧦]àE=JæŠ`Š]ˆ©ÅÈŠpí-üMȧ¤ŠmE7UT,MT¨‚:u"™õMxó‘N4Rp×S™1›‘IÒé¦Ý…´  Æÿ Šœˆ¦ƒ* œó}‡&7¢›EMZ ±7îÞ¶³|Ar"¤¶bn‚†:4T¿mNDS‡£ @0Ó1›…Nz)¬¦¡SE†íëQÍËes¦H¦b¦H,:â¦å»…ÀÐã¶€*DS‰§ \ÀôSJ©y½uJ7(ýbåË¥ÉVäE݇)ˆ©Òš‚ ŠØE:ú"”E5ðkÉTÜŠQáE1E:j¦÷)²è^r¢”-©Ëèg[eDRøXTœh¥½K"™òŠ€†ÍDSnßEÒŠnÐ(`d*PÔÜŠXßT,ªCw>ÿ¥ÀŠPµÏ)ŽlÞu¢”/3Åðâ*tKí]ºsE1P Ý{h‚8ÜŠq"Aã3E)­Ë%½碘šøEJé9ȤÚÄC#^<( jE.ч;1p/E9jolE5"›•޶ÑÞÒ*m%QMµU)¹Ïý€¢âæy€käýq|õ~{§ÅÍûdË66æòKˆB~_=>:Xóåú>ŒK¿¾½iÞ<>{%¸1¥@Èÿ•ôzž>æÇÍçÀ ²xÀèˆP,óx˜ùþ™žCüá–‡˜ñ˜l<Ÿ4¡^oJž]x«ç¯ù^¹ôsÍü?‡ñßEÿ!w$S… ÓÆâ osmium-tool-1.17.0/fix-formatting.sh000077500000000000000000000002241474143067200173670ustar00rootroot00000000000000#!/bin/sh # # fix-formatting # exec astyle --style=java --indent-namespaces --indent-switches --pad-header --lineend=linux --suffix=none src/*pp osmium-tool-1.17.0/iwyu.imp000066400000000000000000000024541474143067200156050ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # Configuration for Include-What-You-Use tool # # https://include-what-you-use.org/ # #----------------------------------------------------------------------------- [ { "include": ["", "private", "", "public"] }, { "include": ["", "private", "", "public"] }, { "include": ["", "private", "", "public"] }, { "include": ["", "private", "", "public"] }, { "include": ["", "private", "", "public"] }, { "include": ["", "private", "", "public"] }, { "include": ["", "private", "", "public"] }, { "include": ["", "public", "", "private"] }, { "include": ["", "private", "", "public"] } ] osmium-tool-1.17.0/man/000077500000000000000000000000001474143067200146475ustar00rootroot00000000000000osmium-tool-1.17.0/man/CMakeLists.txt000066400000000000000000000063601474143067200174140ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # Create man pages # #----------------------------------------------------------------------------- message(STATUS "Looking for pandoc") find_program(PANDOC pandoc) function(add_man_page _section _name) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man${_section}) set(_output_file ${CMAKE_CURRENT_BINARY_DIR}/man${_section}/${_name}.${_section}) install(FILES ${_output_file} DESTINATION share/man/man${_section}) set(_source_file ${CMAKE_CURRENT_SOURCE_DIR}/${_name}.md) set(_dest_file ${CMAKE_CURRENT_BINARY_DIR}/source/${_name}.md) file(READ ${CMAKE_CURRENT_SOURCE_DIR}/common-options.md MAN_COMMON_OPTIONS) file(READ ${CMAKE_CURRENT_SOURCE_DIR}/progress-options.md MAN_PROGRESS_OPTIONS) file(READ ${CMAKE_CURRENT_SOURCE_DIR}/input-options.md MAN_INPUT_OPTIONS) file(READ ${CMAKE_CURRENT_SOURCE_DIR}/output-options.md MAN_OUTPUT_OPTIONS) file(READ ${CMAKE_SOURCE_DIR}/export-example-config/default-config.json EXPORT_DEFAULT_CONFIG) configure_file(${_source_file} ${_dest_file} @ONLY) string(TOUPPER ${_name} _name_upcase) add_custom_command(OUTPUT ${_output_file} COMMAND ${PANDOC} ${PANDOC_MAN_OPTIONS} --variable "title=${_name_upcase}" --variable "section=${_section}" -o ${_output_file} ${_dest_file} DEPENDS ${_source_file} manpage.template common-options.md input-options.md output-options.md WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Building manpage ${_name}.${_section}" VERBATIM) set(ALL_MAN_PAGES "${ALL_MAN_PAGES};${_output_file}" PARENT_SCOPE) endfunction() if(PANDOC) message(STATUS "Looking for pandoc - found") message(STATUS " Manual pages will be built") set(PANDOC_MAN_OPTIONS -s -t man --template ${CMAKE_CURRENT_SOURCE_DIR}/manpage.template --variable "description=osmium/${PROJECT_VERSION}" --variable "version=${PROJECT_VERSION}" --variable "author=${AUTHOR}" ) add_man_page(1 osmium) add_man_page(1 osmium-add-locations-to-ways) add_man_page(1 osmium-apply-changes) add_man_page(1 osmium-cat) add_man_page(1 osmium-changeset-filter) add_man_page(1 osmium-check-refs) add_man_page(1 osmium-create-locations-index) add_man_page(1 osmium-derive-changes) add_man_page(1 osmium-diff) add_man_page(1 osmium-export) add_man_page(1 osmium-extract) add_man_page(1 osmium-fileinfo) add_man_page(1 osmium-getid) add_man_page(1 osmium-getparents) add_man_page(1 osmium-merge) add_man_page(1 osmium-merge-changes) add_man_page(1 osmium-query-locations-index) add_man_page(1 osmium-removeid) add_man_page(1 osmium-renumber) add_man_page(1 osmium-show) add_man_page(1 osmium-sort) add_man_page(1 osmium-tags-count) add_man_page(1 osmium-tags-filter) add_man_page(1 osmium-time-filter) add_man_page(5 osmium-file-formats) add_man_page(5 osmium-index-types) add_man_page(5 osmium-output-headers) add_custom_target(man ALL DEPENDS ${ALL_MAN_PAGES}) else() message(STATUS "Looking for pandoc - not found") message(STATUS " Manual pages will not be built") endif() osmium-tool-1.17.0/man/common-options.md000066400000000000000000000002441474143067200201520ustar00rootroot00000000000000 # COMMON OPTIONS -h, \--help : Show usage help. -v, \--verbose : Set verbose mode. The program will output information about what it is doing to STDERR. osmium-tool-1.17.0/man/input-options.md000066400000000000000000000005441474143067200200240ustar00rootroot00000000000000 # INPUT OPTIONS -F, \--input-format=FORMAT : The format of the input file(s). Can be used to set the input format if it can't be autodetected from the file name(s). This will set the format for all input files, there is no way to set the format for some input files only. See **osmium-file-formats**(5) or the libosmium manual for details. osmium-tool-1.17.0/man/manpage.template000066400000000000000000000012751474143067200200210ustar00rootroot00000000000000$if(has-tables)$ .\"t $endif$ .TH "$title$" "$section$" "$version$" "$footer$" "$header$" $for(header-includes)$ $header-includes$ $endfor$ $for(include-before)$ $include-before$ $endfor$ $body$ $for(include-after)$ $include-after$ $endfor$ $if(author)$ .SH COPYRIGHT .PP Copyright (C) 2013\-2025 Jochen Topf . License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. .SH CONTACT .PP If you have any questions or want to report a bug, please go to https://osmcode.org/contact.html .SH AUTHORS $for(author)$$author$$sep$; $endfor$. $endif$ osmium-tool-1.17.0/man/osmium-add-locations-to-ways.md000066400000000000000000000112571474143067200226300ustar00rootroot00000000000000 # NAME osmium-add-locations-to-ways - add node locations to ways in OSM file # SYNOPSIS **osmium add-locations-to-ways** \[*OPTIONS*\] *OSM-FILE*... # DESCRIPTION Usually only nodes have locations and the ways refer to those locations via the IDs of the nodes. This program will copy the input file(s) to the output, taking the locations from the nodes and adding them to the ways. This makes it easier for other programs to assemble the way geometries. The input file must contain all nodes needed for the ways, otherwise there will be an error. You can change this behaviour using the **\--ignore-missing-nodes** option. Nodes without any tags will not be copied (unless the **\--keep-untagged-nodes/-n** option is used). The size of the output file will be similar or a bit smaller than the input file (unless the **\--keep-untagged-nodes/-n** option is used in which case it will be a lot bigger). Note that the OSM files generated by this command use a format extension. Most programs reading OSM files will not understand this extension and should ignore the extra data. The **osmium add-locations-to-ways** command has to keep an index of the node locations in memory or in a temporary file on disk while doing its work. There are several different ways it can do that which have different advantages and disadvantages. The default is good enough for most cases, but see the [**osmium-index-types**(5)](osmium-index-types.html) man page for details. If the **\--keep-untagged-nodes/-n** option is used, files created by this command can be updated with the **apply-changes** command using the **\--locations-on-ways** option. This command will not work on full history files. The command will work with negative IDs (unless the option **--keep-member-nodes** is used). The index types for positive IDs and negative IDs are set separately with the **\--index-type/-i** and **\--index-type-neg** options, respectively. This commands reads its input file(s) only once (unless the **--keep-member-nodes** option is used) and writes its output file in one go so it can be streamed, ie. it can read from STDIN and write to STDOUT. The input file must be sorted in the usual order: first nodes, then ways, then relations, objects of each type ordered by id. If there are multiple input files, they will be read in the order specified on the command line. They must together have the correct order, so, for instance, the first one can have all the sorted nodes, the second all the sorted ways, etc. If this is not the case use **osmium merge** on the inputs first. # OPTIONS -i, \--index-type=TYPE : Set the index type for positive IDs. For details see the [**osmium-index-types**(5)](osmium-index-types.html) man page. \--index-type-neg=TYPE : Set the index type for negative IDs. For details see the [**osmium-index-types**(5)](osmium-index-types.html) man page. -I, \--show-index-types : Shows a list of available index types. For details see the [**osmium-index-types**(5)](osmium-index-types.html) man page. -n, \--keep-untagged-nodes : Keep the untagged nodes in the output file. \--keep-member-nodes : Keep the nodes that are referenced from relations. If this option is specified the input file(s) are read twice. Note that the nodes kept when this option is set are a strict subset of the nodes kept when **--keep-untagged-nodes** is set, so setting both options is unnecessary. \--ignore-missing-nodes : If this is not set a missing node needed for a way results in an error. If this is set, errors are ignored and the way will have an invalid location set for the missing node. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium add-locations-to-ways** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium add-locations-to-ways** will usually keep all node locations in memory. For larger data files, this can need several tens of GBytes of memory. See the [**osmium-index-types**(5)](osmium-index-types.html) man page for details. # EXAMPLES Add node locations to an extract keeping all nodes: osmium add-locations-to-ways -n -o germany-low.osm.pbf germany.osm.pbf Add node locations to a planet file (without untagged nodes): osmium add-locations-to-ways -i dense_mmap_array -o planet-low.osm.pbf planet.osm.pbf # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-index-types**(5)](osmium-index-types.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-apply-changes.md000066400000000000000000000074661474143067200212500ustar00rootroot00000000000000 # NAME osmium-apply-changes - apply OSM change file(s) to OSM data file # SYNOPSIS **osmium apply-changes** \[*OPTIONS*\] *OSM-DATA-FILE* *OSM-CHANGE-FILE*...\ **osmium apply-changes** \[*OPTIONS*\] *OSM-HISTORY-FILE* *OSM-CHANGE-FILE*... # DESCRIPTION Merges the content of all OSM change files and applies those changes to the OSM data or history file. Objects in the data or history file must be sorted by type, ID, and version. Objects in change files need not be sorted, so it doesn't matter in what order the change files are given or in what order they contain the data. (If you are using change files of extracts this is not necessarily true and you must specify the change files on the command line in the correct order from oldest to newest. This is because change files from extracts can contain multiple different object versions with the same version and timestamp!) Changes can be applied to normal OSM data files or OSM history files with this command. File formats will be autodetected from the file name suffixes, see the **\--with-history/-H** option if that doesn't work. This commands reads its input file(s) only once and writes its output file in one go so it can be streamed, ie. it can read from STDIN and write to STDOUT. # OPTIONS -H, \--with-history : Update an OSM history file (instead of a normal OSM data file). Both input and output must be history files. This option is usually not necessary, because history files will be detected from their file name suffixes, but if this detection doesn't work, you can force this mode with this option. Can not be used together with the **\--locations-on-ways** option. \--locations-on-ways : Input has and output should have node locations on ways. Can be used to update files created by the **osmium-add-locations-to-ways**. See there for details on the format. Can not be used together with the **\--with-history/-H** option. \--redact : Redact (patch) history files. Change files can contain any version of any object which will replace that version of that object from the input. This allows changing the history! This mode is for special use only, for instance to remove copyrighted or private data. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ # INPUT OPTIONS -F, \--input-format=FORMAT : The format of the OSM-DATA-FILE or OSM-HISTORY-FILE. Can be used to set the input format if it can't be autodetected from the file name. See [**osmium-file-formats**(5)](osmium-file-formats.html) or the libosmium manual for details. \--change-file-format=FORMAT : The format of the OSM-CHANGE-FILE(s). Can be used to set the input format if it can't be autodetected from the file name(s). This will set the format for all change files, there is no way to set the format for some change files only. See [**osmium-file-formats**(5)](osmium-file-formats.html) or the libosmium manual for details. @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium apply-changes** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium apply-changes** keeps the contents of all the change files in main memory. This will take roughly 10 times as much memory as the files take on disk in *.osm.bz2* format. # EXAMPLES Apply changes in `362.osc.gz` to planet file and write result to `new.osm.pbf`: osmium apply-changes --output=new.osm.pbf planet.osm.pbf 362.osc.gz # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-merge-changes**(1)](osmium-merge-changes.html), [**osmium-derive-changes**(1)](osmium-derive-changes.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-cat.md000066400000000000000000000051031474143067200172460ustar00rootroot00000000000000 # NAME osmium-cat - concatenate OSM files and convert to different formats # SYNOPSIS **osmium cat** \[*OPTIONS*\] *OSM-FILE*... # DESCRIPTION Concatenates all input files and writes the result to the output file. The data is not sorted in any way but strictly copied from input to output. Because this program supports several different input and output formats, it can be used to convert OSM files from one format into another. This commands reads its input file(s) only once and writes its output file in one go so it can be streamed, ie. it can read from STDIN and write to STDOUT. Usually this is not the right command to merge two or more typical OSM files, see **osmium merge** for that. # OPTIONS -c, \--clean=ATTR : Clean the attribute (*version*, *timestamp*, *changeset*, *uid*, *user*), from the data before writing it out again. The attribute will be set to 0 (the user will be set to the empty string). This option can be given multiple times. Depending on the output format these attributes might show up as 0 or not show up at all. -t, \--object-type=TYPE : Read only objects of given type (*node*, *way*, *relation*, *changeset*). By default all types are read. This option can be given multiple times. \--buffer-data : Read all input files into memory and only then write out all the data. This will need a lot of memory and is usually slower than a normal copy. Used for timing the reading and writing phase separately. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium cat** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium cat** does all its work on the fly and doesn't keep much data in main memory. # EXAMPLES Convert a PBF file to a compressed XML file: osmium cat -o out.osm.bz2 in.osm.pbf Concatenate all change files in the 'changes' directory into one: osmium cat -o all-changes.osc.gz changes/*.osc.gz Copy nodes and ways from source to destination file: osmium cat -o dest.osm.pbf source.osm.pbf -t node -t way Remove changeset, uid, and user from a file to protect personal data: osmium cat -c changeset -c uid -c user -o cleaned.osm.pbf data.osm.pbf # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-merge**(1)](osmium-merge.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-changeset-filter.md000066400000000000000000000044741474143067200217350ustar00rootroot00000000000000 # NAME osmium-changeset-filter - filter changesets from OSM changeset file # SYNOPSIS **osmium changeset-filter** \[*OPTIONS*\] *OSM-CHANGESET-FILE* # DESCRIPTION Copy the changesets matching all the given criteria to the output. Matching criteria are given through command line options. This commands reads its input file only once and writes its output file in one go so it can be streamed, ie. it can read from STDIN and write to STDOUT. # FILTER OPTIONS -a, \--after=TIMESTAMP : Only copy changesets closed after the given time. This will always include all open changesets. -b, \--before=TIMESTAMP : Only copy changesets created before the given time. -B, \--bbox=LONG1,LAT1,LONG2,LAT2 : Only copy changesets with a bounding box overlapping the specified box. The coordinates LONG1,LAT1 are from one arbitrary corner, the coordinates LONG2,LAT2 are from the opposite corner. -c, \--with-changes : Only copy changesets with changes. -C, \--without-changes : Only copy changesets without changes. -d, \--with-discussion : Only copy changesets with discussions, ie changesets with at least one comment. -D, \--without-discussion : Only copy changesets without discussions, ie changesets without any comments. \--open : Only copy open changesets. \--closed : Only copy closed changesets. -u, \--user=USER : Only copy changesets by the given user name. -U, \--uid=UID : Only copy changesets by the given user ID. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium changeset-filter** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium changeset-filter** does all its work on the fly and doesn't keep much data in main memory. # EXAMPLES To see all changesets by user "foo": osmium changeset-filter -u foo -f debug changesets.osm.bz2 To create an OPL file containing only open changesets: osmium changeset-filter --open -o open-changesets.opl.bz2 changesets.osm.bz2 # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-check-refs.md000066400000000000000000000043461474143067200205210ustar00rootroot00000000000000 # NAME osmium-check-refs - check referential integrity of OSM file # SYNOPSIS **osmium check-refs** \[*OPTIONS*\] *OSM-DATA-FILE* # DESCRIPTION Ways in OSM files refer to OSM nodes; relations refer to nodes, ways, or other relations. This command checks whether all objects *referenced* in the input file are also *present* in the input file. Referential integrity is often broken in extracts. This can lead to problems with some uses of the OSM data. Use this command to make sure your data is good. If the option **\--check-relations/-r** is not given, this command will only check if all nodes referenced in ways are in the file, with the option, relations will also be checked. This command expects the input file to be ordered in the usual way: First nodes in order of ID, then ways in order of ID, then relations in order of ID. Negative IDs are allowed, they must be ordered before the positive IDs. See the [**osmium-sort**(1)](osmium-sort.html) man page for details of the ordering. This command will only work for OSM data files, not OSM history files or change files. This commands reads its input file only once, ie. it can read from STDIN. # OPTIONS -i, \--show-ids : Print all missing IDs to STDOUT. If you don't specify this option, only a summary is shown. -r, \--check-relations : Also check referential integrity of relations. Without this option, only nodes in ways are checked. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ # MEMORY USAGE **osmium check-refs** will do the check in one pass through the input data. It needs enough main memory to store all temporary data. Largest memory need will be about 1 bit for each node ID, that's roughly 860 MB these days (February 2020). With the **\--check-relations/-r** option memory use will be a bit bigger. # DIAGNOSTICS **osmium check-refs** exits with exit code 0 ~ if all references are satisfied 1 ~ if there was an error processing the data or some references were not satisfied, or 2 ~ if there was a problem with the command line arguments. # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-sort**(1)](osmium-sort.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-create-locations-index.md000066400000000000000000000041451474143067200230450ustar00rootroot00000000000000 # NAME osmium-create-locations-index - create or update locations index from OSM file # SYNOPSIS **osmium create-locations-index** -i INDEX-FILE \[*OPTIONS*\] *OSM-FILE* # DESCRIPTION Create an index of all node locations from the OSM-FILE in the file INDEX-FILE. If the INDEX-FILE exists, it will not be touched unless the **\--update/-u** option is used. Regardless of the size of the input file, this index will need about 8 * highest-node-id bytes on disk. For a current planet file this is more than 50 GBytes. The index file format is compatible to the one created by "osmium add-location-to-ways -i dense_file_array,INDEX-FILE" and to the flatnode store created by osm2pgsql. When the input file is a full history file or a change file, the last location encountered in the file for any ID ends up in the index. Usually this will be the newest location (from the node with the highest version). This command will not work with negative node IDs. This commands reads its input file only once, so it can be streamed, ie. it can read from STDIN. # OPTIONS -i, \--index-file=FILENAME : The name of the index file. -u, \--update : Allow updating of existing file. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ # DIAGNOSTICS **osmium create-locations-index** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium create-locations-index** will not use a lot of memory. # EXAMPLES Create node locations index from planet: osmium create-locations-index -i locations.idx planet.osm.pbf Set a node location in the index using an input file in OPL format: echo "n123 x-80.6042 y28.6083" | \ osmium create-locations-index -i locations.idx -F opl --update # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-query-locations-index**(1)](osmium-query-locations-index.html), [**osmium-file-formats**(5)](osmium-file-formats.html) * [Osmium website](https://osmcode.org/osmium-tool/) * [osm2pgsql](https://wiki.openstreetmap.org/wiki/Osm2pgsql) osmium-tool-1.17.0/man/osmium-derive-changes.md000066400000000000000000000066301474143067200213710ustar00rootroot00000000000000 # NAME osmium-derive-changes - create OSM change files from two OSM data files # SYNOPSIS **osmium derive-changes** \[*OPTIONS*\] *OSM-FILE1* *OSM-FILE2* # DESCRIPTION Finds differences between two OSM files and creates a change file with those differences. The resulting change file is created in a way, that it could be applied on *OSM-FILE1* to re-create *OSM-FILE2*. Objects in both input files must be sorted by type, ID, and version. The first input file must be from a point in time before the second input file. Only object type, id, and version are compared, so this program will not detect differences in, say, the tags, unless the object has a new version, which is the normal way things work in OSM. If you need to compare all data in OSM files, have a look at the **osmium diff** program. For this command to create a proper change file you have to set the **\--output** option or **\--output-format** option in a way that it will generate an .osc file, typically by using something like '-o out.osc.gz'. You can create any other OSM file format, but that is usually not what you want. Osmium derive-changes will warn you in this case. Note that for objects that are in *OSM-FILE1* but not *OSM-FILE2* a "deleted" entry will be created in the output. But because we can not know when this deletion actually occurred, in which changeset, and by which user, it is unclear what attributes this deleted object should have. Also, if you are working with extracts, the object might not actually have been deleted in the OSM database, but just moved out of the extract you are looking at. So a real, new, "deleted" version was never created. Usually the "deleted" object will get the same version number and timestamp as the object in *OSM-FILE1* had, all other information will be removed. But you can change this using the **\--increment-version**, **\--keep-details**, and **\--update-timestamp** options. Depending on which software you are using the change files with, different settings might be necessary. This commands reads its input files only once and writes its output file in one go so it can be streamed, ie. it can read from STDIN and write to STDOUT. # OPTIONS \--increment-version : Increment version number of deleted objects. \--keep-details : Keep details of deleted objects. Usually only id, version, and timestamp are kept. If this option is set all attributes, all tags, and all nodes or members for ways and relations, respectively, are kept. \--update-timestamp : Update timestamp of deleted objects to the current time. This is the same behaviour as Osmosis. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium derive-changes** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium derive-changes** doesn't keep a lot of data in memory. # EXAMPLES Find changes in Nepal extract in January 2016: osmium derive-changes nepal-20160101.osm.pbf nepal-20160201.osm.pbf -o nepal-jan.osc.bz2 # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html), [**osmium-apply-changes**(1)](osmium-apply-changes.html), [**osmium-diff**(1)](osmium-diff.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-diff.md000066400000000000000000000101251474143067200174070ustar00rootroot00000000000000 # NAME osmium-diff - display differences between OSM files # SYNOPSIS **osmium diff** \[*OPTIONS*\] *OSM-FILE1* *OSM-FILE2* # DESCRIPTION Finds all differences between two OSM files and displays them. This command compares all attributes of all objects, so it will even find, say, differences in the user name or even the order of tags, differences that should not happen in normal OSM data unless there is also a different object version. Only differences between objects (node, ways, and relations) are found and displayed. Headers are ignored. Objects in both input files must be sorted in the same order. Several output formats are supported, see the **OUTPUT FORMATS** section. This command is intended for displaying the differences between files to humans. It can not be used to create an OSM change file (`.osc`), use **osmium-derive-changes** for that. # OUTPUT FORMATS The following output formats are supported and can be set with the **\--output-format/-f** options. Default is the compact format. compact : A very compact format. For all objects a line is printed with the type of object ('n', 'w', or 'r'), the object ID and then the version number. If objects appear in both files and are identical they are preceded by a space (' ') character, if they are in both files, but different, they are preceded by an asterisk ('*'). Otherwise they get a minus ('-') or plus ('+') character to show that they are only in the first or second file, respectively. opl : The usual OPL format with all lines preceded by space (' '), minus ('-'), or plus ('+') characters depending on whether the object is in both, the first, or the second file. debug : The usual debug format with all lines preceded by space (' '), minus ('-'), or plus ('+') characters depending on whether the object is in both, the first, or the second file. Color support can be enabled ('debug,color'). None of the output formats print the headers of the input files. # OPTIONS -c, \--suppress-common : Do not output objects that are the same in both files. -f, \--output-format=FORMAT : See the **OUTPUT FORMATS** section. \--ignore-changeset : Ignore changeset id on OSM objects when comparing files. When used with the OPL output format the 'changeset' attribute is not written to the output. \--ignore-uid : Ignore user id on OSM objects when comparing files. When used with the OPL output format the 'uid' attribute is not written to the output. \--ignore-user : Ignore user name on OSM objects when comparing files. When used with the OPL output format the 'user' attribute is not written to the output. -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. -q, \--quiet : No output. Just report when files differ through the return code. -s, \--summary : Print count of objects that are only in the left or right files, or the same in both or different in both to STDERR. -t, \--object-type=TYPE : Read only objects of given type (*node*, *way*, *relation*). By default all types are read. This option can be given multiple times. This affects the output as well as the return code of the command. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ # DIAGNOSTICS **osmium diff** exits with exit code 0 ~ if the files are the same, 1 ~ if the files are different, or 2 ~ if there was an error # MEMORY USAGE **osmium diff** doesn't keep a lot of data in memory. # EXAMPLES Show difference between Nepal files from January 2016 and February 2016 in compact format: osmium diff nepal-20160101.osm.pbf nepal-20160201.osm.pbf Show in color debug format only those objects that are different: osmium diff nepal-20160101.osm.pbf nepal-20160201.osm.pbf -f debug,color -c # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-derive-changes**(1)](osmium-derive-changes.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-export.md000066400000000000000000000360771474143067200200360ustar00rootroot00000000000000 # NAME osmium-export - export OSM data # SYNOPSIS **osmium export** \[*OPTIONS*\] *OSM-FILE* # DESCRIPTION The OSM data model with its nodes, ways, and relations is very different from the data model usually used for geodata with features having point, linestring, or polygon geometries (or their cousins, the multipoint, multilinestring, or multipolygon geometries). The **export** command transforms OSM data into a more usual GIS data model. Nodes will be translated into points and ways into linestrings or polygons (if they are closed ways). Multipolygon and boundary relations will be translated into multipolygons. This transformation is not loss-less, especially information in non-multipolygon, non-boundary relations is lost. All tags are preserved in this process. Note that most GIS formats (such as Shapefiles, etc.) do not support arbitrary tags. Transformation into other GIS formats will need extra steps mapping tags to a limited list of attributes. This is outside the scope of this command. The **osmium export** command has to keep an index of the node locations in memory or in a temporary file on disk while doing its work. There are several different ways it can do that which have different advantages and disadvantages. The default is good enough for most cases, but see the [**osmium-index-types**(5)](osmium-index-types.html) man page for details. Objects with invalid geometries are silently omitted from the output. This is the case for ways with less than two nodes or closed ways or relations that can't be assembled into a valid (multi)polygon. See the options **\--show-errors/-e** and **\--stop-on-error/-E** for how to modify this behaviour. The input file will be read twice (once for the relations, once for nodes and ways), so this command can not read its input from STDIN. This command will not work on full history files. This command will work with negative IDs on OSM objects (for instance on files created with JOSM). # OPTIONS -c, \--config=FILE : Read configuration from specified file. -C, \--print-default-config : Print the default config to STDOUT. Useful if you want to change it and not write the whole thing manually. If you use this option all other options are ignored. -e, \--show-errors : Output any geometry errors on STDERR. This includes ways with a single node or areas that can't be assembled from multipolygon relations. This output is not suitable for automated use, there are other tools that can create very detailed errors reports that are better for that (see https://osmcode.org/osm-area-tools/). -E, \--stop-on-error : Usually geometry errors (due to missing node locations or broken polygons) are ignored and the features are omitted from the output. If this option is set, any error will immediately stop the program. \--geometry-types=TYPES : Specify the geometry types that should be written out. Usually all created geometries (points, linestrings, and (multi)polygons) are written to the output, but you can restrict the types using this option. TYPES is a comma-separated list of the types ("point", "linestring", and "polygon"). -a, \--attributes=ATTRS : In addition to tags, also export attributes specified in this comma-separated list. By default, none are exported. See the **ATTRIBUTES** section below for the known attributes list and an explanation. -i, \--index-type=TYPE : Set the index type. For details see the [**osmium-index-types**(5)](osmium-index-types.html) man page. -I, \--show-index-types : Shows a list of available index types. For details see the [**osmium-index-types**(5)](osmium-index-types.html) man page. If you use this options all other options are ignored. -n, \--keep-untagged : If this is set, features without any tags will be in the exported data. By default these features will be omitted from the output. Tags are the OSM tags, not attributes (like id, version, uid, ...) without the tags removed by the **exclude_tags** or **include_tags** settings. -u, \--add-unique-id=TYPE : Add a unique ID to each feature. TYPE can be either *counter* in which case the first feature will get ID 1, the next ID 2 and so on. The type of object does not matter in this case. Or the TYPE is *type_id* in which case the ID is a string, the first character is the type of object ('n' for nodes, 'w' for linestrings created from ways, and 'a' for areas created from ways and/or relations, after that there is a unique ID based on the original OSM object ID(s). For nodes and ways the numeric part of the ID is identical to the original node or way ID. For areas, the ID is calculated from the original ID, for ways it is twice the original ID, for relations it is twice the original ID plus one. If the input file has negative IDs, this can create IDs such as 'w-12'. -x, \--format-option=OPTION(=VALUE) : Set an output format option. The options available depend on the output format. See the **OUTPUT FORMAT OPTIONS** section for available options. If the VALUE is not set, the OPTION will be set to "true". If needed you can specify this option multiple times to set several options. Options set on the command line overwrite options set in the config file. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ # OUTPUT 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 the OUTPUT FORMATS section for a list of formats. \--fsync : Call fsync after writing the output file to force flushing buffers to disk. -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. # CONFIG FILE The config file is in JSON format. The top-level is an object which contains the following optional names: * `attributes`: An object specifying which attributes of OSM objects to export. See the ATTRIBUTES section. * `format_options`: An object specifying output format options. The options available depend on the output format. See the **OUTPUT FORMAT OPTIONS** section for available options. These options can also be set using the command line option **\--format-option/-x**. * `linear_tags`: An expression specifying tags that should be treated as linear tags. See below for details and also look at the AREA HANDLING section. * `area_tags`: An expression specifying tags that should be treated as area tags. See below for details and also look at the AREA HANDLING section. * `exclude_tags`: A list of tag expressions. Tags matching these expressions are excluded from the output. See the FILTER EXPRESSION section. * `include_tags`: A list of tag expressions. Tags matching these expressions are included in the output. See the FILTER EXPRESSION section. The `area_tags` and `linear_tags` can have the following values: true : All tags match. (An empty list `[]` can also be used to mean the same, but this use is deprecated because it can be confusing.) false : No tags match. Array : The array contains one or more expressions as described in the FILTER EXPRESSION section. null : If the `area_tags` or `linear_tags` is set to null or not set at all, the inverse of the other setting is used. So if you do not set the `linear_tags` but have some expressions in `area_tags`, areas will be created for all objects matching those expressions and linestrings for everything else. This can be simpler, because you only have to keep one list, but in cases where an object can be interpreted as both an area and a linestring, only one interpretation will be used. The `exclude_tags` and `include_tags` options are mutually exclusive. If you want to just exclude some tags but leave most tags untouched, use the `exclude_tags` setting. If you only want a defined list of tags, use `include_tags`. When no config file is specified, the following settings are used: @EXPORT_DEFAULT_CONFIG@ # FILTER EXPRESSIONS A filter expression specifies a tag or tags that should be matched in the data. Some examples: amenity : Matches all objects with the key "amenity". highway=primary : Matches all objects with the key "highway" and value "primary". highway!=primary : Matches all objects with the key "highway" and a value other than "primary". type=multipolygon,boundary : Matches all objects with key "type" and value "multipolygon" or "boundary". name,name:de=Kastanienallee,Kastanienstrasse : Matches any object with a "name" or "name:de" tag with the value "Kastanienallee" or "Kastanienstrasse". addr:\* : Matches all objects with any key starting with "addr:" name=\*Paris : Matches all objects with a name that contains the word "Paris". If there is no equal sign ("=") in the expression only keys are matched and values can be anything. If there is an equal sign ("=") in the expression, the key is to the left and the value to the right. An exclamation sign ("!") before the equal sign means: A tag with that key, but not the value(s) to the right of the equal sign. A leading or trailing asterisk ("\*") can be used for substring or prefix matching, respectively. Commas (",") can be used to separate several keys or values. All filter expressions are case-sensitive. There is no way to escape the special characters such as "=", "\*" and ",". You can not mix comma-expressions and "\*"-expressions. # ATTRIBUTES All OSM objects (nodes, ways, and relations) have *attributes*, areas inherit their attributes from the ways and/or relations they were created from. The attributes known to `osmium export` are: * `type` ('node', 'way', or 'relation') * `id` (64 bit object ID) * `version` (version number) * `changeset` (changeset ID) * `timestamp` (time of object creation in seconds since Jan 1 1970) * `uid` (user ID) * `user` (user name) * `way_nodes` (ways only, array with node IDs) For areas, the type will be `way` or `relation` if the area was created from a closed way or a multipolygon or boundary relation, respectively. The `id` for areas is the id of the closed way or the multipolygon or boundary relation. By default the attributes will not be in the export, because they are not necessary for most uses of OSM data. If you are interested in some (or all) attributes, add an `attributes` object to the config file. Add a member for each attribute you are interested in, the value can be either `false` (do not output this attribute), `true` (output this attribute with the attribute name prefixed by the `@` sign) or any string, in which case the string will be used as the attribute name. Another option is to specify attributes list in a comma-separated string for the **\--attributes/-a** command-line option. This way you cannot control column names, but also you won't have to create a config file. Depending on your choice of values for the `attributes` objects, attributes can have the same name as tag keys. If this is the case, the conflicting tag is silently dropped. So if there is a tag "@id=foo" and you have set `id` to `true` in the `attributes` object, the tag will not show up in the output. Note that the `id` is not necessarily unique. Even the combination `type` and `id` is not unique, because a way may end up in the output file as LineString and as (Multi)Polygon. See the **\--add-unique-id/-u** option for a unique ID. # AREA HANDLING Multipolygon relations will be assembled into multipolygon geometries forming areas. Some closed ways will also form areas. Here are the detailed rules: Non-closed way : A non-closed way (with the last node location not the same as the first node location) is always (regardless of any tags) a linestring, not an area. Relation : A relation tagged `type=multipolygon` or `type=boundary` is always (regardless of any tags) assembled into an area. Closed way : For a closed way (with the last node location the same as the first node location) the tags are checked: If the way has an `area=yes` tag, an area is created. If the way has an `area=no` tag, a linestring is created. An `area` tag with a value other than `yes` or `no` is ignored. The configuration settings `area_tags` and `linear_tags` can be used to augment the area check. If any of the tags matches the `area_tags`, an area is created. If any of the tags matches the `linear_tags`, a linestring is created. If both match, an area and a linestring is created. This is important because some objects have tags that make them both, an area and a linestring. # OUTPUT FORMATS The following output formats are supported: * `geojson` (alias: `json`): GeoJSON (RFC7946). The output file will contain a single `FeatureCollection` object. This is the default format. * `geojsonseq` (alias: `jsonseq`): GeoJSON Text Sequence (RFC8142). Each line (beginning with a RS (0x1e, record separator) and ending in a linefeed character) contains one GeoJSON object. Used for streaming GeoJSON. * `pg`: PostgreSQL COPY text format. One line per object containing the WGS84 geometry as WKB, the tags in JSON format and, optionally, more columns for id and attributes. You have to create the table manually, then use the PostgreSQL COPY command to import the data. Enable verbose output to see the SQL commands needed to create the table and load the data. * `text` (alias: `txt`): A simple text format with the geometry in WKT format followed by the comma-delimited tags. This is mainly intended for debugging at the moment. THE FORMAT MIGHT CHANGE WITHOUT NOTICE! # OUTPUT FORMAT OPTIONS * `print_record_separator` (default: `true`). Set to `false` to not print the RS (0x1e, record separator) character when using the GeoJSON Text Sequence Format. Ignored for other formats. * `tags_type` (default: `jsonb`). Set to `hstore` to use HSTORE format instead of JSON/JSONB when using the Pg Format. Ignored in other formats. # DIAGNOSTICS **osmium export** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium export** will usually keep all node locations and all objects needed for assembling the areas in memory. For larger data files, this can need several tens of GBytes of memory. See the [**osmium-index-types**(5)](osmium-index-types.html) man page for details. # EXAMPLES Export into GeoJSON format: osmium export data.osm.pbf -o data.geojson Use a config file and export into GeoJSON Text Sequence format: osmium export data.osm.pbf -o data.geojsonseq -c export-config.json # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-index-types**(5)](osmium-index-types.html), [**osmium-add-node-locations-to-ways**(1)](osmium-add-node-locations-to-ways.html) * [Osmium website](https://osmcode.org/osmium-tool/) * [GeoJSON](http://geojson.org/) * [RFC7946](https://tools.ietf.org/html/rfc7946) * [RFC8142](https://tools.ietf.org/html/rfc8142) * [Line delimited JSON](https://en.wikipedia.org/wiki/JSON_Streaming#Line_delimited_JSON) osmium-tool-1.17.0/man/osmium-extract.md000066400000000000000000000401001474143067200201450ustar00rootroot00000000000000 # NAME osmium-extract - create geographical extracts from an OSM file # SYNOPSIS **osmium extract** \--config *CONFIG-FILE* \[*OPTIONS*\] *OSM-FILE*\ **osmium extract** \--bbox *LEFT*,*BOTTOM*,*RIGHT*,*TOP* \[*OPTIONS*\] *OSM-FILE*\ **osmium extract** \--polygon *POLYGON-FILE* \[*OPTIONS*\] *OSM-FILE* # DESCRIPTION Create geographical extracts from an OSM data file or an OSM history file. The region (geographical extent) can be given as a bounding box or as a (multi)polygon. There are three ways of calling this command: * Specify a config file with the **\--config/-c** option. It can define any number of regions you want to cut out. See the **CONFIG FILE** section for details. * Specify a bounding box to cut out with the **\--bbox/-b** option. * Specify a (multi)polygon to cut out with the **\--polygon/-p** option. The input file is assumed to be ordered in the usual order: nodes first, then ways, then relations. If the **\--with-history/-H** option is used, the command will work correctly for history files. This currently works for the **complete_ways** strategy only. The **simple** or **smart** strategies do not work with history files. A history extract will contain every version of all objects with at least one version in the region. Generating a history extract is somewhat slower than a normal data extract. Osmium will make sure that all nodes on the vertices of the boundary of the region will be in the extract, but nodes that happen to be directly on the boundary, but between those vertices, might end up in the extract or not. In almost all cases this will be good enough, but if you want to make really sure you got everything, use a small buffer around your region. By default no **bounds** will be set in the header of the output file. Use the **\--set-bounds** option if you need this. Note that **osmium extract** will never clip any OSM objects, ie. it will not remove node references outside the region from ways or unused relation members from relations. This means you might get objects that are not reference-complete. It has the advantage that you can use **osmium merge** to merge several extracts without problems. # OPTIONS -b, \--bbox=LONG1,LAT1,LONG2,LAT2 : Set the bounding box to cut out. Can not be used with **\--polygon/-p**, **\--config/-c**, or **\--directory/-d**. The coordinates LONG1,LAT1 are from one arbitrary corner, the coordinates LONG2,LAT2 are from the opposite corner. -c, \--config=FILE : Set the name of the config file. Can not be used with the **\--bbox/-b** or **\--polygon/-p** option. If this is set, the **\--output/-o** and **\--output-format/-f** options are ignored, because they are set in the config file. \--clean=ATTR : Clean the attribute (*version*, *timestamp*, *changeset*, *uid*, *user*), from the data before writing it out again. The attribute will be set to 0 (the user will be set to the empty string). This option can be given multiple times. Depending on the output format these attributes might show up as 0 or not show up at all. -d, \--directory=DIRECTORY : Output directory. Output file names in the config file are relative to this directory. Overwrites the setting of the same name in the config file. This option is ignored when the **\--bbox/-b** or **\--polygon/-p** options are used, set the output directory and name with the **\--output/-o** option in that case. -H, \--with-history : Specify that the input file is a history file. The output file(s) will also be history file(s). -p, \--polygon=POLYGON_FILE : Set the polygon to cut out based on the contents of the file. The file has to be a GeoJSON, poly, or OSM file as described in the **(MULTI)POLYGON FILE FORMATS** section. It has to have the right suffix to be detected correctly. Can not be used with **\--bbox/-b**, **\--config/-c**, or **\--directory/-d**. -s, \--strategy=STRATEGY : Use the given strategy to extract the region. For possible values and details see the **STRATEGIES** section. Default is "complete_ways". -S, \--option=OPTION=VALUE : Set a named option for the strategy. If needed you can specify this option multiple times to set several options. \--set-bounds : Set the bounds field in the header. The bounds are set to the bbox or envelope of the polygon specified for the extract. Note that strategies other than "simple" can put nodes outside those bounds into the output file. @MAN_COMMON_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # CONFIG FILE The config file mainly specifies the file names and the regions of the extracts that should be created. The config file is in JSON format. The top-level is an object which contains at least an "extracts" array. It can also contain a "directory" entry which names the directory where all the output files will be created: { "extracts": [...], "directory": "/tmp/" } The extracts array specifies the extracts that should be created. Each item in the array is an object with at least a name "output" naming the output file and a region defined in a "bbox", "polygon" or "multipolygon" name. An optional "description" can be added, it will not be used by the program but can help with documenting the file contents. You can add an optional "output_format" if the format can not be detected from the "output" file name. Run "osmium help file-formats" to get a description of allowed formats. The optional "output_header" allows you to set additional OSM file header settings such as the "generator". If you set the value of a file header setting to `null`, the output header will be set to the same header from the input file. "extracts": [ { "output": "hamburg.osm.pbf", "output_format": "pbf", "description": "optional description", "bbox": ... }, { "output": "berlin.osm.pbf", "description": "optional description", "polygon": ... }, { "output": "munich.osm.pbf", "output_header": { "generator": "MyExtractor/1.0", "osmosis_replication_timestamp": null }, "description": "optional description", "multipolygon": ... } ] There are several formats for specifying the regions: **bbox**: A bounding box in one of two formats. The first is a simple array with four real numbers, the first two specifying the coordinates of an arbitrary corner, the second two specifying the coordinates of the opposite corner. { "output": "munich.osm.pbf", "description": "Bounding box specified in array format", "bbox": [11.35, 48.05, 11.73, 48.25] } The second format uses an object instead of an array: { "output": "dresden.osm.pbf", "description": "Bounding box specified in object format", "bbox": { "left": 13.57, "right": 13.97, "top": 51.18, "bottom": 50.97 } } **polygon**: A polygon, either specified inline in the config file or read from an external file. See the **(MULTI)POLYGON FILE FORMATS** section for external files. If specified inline this is a nested array, the outer array defining the polygon, the next array the rings and the innermost arrays the coordinates. This format is the same as in GeoJSON files. In this example there is only one outer ring: "polygon": [[ [9.613465, 53.58071], [9.647599, 53.59655], [9.649288, 53.61059], [9.613465, 53.58071] ]] In each ring, the last set of coordinates should be the same as the first set, closing the ring. **multipolygon**: A multipolygon, either specified inline in the config file or read from an external file. See the **(MULTI)POLYGON FILE FORMATS** section for external files. If specified inline this is a nested array, the outer array defining the multipolygon, the next array the polygons, the next the rings and the innermost arrays the coordinates. This format is the same as in GeoJSON files. In this example there is one outer and one inner ring: "multipolygon": [[[ [6.847, 50.987], [6.910, 51.007], [7.037, 50.953], [6.967, 50.880], [6.842, 50.925], [6.847, 50.987] ],[ [6.967, 50.954], [6.969, 50.920], [6.932, 50.928], [6.934, 50.950], [6.967, 50.954] ]]] In each ring, the last set of coordinates should be the same as the first set, closing the ring. Osmium must check each and every node in the input data and find out in which bounding boxes or (multi)polygons this node is. This is very cheap for bounding boxes, but more expensive for (multi)polygons. And it becomes more expensive the more vertices the (multi)polyon has. Use bounding boxes or simplified polygons where possible. Note that bounding boxes or (multi)polygons are not allowed to span the -180/180 degree line. If you need this, cut out the regions on each side and use **osmium merge** to join the resulting files. # (MULTI)POLYGON FILE FORMATS External files describing a (multi)polygon are specified in the config file using the "file_name" and "file_type" properties on the "polygon" or "multipolygon" object: "polygon": { "file_name": "berlin.geojson", "file_type": "geojson" } If file names don't start with a slash (/), they are interpreted relative to the directory where the config file is. If the "file_type" is missing, Osmium will try to autodetect it from the suffix of the "file_name". The following file types are supported: geojson : GeoJSON file containing exactly one Feature of type Polygon or MultiPolygon, or a FeatureCollection with the first Feature of type Polygon or MultiPolygon. Everything except the actual geometry (of the first Feature) is ignored. poly : A poly file as described in https://wiki.openstreetmap.org/wiki/Osmosis/Polygon_Filter_File_Format . This wiki page also mentions several sources for such poly files. osm : An OSM file containing one or more multipolygon or boundary relation together with all the nodes and ways needed. Any OSM file format (XML, PBF, ...) supported by Osmium can be used here, but the correct suffix must be used, so the file format is detected correctly. Files for this can easily be obtained by searching for the area on OSM and then downloading the full relation using a URL like https://www.openstreetmap.org/api/0.6/relation/RELATION-ID/full . Or you can use **osmium getid -r** to get a specific relation from an OSM file. Note that both these approaches can get you very detailed boundaries which can take quite a while to cut out. Consider simplifying the boundary before use. If there are several (multi)polygons in a poly file or OSM file, they will be merged. The (multi)polygons must not overlap, otherwise the result is undefined. # STRATEGIES **osmium extract** can use different strategies for creating the extracts. Depending on the strategy different objects will end up in the extracts. The strategies differ in how much memory they need and how often they need to read the input file. The choice of strategy depends on how you want to use the generated extracts and how much memory and time you have. The default strategy is **complete_ways**. Strategy **simple** : Runs in a single pass. The extract will contain all nodes inside the region and all ways referencing those nodes as well as all relations referencing any nodes or ways already included. Ways crossing the region boundary will not be reference-complete. Relations will not be reference-complete. This strategy is fast, because it reads the input only once, but the result is not enough for most use cases. It is the only strategy that will work when reading from a socket or pipe. This strategy will not work for history files. Strategy **complete_ways** : Runs in two passes. The extract will contain all nodes inside the region and all ways referencing those nodes as well as all nodes referenced by those ways. The extract will also contain all relations referenced by nodes inside the region or ways already included and, recursively, their parent relations. The ways are reference-complete, but the relations are not. Strategy **smart** : Runs in three passes. The extract will contain all nodes inside the region and all ways referencing those nodes as well as all nodes referenced by those ways. The extract will also contain all relations referenced by nodes inside the region or ways already included and, recursively, their parent relations. The extract will also contain all nodes and ways (and the nodes they reference) referenced by relations tagged "type=multipolygon" directly referencing any nodes in the region or ways referencing nodes in the region. The ways are reference-complete, and all multipolygon relations referencing nodes in the regions or ways that have nodes in the region are reference-complete. Other relations are not reference-complete. For the **complete_ways** strategy you can set the option "-S relations=false" in which case no relations will be written to the output file. The **smart** strategy allows the following strategy options: Use "-S types=TYPE,..." to change the types of relations that should be reference-complete. Instead of just relations tagged "type=multipolygon", you can either get all relations (use "-S types=any") or give a list of types to the -S option: "-S types=multipolygon,route". Note that especially boundary relations can be huge, so if you include them, be aware your result might be huge. Use "-S complete-partial-relations=X" to force completion of partly completed relations. If this is set, all relations that have more than X percent of their members already in the extract will have their full set of members in the extract. So this allows completing almost complete relations. It can be useful for instance to make sure a boundary relation is complete even if some of it is outside the polygon used for extraction. Use "-S tags=PATTERN,..." to only complete relations that have a tag matching one of the PATTERNs. So for example if you use "-S tags=landuse,natural=wood,natural=water" everything tagged `landuse=*` or `natural=wood` or `natural=water` is added to the result, but no other relations. You can combine the "-S types", "-S complete-partial-relations", and "-S tags" options. The options will be interpreted as "(types OR complete-partial-relations) AND tags". # DIAGNOSTICS **osmium extract** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments, config file or polygon files. # MEMORY USAGE Memory usage of **osmium extract** depends on the number of extracts and on the strategy used. For the *simple* strategy it will at least be the number of extracts times the highest node ID used divided by 8. For the *complete_ways* twice that and for the *smart* strategy a bit more. If you want to split a large file into many extracts, do this in several steps. First create several larger extracts and then split them again and again into smaller pieces. # LIMITS You can not have more than 500 extracts. Although chances are that you will be running out of memory long before that. See MEMORY USAGE. # EXAMPLES See the example config files in the *extract-example-config* directory. To try it: osmium extract -v -c extract-example-config/extracts.json \ germany-latest.osm.pbf Extract the city of Karlsruhe using a boundary polygon: osmium extract -p karlsruhe-boundary.osm.bz2 germany-latest.osm.pbf \ -o karlsruhe.osm.pbf Extract the city of Munich using a bounding box: osmium extract -b 11.35,48.05,11.73,48.25 germany-latest.osm.pbf \ -o munich.osm.pbf # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html), [**osmium-getid**(1)](osmium-getid.html), [**osmium-merge**(1)](osmium-merge.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-file-formats.md000066400000000000000000000121501474143067200210670ustar00rootroot00000000000000 # NAME osmium-file-formats - OSM file formats known to Osmium # FILE TYPES OSM uses three types of files for its main data: **Data files** : These are the most common files. They contain the OSM data from a specific point in time. This can either be a planet file containing *all* OSM data or some kind of extract. At most one version of every object (node, way, or relation) is contained in this file. Deleted objects are *not* in this file. The usual suffix used is `.osm`. **History files** : These files contain not only the current version of an object, but their history, too. So for any object (node, way, or relation) there can be zero or more versions in this file. Deleted objects can also be in this file. The usual suffix used is `.osm` or `.osh`. Because sometimes the same suffix is used as for normal data files (`.osm`) and because there is no clear indicator in the header, it is not always clear what type of file you have in front of you. **Change files** : Sometimes called *diff files* or *replication diffs* these files contain the changes between one state of the OSM database and another state. Change files can contains several versions of an object and also deleted objects. The usual suffix used is `.osc`. All these files have in common that they contain OSM objects (nodes, ways, and relations). History files and change files can contain several versions of the same object and also deleted objects, data files can't. Where possible, Osmium commands can handle all file types. For some commands only some file types make sense. # FORMATS The **osmium** command line tool supports all major OSM file formats plus some more. These are: * The classical XML format in the variants *.osm* (for data files), *.osh* (for data files with history) and *.osc* (for change files). * The PBF binary format (usually with suffix *.osm.pbf* or just *.pbf*). * The OPL format (usually with suffix *.osm.opl* or just *.opl*). * The O5M/O5C format (usually with suffix *.o5m* or *.o5c*) (reading only). * The "debug" format (usually with suffix *.osm.debug*) (writing only). In addition files in all formats except PBF can be compressed using *gzip* or *bzip2*. (Add *.gz* or *.bz2* suffixes, respectively.) # AUTODETECTION Which format a file has is usually autodetected from the file name suffix. If this doesn't work, either because you are reading from STDIN or writing to STDOUT, or because you have an unusual file name, you have to set the format manually. You can also set the format manually if you want to specify special format options. Most **osmium** commands support the **\--input-format/-F** and **\--output-format/-f** options to set the format. They take a comma-separated list of arguments, the first is the format, further arguments set additional options. # SPECIAL FORMAT OPTIONS The following options can be added when writing OSM files: `history`=`true`/`false` : Explicitly set whether this file allows multiple versions of the same object or not. By default set to `true` for *.osh* and *.osc* files, to `false` otherwise. `xml_change_format`=`true`/`false` : Enable/disable XML change format. Same as *.osc*. `force_visible_flag`=`true`/`false` (*default: false*) : Force writing of visible flag, even for normal OSM XML files. `pbf_dense_nodes`=`true`/`false` (*default: true*) : Enable/disable DenseNodes format for PBF files. `pbf_compression`=`none`/`zlib`/`lz4` (*default: zlib*) : Set compression type in PBF files. `zlib` (or `true`) is the default and almost all files use this. `none` (or `false`) disables compression which will make writing files a bit faster, but the resulting files are 2 to 3 times bigger. The `lz4` compression is not quite as good as `zlib` but much faster to compress and decompress, it is currently not supported by most OSM file readers. `pbf_compression_level`=... : Set compression level for PBF. Available values and default depend on the compression type used, see the OSM File Formats Manual for details. `add_metadata`=`true`/`false`/... (*default: true*) : Enable/disable writing of object metadata such as changeset id, username, etc. Disabling this will make files a bit smaller. This can also be set to other values, see the OSM File Formats Manual for details. `locations_on_ways`=`true`/`false` (*default: false*) : Add node locations to way nodes. (PBF, XML, OPL only.) `use_color`=`true`/`false` (*default: false*) : Output with ANSI colors. (DEBUG format only.) `add_crc32`=`true`/`false` (*default: false*) : Add CRC32 checksum to all objects. (DEBUG format only.) # EXAMPLES Here are some examples: `pbf` : PBF format. `pbf,add_metadata=false` : PBF format, don't write metadata `osm.bz2` : XML format, compressed with bzip2. `osc.gz` : OSM change file, compressed with gzip. `osm.gz,xml_change_format=true` : OSM change file, compressed with gzip. `osh.opl` : OSM history file in OPL format. # SEE ALSO * [**osmium**(1)](osmium.html) * [Osmium website](https://osmcode.org/osmium-tool/) * [OSM File Formats Manual](https://osmcode.org/file-formats-manual/) osmium-tool-1.17.0/man/osmium-fileinfo.md000066400000000000000000000137511474143067200203020ustar00rootroot00000000000000 # NAME osmium-fileinfo - show information about an OSM file # SYNOPSIS **osmium fileinfo** \[*OPTIONS*\] *OSM-FILE* # DESCRIPTION Shows various information about OSM files such as the file type, bounding boxes in the header, etc. This command will usually only read the file header. Use the **\--extended/-e** option to show more information. Normally this command will output the data in human readable form. If the **\--json/-j** option is used, the output will be in JSON format instead. If the **\--get/-g** option is used, only the value of the named variable will be printed. The output is split into four sections: File : This section shows the information available without opening the file itself. It contains the file name, the format deduced from the file name, the compression used and the size of the file in bytes. Header : This section shows the information available from the header of the file (if available, OPL files have no header). Any available bounding boxes are shown as well as header options such as the generator and file format version. Data : This section shows the information available from reading the whole file. It is only shown if the **\--extended/-e** option was used. It shows the actual bounding box calculated from the nodes in the file, the first and last timestamp of all objects in the file, a CRC32 checksum of the data in the file, the number of changesets, nodes, ways, and relations found in the file, whether the objects in the file were ordered by type (nodes, then ways, then relations) and id, and whether there were multiple versions of the same object in the file (history files and change files can have that). See the [**osmium-sort**(1)](osmium-sort.html) man page for details of the expected ordering. Metadata : This section shows which metadata attributes are used in the file. It contains information which attributes are used by all objects in the file and which are only used by some objects. This section is only shown if the **\--extended/-e** option was used because the whole file has to be read. This commands reads its input file only once, ie. it can read from STDIN. # OPTIONS -c, \--crc : Calculate the CRC32. This is the default if you use the JSON output format. \--no-crc : Do not calculate the CRC32. This is the default unless you use the JSON output format. -e, \--extended : Read the complete file and show additional information. The default is to read only the header of the file. -g, \--get=VARIABLE : Get value of VARIABLE. Can not be used together with **\--json/-j**. -G, \--show-variables : Show a list of all variable names. -j, \--json : Output in JSON format. Can not be used together with **\--get/-g**. -t, \--object-type=TYPE : Read only objects of given type (*node*, *way*, *relation*, *changeset*). By default all types are read. This option can be given multiple times. This only takes effect if the **\--extended/-e** option is also used. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ # VARIABLES The following variables are available: file.name - STRING file.format - STRING: XML|PBF file.compression - STRING: none|bzip2|gzip file.size - INTEGER (always 0 when reading from STDIN) header.boxes - STRING (could be multiline) header.with_history - BOOL (yes|no) header.option.generator - STRING header.option.version - STRING header.option.pbf_dense_nodes - BOOL (yes|no) header.option.osmosis_replication_timestamp - STRING with TIMESTAMP header.option.osmosis_replication_sequence_number - INTEGER header.option.osmosis_replication_base_url - STRING data.bbox - BOX (in JSON as nested ARRAY with coordinates) data.timestamp.first - STRING with TIMESTAMP data.timestamp.last - STRING with TIMESTAMP data.objects_ordered - BOOL (yes|no) data.multiple_versions - STRING (yes|no|unknown) (in JSON as BOOL and missing if "unknown") data.crc32 - STRING with 8 hex digits data.count.nodes - INTEGER data.count.ways - INTEGER data.count.relations - INTEGER data.count.changesets - INTEGER data.minid.nodes - INTEGER data.minid.ways - INTEGER data.minid.relations - INTEGER data.minid.changesets - INTEGER data.maxid.nodes - INTEGER data.maxid.ways - INTEGER data.maxid.relations - INTEGER data.maxid.changesets - INTEGER data.buffers.count - INTEGER data.buffers.size - INTEGER data.buffers.capcity - INTEGER metadata.all_objects.version - BOOL (yes|no) metadata.all_objects.timestamp - BOOL (yes|no) metadata.all_objects.changeset - BOOL (yes|no) metadata.all_objects.uid - BOOL (yes|no) metadata.all_objects.user - BOOL (yes|no) metadata.some_objects.version - BOOL (yes|no) metadata.some_objects.timestamp - BOOL (yes|no) metadata.some_objects.changeset - BOOL (yes|no) metadata.some_objects.uid - BOOL (yes|no) metadata.some_objects.user - BOOL (yes|no) All timestamps are in the usual OSM ISO format `yy-mm-ddThh::mm::ssZ`. Boxes are in the format `(xmin, ymin, xmax, ymax)`. There are two variables for each metadata field. The `metadata.all_objects.*` variables are true if all objects in the file have the attribute. The `metadata.some_objects.*` variables are true if at least one object in the file has the attribute. Please note that objects last modified by anonymous users (until 2007) do not have `user` and `uid` attributes and can lead to wrong results. # DIAGNOSTICS **osmium fileinfo** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium fileinfo** does all its work on the fly and doesn't keep much data in main memory. # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-sort**(1)](osmium-sort.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-getid.md000066400000000000000000000122101474143067200175700ustar00rootroot00000000000000 # NAME osmium-getid - get objects from OSM file by ID # SYNOPSIS **osmium getid** \[*OPTIONS*\] *OSM-FILE* *ID*...\ **osmium getid** \[*OPTIONS*\] *OSM-FILE* -i *ID-FILE*\ **osmium getid** \[*OPTIONS*\] *OSM-FILE* -I *ID-OSM-FILE* # DESCRIPTION Get objects with the given IDs from the input and write them to the output. IDs can be given on the command line (first case in synopsis), or read from text files with one ID per line (second case in synopsis), or read from OSM files (third cases in synopsis). A mixture of these cases is also allowed. All objects with these IDs will be read from *OSM-FILE* and written to the output. If the option **\--add-referenced/-r** is used all objects referenced from those objects will also be added to the output. Objects will be written out in the order they are found in the *OSM-FILE*. If the option **\--add-referenced/-r** is *not* used, the input file is read only once, if it is used, the input file will possibly be read up to three times. On the command line or in the ID file, the IDs have the form: *TYPE-LETTER* *NUMBER*. The type letter is 'n' for nodes, 'w' for ways, and 'r' for relations. If there is no type letter, 'n' for nodes is assumed (or whatever the **\--default-type** option says). So "n13 w22 17 r21" will match the nodes 13 and 17, the way 22 and the relation 21. The order in which the IDs appear does not matter. Identical IDs can appear multiple times on the command line or in the ID file(s). On the command line, the list of IDs can be in separate arguments or in a single argument separated by spaces, tabs, commas (,), semicolons (;), forward slashes (/) or pipe characters (|). In an ID file (option **\--id-file/-i**) each line must start with an ID in the format described above. Leading space characters in the line are ignored. Lines can optionally contain a space character or a hash sign ('#') after the ID. Any characters after that are ignored. (This also allows files in OPL format to be read.) Empty lines are ignored. Note that all objects will be taken from the *OSM-FILE*, the *ID-OSM-FILE* is only used to detect which objects to get. This might matter if there are different object versions in the different files. The *OSM-FILE* can not be a history file unless the **\--with-history/-H** option is used. Then all versions of the objects will be copied to the output. If referenced objects are missing from the input file, the type and IDs of those objects is written out to STDERR at the end of the program unless the **\--with-history/-H** option was given. This command will not work with negative IDs. # OPTIONS \--default-type=TYPE : Use TYPE ('node', 'way', or 'relation') for IDs without a type prefix (default: 'node'). It is also allowed to just use the first character of the type here. -H, \--with-history : Make this program work on history files. This is only needed when using the **-r** option. -i, \--id-file[=FILE] : Read IDs from text file instead of from the command line. Use the special name "-" to read from *STDIN*. Each line of the file must start with an ID in the format described above. Lines can optionally contain a space character or a hash sign ('#') after the ID. This character and all following characters are ignored. (This allows files in OPL format to be read.) Empty lines are also ignored. This option can be used multiple times. -I, \--id-osm-file=OSMFILE : Like **\--id-file/-i** but get the IDs from an OSM file. This option can be used multiple times. -r, \--add-referenced : Recursively find all objects referenced by the objects of the given IDs and include them in the output. This only works correctly on non-history files unless the `-H` option is also used. -t, \--remove-tags : Remove tags from objects that are not explicitly requested but are only included to complete references (nodes in ways and members of relations). If an object is both requested and used as a reference it will keep its tags. You also need **\--add-referenced/-r** for this to make sense. \--verbose-ids : Also print all requested and missing IDs. This is usually disabled, because the lists can get quite long. (This option implies **\--verbose**.) @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium getid** exits with exit code 0 ~ if all IDs were found 1 ~ if there was an error processing the data or not all IDs were found, (this is only detected if the **\--with-history/-H** option was not used), 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium getid** does all its work on the fly and only keeps a table of all IDs it needs in main memory. # EXAMPLES Output nodes 17 and 1234, way 42, and relation 111 to STDOUT in OPL format: osmium getid -f opl planet.osm.pbf n1234 w42 n17 r111 # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-getparents**(1)](osmium-getparents.html), [**osmium-removeid**(1)](osmium-removeid.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-getparents.md000066400000000000000000000107071474143067200206610ustar00rootroot00000000000000 # NAME osmium-getparents - get parents of objects from OSM file # SYNOPSIS **osmium getparents** \[*OPTIONS*\] *OSM-FILE* *ID*...\ **osmium getparents** \[*OPTIONS*\] *OSM-FILE* -i *ID-FILE*\ **osmium getparents** \[*OPTIONS*\] *OSM-FILE* -I *ID-OSM-FILE* # DESCRIPTION Get objects referencing the objects with the specified IDs from the input and write them to the output. So this will get ways referencing any of the specified node IDs and relations referencing any specified node, way, or relation IDs. Only one level of indirection is resolved, so no relations of relations are found and no relations referencing ways referencing the specified node IDs. IDs can be specified on the command line (first case in synopsis), or read from text files with one ID per line (second case in synopsis), or read from OSM files (third cases in synopsis). A mixture of these cases is also allowed. All objects with these IDs will be read from *OSM-FILE* and written to the output. If the option **\--add-self/-s** is specified, the objects with the specified IDs themselves will also be added to the output. Objects will be written out in the order they are found in the *OSM-FILE*. The input file is read only once. On the command line or in the ID file, the IDs have the form: *TYPE-LETTER* *NUMBER*. The type letter is 'n' for nodes, 'w' for ways, and 'r' for relations. If there is no type letter, 'n' for nodes is assumed (or whatever the **\--default-type** option says). So "n13 w22 17 r21" will match the nodes 13 and 17, the way 22 and the relation 21. The order in which the IDs appear does not matter. Identical IDs can appear multiple times on the command line or in the ID file(s). On the command line, the list of IDs can be in separate arguments or in a single argument separated by spaces, tabs, commas (,), semicolons (;), forward slashes (/) or pipe characters (|). In an ID file (option **\--id-file/-i**) each line must start with an ID in the format described above. Leading space characters in the line are ignored. Lines can optionally contain a space character or a hash sign ('#') after the ID. Any characters after that are ignored. (This also allows files in OPL format to be read.) Empty lines are ignored. Note that all objects will be taken from the *OSM-FILE*, the *ID-OSM-FILE* is only used to detect which objects to get. This might matter if there are different object versions in the different files. The *OSM-FILE* can be a history file, then all matching versions of the objects will be copied to the output. This command will not work with negative IDs. # OPTIONS \--default-type=TYPE : Use TYPE ('node', 'way', or 'relation') for IDs without a type prefix (default: 'node'). It is also allowed to just use the first character of the type here. -i, \--id-file[=FILE] : Read IDs from text file instead of from the command line. Use the special name "-" to read from *STDIN*. Each line of the file must start with an ID in the format described above. Lines can optionally contain a space character or a hash sign ('#') after the ID. This character and all following characters are ignored. (This allows files in OPL format to be read.) Empty lines are also ignored. This option can be used multiple times. -I, \--id-osm-file=OSMFILE : Like **-i** but get the IDs from an OSM file. This option can be used multiple times. -s, \--add-self : Also add all objects with the specified IDs to the output. \--verbose-ids : Also print all requested IDs. This is usually disabled, because the lists can get quite long. (This option implies **\--verbose**.) @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium getparents** exits with exit code 0 ~ if there was no error. 1 ~ if there was an error processing the data. 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium getparents** does all its work on the fly and only keeps a table of all IDs it needs in main memory. # EXAMPLES Output all ways referencing nodes 17 or 1234, and all relations with nodes 17 or 1234, or way 42, or relation 111 as members to STDOUT in OPL format: osmium getparents -f opl planet.osm.pbf n1234 w42 n17 r111 # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-getid**(1)](osmium-getid.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-index-types.md000066400000000000000000000050061474143067200207520ustar00rootroot00000000000000 # NAME osmium-index-types - Index types used to store node locations # DESCRIPTION The **osmium add-locations-to-ways** and **osmium export** commands have to keep an index of the node locations in memory or in a temporary file on disk while doing their work. There are several different ways this can be done which have different advantages and disadvantages. Use the **\--show-index-types/-I** option on these commands to show all available index types. It depends on your operating system which index types are available. Use the **\--index-type/-i** option on these commands to set the index type to be used. The default index type is `flex_mem` which will keep all data in memory and works for small extracts as well as the whole planet file. It is the right choice for almost all use cases if you have enough memory to keep the whole index in memory. For the **osmium export** command, the special type `none` is used when reading from files with the node locations on the ways. (See [**osmium-add-node-locations-to-ways**(1)](osmium-add-node-locations-to-ways.html) for how to get a file like this.) You can use one of the file-based indexes for the node location store to minimize memory use, but performance will suffer. In this case use `sparse_file_array` if you have a small or medium sized extract and `dense_file_array` if you are working with a full planet or a really large extract. When using the file-based index types (`*_file_array`), add the filename you want to use for the index after a comma to the index types like so: `... -i dense_file_array,index.dat ...` # MEMORY USE It depends on the index type used how much memory is needed: * For `sparse_*_array` types 16 bytes per node in the input file are used. * For `dense_*_array` types 8 bytes times the largest node ID in the input file are used. The `*_mem_*` types use potentially up to twice this amount. The `*mem*` and `*mmap*` types store the data in memory, the `*file*` types in a file on disk. The `flex_mem` type automatically switches between something similar to `sparse_mmap_array` for smaller extracts and `dense_mmap_array` for larger extracts or the whole planet file. If you specify the **\--verbose/-v** option, Osmium will display how much memory was used for the index. # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-add-locations-to-ways**(1)](osmium-add-locations-to-ways.html), [**osmium-export**(1)](osmium-export.html) * [Osmium website](https://osmcode.org/osmium-tool/) * [Index types](https://osmcode.org/osmium-concepts/#indexes) osmium-tool-1.17.0/man/osmium-merge-changes.md000066400000000000000000000042011474143067200212020ustar00rootroot00000000000000 # NAME osmium-merge-changes - merge several OSM change files into one # SYNOPSIS **osmium merge-changes** \[*OPTIONS*\] *OSM-CHANGE-FILE*... # DESCRIPTION Merges the content of all change files given on the command line into one large change file. Objects are sorted by type, ID, version, and timestamp so it doesn't matter in what order the change files are given or in what order they contain the data. (If you are using change files of extracts this is not necessarily true and you must specify the change files on the command line in the correct order from oldest to newest. This is because change files from extracts can contain multiple different object versions with the same version and timestamp!) This commands reads its input file(s) only once and writes its output file in one go so it can be streamed, ie. it can read from STDIN and write to STDOUT. # OPTIONS -s, \--simplify : Only write the last version of any object to the output. For an object created in one of the change files and removed in a later one, the deleted version of the object will still appear because it is the latest version. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium merge-changes** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium merge-changes** keeps the contents of all the change files in main memory. This will take roughly 10 times as much memory as the files take on disk in *.osm.bz2* format. # EXAMPLES Merge all changes in *changes* directory into *all.osc.gz*: osmium merge-changes -o all.osc.gz changes/*.gz Because `osmium merge-changes` sorts its input, you can also use it to sort just a single change file: osmium merge-changes unsorted.osc.gz -o sorted.osc.gz # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html), [**osmium-merge**(1)](osmium-merge.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-merge.md000066400000000000000000000043601474143067200176020ustar00rootroot00000000000000 # NAME osmium-merge - merge several sorted OSM files into one # SYNOPSIS **osmium merge** \[*OPTIONS*\] *OSM-FILE*... # DESCRIPTION Merges the content of all OSM files given on the command line into one large OSM file. Objects in all files must be sorted by type, ID, and version. The results will also be sorted in the same way. Objects that appear in multiple input files will only be in the output once. If there is only a single input file, its contents will be copied to the output. If there are different versions of the same object in the input files, all versions will appear in the output. So this command will work fine with history files as input creating a new history file. Do not use this command to merge non-history files with data from different points in time. It will not work correctly. If you have objects with the same type, id, and version but different other data, the result of this command is undefined. This situation can never happen in correct OSM files, but sometimes buggy programs can generate data like this. Osmium doesn't make any promises on what the result of the command is if the input data is not correct. This commands reads its input file(s) only once and writes its output file in one go so it can be streamed, ie. it can read from STDIN and write to STDOUT. # OPTIONS -H, \--with-history : Do not warn when there are multiple versions of the same object in the input files. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium merge** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium merge** doesn't keep a lot of data in memory, but if you are merging many files, the buffers might take a noticeable amount of memory. # EXAMPLES Merge several extracts into one: osmium merge washington.pbf oregon.pbf california.pbf -o westcoast.pbf # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html), [**osmium-merge-changes**(1)](osmium-merge-changes.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-output-headers.md000066400000000000000000000033351474143067200214550ustar00rootroot00000000000000 # NAME osmium-output-headers - Header options that can be set on output files # DESCRIPTION Most osmium commands that write OSM files can set values in the file header of the OSM file using the **\--output-header** option. The format generally is **\--output-header=OPTION=VALUE**. For some commands you can use the special format **\--output-header=OPTION!** (ie. an exclamation mark after the *OPTION* and no value set) to set the value to the same as in the input file. See the individual command man pages for where this is allowed. # HEADER OPTIONS `generator` : Set the "generator program" value. Default is "osmium/VERSION". Can also be set using the **\--generator** option. (XML and PBF files only.) `xml_josm_upload` : Value of the upload attribute on the osm XML element (true or false) for use in JOSM. (XML files only.) `osmosis_replication_timestamp` : Timestamp used in replication (PBF files only). `osmosis_replication_sequence_number` : Sequence number used in replication (PBF files only). `osmosis_replication_base_url` : Base URL for change files used in replication (PBF files only). `sorting` : Set the **Sort.Type_then_ID** property in the PBF header if set to **Type_then_ID**. Other values are currently not supported. (PBF files only). Note that this only sets the header option, it does not actually sort the file! Use **osmium sort** for that. # EXAMPLES Copy the file in.osm.pbf to out.osm.pbf setting the generator to **myscript**: osmium cat --output-header=generator=myscript -o out.osm.pbf in.osm.pbf # SEE ALSO * [**osmium**(1)](osmium.html) * [Osmium website](https://osmcode.org/osmium-tool/) * [Replication headers](https://wiki.openstreetmap.org/wiki/PBF_Format) osmium-tool-1.17.0/man/osmium-query-locations-index.md000066400000000000000000000040161474143067200227440ustar00rootroot00000000000000 # NAME osmium-query-locations-index - query node locations index # SYNOPSIS **osmium query-locations-index** -i INDEX-FILE \[*OPTIONS*\] *NODE-ID*\ **osmium query-locations-index** -i INDEX-FILE \[*OPTIONS*\] \--dump # DESCRIPTION Get the location of a node from an index created with **osmium create-locations-index** or dump the whole index into an OSM file. The index file format is compatible to the one created by "osmium add-location-to-ways -i dense_file_array,INDEX-FILE" and to the flatnode store created by osm2pgsql. This command will not work with negative node IDs. Note that when the **\--dump** option is used, metadata (like version, timestamp, etc.) is not written to the output file because it is all empty anyway. Use the **\--output-format/-f** option with `add_metadata=...` to overwrite this. # OPTIONS \--dump : Dump all node locations to an OSM file. Use the **\--output/-o** and **\--output-format/-f** options to set the file format to be used. Default is STDOUT and the OPL format, respectively. -i, \--index-file=FILENAME : The name of the index file. @MAN_COMMON_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium query-locations-index** exits with exit code 0 ~ if everything went alright and the node location was found, 1 ~ if the node location was not found, 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium query-locations-index** will not use a lot of memory. # EXAMPLES Get location of node 1234 from locations.idx: osmium query-locations-index -i locations.idx 1234 Dump contents of locations.idx into an OPL file: osmium query-locations-index -i locations.idx --dump -o nodes.opl # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-create-locations-index**(1)](osmium-create-locations-index.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) * [osm2pgsql](https://wiki.openstreetmap.org/wiki/Osm2pgsql) osmium-tool-1.17.0/man/osmium-removeid.md000066400000000000000000000071661474143067200203240ustar00rootroot00000000000000 # NAME osmium-removeid - remove objects from OSM file by ID # SYNOPSIS **osmium removeid** \[*OPTIONS*\] *OSM-FILE* *ID*...\ **osmium removeid** \[*OPTIONS*\] *OSM-FILE* -i *ID-FILE*\ **osmium removeid** \[*OPTIONS*\] *OSM-FILE* -I *ID-OSM-FILE* # DESCRIPTION Copy input file to output removing objects with the specified IDs. IDs can be given on the command line (first case in synopsis), or read from text files with one ID per line (second case in synopsis), or read from OSM files (third cases in synopsis). A mixture of these cases is also allowed. Objects will be written out in the order they are found in the *OSM-FILE*. The input file is only read once, reading from *STDIN* is possible by using the special file name '-'. On the command line or in the ID file, the IDs have the form: *TYPE-LETTER* *NUMBER*. The type letter is 'n' for nodes, 'w' for ways, and 'r' for relations. If there is no type letter, 'n' for nodes is assumed (or whatever the **\--default-type** option says). So "n13 w22 17 r21" will match the nodes 13 and 17, the way 22 and the relation 21. The order in which the IDs appear does not matter. Identical IDs can appear multiple times on the command line or in the ID file(s). On the command line, the list of IDs can be in separate arguments or in a single argument separated by spaces, tabs, commas (,), semicolons (;), forward slashes (/) or pipe characters (|). In an ID file (option **\--id-file/-i**) each line must start with an ID in the format described above. Leading space characters in the line are ignored. Lines can optionally contain a space character or a hash sign ('#') after the ID. Any characters after that are ignored. (This also allows files in OPL format to be read.) Empty lines are ignored. Note that all objects will be taken from the *OSM-FILE*, the *ID-OSM-FILE* is only used to detect which objects to remove. The *OSM-FILE* can be a history file in which case all versions of the objects with the specified IDs will be removed. This command will not work with negative IDs. # OPTIONS \--default-type=TYPE : Use TYPE ('node', 'way', or 'relation') for IDs without a type prefix (default: 'node'). It is also allowed to just use the first character of the type here. -i, \--id-file[=FILE] : Read IDs from text file instead of from the command line. Use the special name "-" to read from *STDIN*. Each line of the file must start with an ID in the format described above. Lines can optionally contain a space character or a hash sign ('#') after the ID. This character and all following characters are ignored. (This allows files in OPL format to be read.) Empty lines are also ignored. This option can be used multiple times. -I, \--id-osm-file=OSMFILE : Like **\--id-file/-i** but get the IDs from an OSM file. This option can be used multiple times. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium removeid** exits with exit code 0 ~ if nothing went wrong 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium removeid** does all its work on the fly and only keeps a table of all IDs it needs in main memory. # EXAMPLES Output all nodes except nodes 17 and 1234, all ways except way 42, and all relations except relation 111 to STDOUT in OPL format: osmium removeid -f opl planet.osm.pbf n1234 w42 n17 r111 # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-getid**(1)](osmium-getid.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-renumber.md000066400000000000000000000121761474143067200203260ustar00rootroot00000000000000 # NAME osmium-renumber - renumber object IDs # SYNOPSIS **osmium renumber** \[*OPTIONS*\] *OSM-DATA-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. All objects which appear in the source file will be in the same order in the output file. IDs of objects which are not in the file but referenced from ways or relations are not guaranteed to be in the correct order. This command expects the input file to be ordered in the usual way: First nodes in order of ID, then ways in order of ID, then relations in order of ID. Negative IDs are allowed, they must be ordered before the positive IDs. See the [**osmium-sort**(1)](osmium-sort.html) man page for details of the ordering. The input file will be read twice, so it will not work with STDIN. If you are not renumbering relations (ie. if the option **\--object-type/-t** is used with nodes and/or ways but not relations) the input file will only be read once, so in that case it will work with STDIN. To renumber the IDs in several files, call **osmium renumber** for each file and specify the **\--index-directory/-i** option each time. See the **INDEX FILES** section for more details. 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 -i, \--index-directory=DIR : Directory where the index files for mapping between old and news IDs are read from and written to, respectively. Use this if you want to map IDs in several OSM files. Without this option, the indexes are not read from or written to disk. The directory must exist. Use '.' for the current directory. The files written will be named `nodes.idx`, `ways.idx`, and `relations.idx`. See also the **INDEX FILES** section below. \--show-index=TYPE : Print the content of the index for TYPE (node, way, or relation) on STDOUT. Each line contains the old ID, a space character and then the new ID. Any other options (except **\--index-directory/-i**) are ignored if this option is used. -s, \--start-id=FIRST_ID or FIRST_NODE_ID,FIRST_WAY_ID,FIRST_RELATION_ID : Set the first ID that should be used. If the ID is positive, IDs are counted upwards, if the ID is negative, they are counted downwards. This can be set to either a single ID which is used for all object types or a comma-separated list of three IDs used for the first node, way, and relation, respectively. If this is not set, IDs for all object types start at 1. -t, \--object-type=TYPE : Renumber only objects of given type (*node*, *way*, or *relation*). By default all objects of all types are renumbered. This option can be given multiple times. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # INDEX FILES When the **\--index-directory/-i** option is specified, index files named `nodes.idx`, `ways.idx`, and `relations.idx` are read from and written to the given directory together with a file called `start_ids` that contains the start IDs set with **\--start-id/-s**. This can be used to force consistent mapping over several invocations of `osmium renumber`, for instance when you want to remap an OSM data file and a corresponding OSM change file. The index files are in binary format, but you can print the indexes in text format using the **\--show-index** option: osmium renumber -i idxdir --show-index node >nodes-index.txt osmium renumber -i idxdir --show-index way >ways-index.txt osmium renumber -i idxdir --show-index relation >relations-index.txt # DIAGNOSTICS **osmium renumber** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium renumber** needs quite a bit of main memory to keep the mapping between old and new IDs. It is intended for small to medium sized extracts. You will need more than 32 GB RAM to run this on a full planet. Memory use is at least 8 bytes per node, way, and relation ID in the input file. # EXAMPLES Renumber a PBF file and output to a compressed XML file: osmium renumber -o ch.osm.bz2 germany.osm.pbf Renumbering the about 3.3 GB Germany PBF file currently (February 2020) takes about three minutes and needs about 7 GB RAM. Renumber a PBF file starting the node IDs at 1 (and counting upwards), the way IDs at 100 and the relation IDs at -200 (and counting downwards. osmium renumber -o renumbered.osm.pbf -s 1,100,-200 athens.osm.pbf Renumber an OSM file storing the indexes on disk: osmium renumber -i. -o renumbered.osm data.osm then rewrite a change file, too: osmium renumber -i. -o renumbered.osc changes.osc # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html), [**osmium-sort**(1)](osmium-sort.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-show.md000066400000000000000000000042161474143067200174630ustar00rootroot00000000000000 # NAME osmium-show - show OSM file # SYNOPSIS **osmium show** \[*OPTIONS*\] *OSM-FILE* # DESCRIPTION Show the contents of the *OSM-FILE* on STDOUT, usually in a pager. The output format can be set using the **output-format/-f** option, its shortcuts **-d** (debug format with colors), **-o** (OPL), or **-x** (XML), or the `OSMIUM_SHOW_FORMAT` environment variable. The pager can be set with the `OSMIUM_PAGER` or the `PAGER` environment variable. If neither is set, the default `less` is used unless the option **\--no-pager** is used. If the pager variables are set to an empty value or to `cat`, no pager is used. On Windows there is no pager support at all. This commands reads its input file only once, ie. it can read from STDIN. # 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. \--no-pager : Disable pager. -d, \--format-debug : Same as `-f debug,color=true`. -o, \--format-opl : Same as `-f opl`. -x, \--format-xml : Same as `-f xml`. -t, \--object-type=TYPE : Read only objects of given type (*node*, *way*, *relation*, *changeset*). By default all types are read. This option can be given multiple times. # COMMON OPTIONS -h, \--help : Show usage help. @MAN_INPUT_OPTIONS@ # DIAGNOSTICS **osmium show** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium show** does all its work on the fly and doesn't keep much data in main memory. # EXAMPLES Show an OSM file using the default pager and default format: osmium show norway.osm.pbf Use `more` as a pager and only show relations: OSMIUM_PAGER=more osmium show -t r norway.osm.pbf Show using XML format: osmium show -x norway.osm.pbf # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-cat**(1)](osmium-cat.html), [**osmium-file-formats**(5)](osmium-file-formats.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-sort.md000066400000000000000000000045331474143067200174740ustar00rootroot00000000000000 # NAME osmium-sort - sort OSM files # SYNOPSIS **osmium sort** \[*OPTIONS*\] *OSM-FILE*... # DESCRIPTION Combines and sorts the content of all input files given on the command line. Objects are sorted by type, ID, and version. IDs are sorted negative IDs first, then positive IDs, both ordered by their absolute values. So the sort order for types and IDs is: node -1, node -2, ..., node 1, node 2, ..., way -1, way -2, ..., way 1, way 2, ..., relation -1, relation -2, ..., relation 1, relation 2, ... If there are several objects of the same type and with the same ID they are ordered by ascending version. If there are several objects of the same type and with the same ID and version the sort order is unspecified. Duplicate objects will not be removed. This command works with normal OSM data files, history files, and change files. This commands reads its input file(s) only once and writes its output file in one go so it can be streamed, ie. it can read from STDIN and write to STDOUT. (Unless the *multipass* strategy is used.) # OPTIONS -s, \--strategy=STRATEGY : Sorting strategy. The "simple" strategy reads all input files into memory, does the sorting and writes everything out. The "multipass" strategy reads the input files in three passes, one for nodes, one for ways, and one for relations. After reading all objects of each type, they are sorted and written out. This is a bit slower than the "simple" strategy, but uses less memory. The "multipass" strategy doesn't work when reading from STDIN. Default: "simple". @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium sort** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium sort** keeps the contents of all the input files in main memory. This will take roughly 10 times as much memory as the files take on disk in *.osm.bz2* or *osm.pbf* format. # EXAMPLES Sort *in.osm.bz2* and write out to *sorted.osm.pbf*: osmium sort -o sorted.osm.pbf in.osm.bz2 # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-tags-count.md000066400000000000000000000114601474143067200205660ustar00rootroot00000000000000 # NAME osmium-tags-count - count keys/tags # SYNOPSIS **osmium tags-count** \[*OPTIONS*\] *OSM-FILE* [*TAG-EXPRESSION*...]\ **osmium tags-count** \[*OPTIONS*\] \--expressions=*FILE* *OSM-FILE* # DESCRIPTION Count how often keys or tags appear in the input file. If the only command line argument is an OSM file, all keys in this file are counted. If there are one or more tag expressions on the command line, only the keys and tags matching those expressions are counted. See the **TAG EXPRESSIONS** section for a description of the expression format. The output has one line per key/tag found. Each line contains the count, the tag key, and the tag value (if matching tags) separated by TAB characters. Tag keys and values are surrounded by double quotes. Any double quotes in the keys and values are doubled. # OPTIONS -e FILE, \--expressions=FILE : Read expressions from the specified file, one per line. Empty lines are ignored. Everything after the comment character (#) is also ignored. See the **TAG EXPRESSIONS** section for further details. -m COUNT, \--min-count=COUNT : The minimum count that should be in the output. Used when you are only interested in common keys/tags. -M COUNT, \--max-count=COUNT : The maximum count that should be in the output. Used when you are only interested in rare keys/tags. -s SORT, \--sort=SORT : Sort order. Order by "count-asc", "count-desc", "name-asc", or "name-desc". Default is "count-desc". -t, \--object-type=TYPE : Read only objects of given type (*node*, *way*, *relation*). By default all types are read. This option can be given multiple times. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ # OUTPUT OPTIONS -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. # TAG EXPRESSIONS A filter expression specifies one or more keys and/or tags that should be counted in the data. Some examples: amenity : Matches the key "amenity". highway=primary : Matches the tag with key "highway" and value "primary". highway!=primary : Matches any tag with key "highway" and a value other than "primary". type=multipolygon,boundary : Matches any tag with key "type" and value "multipolygon" or "boundary". name,name:de=Kastanienallee,Kastanienstrasse : Matches any tag with the key "name" or "name:de" with the value "Kastanienallee" or "Kastanienstrasse". addr:\* : Matches tags with keys starting with "addr:" name=\*Paris : Matches all tags with key "name" and a value that contains the word "Paris". If there is no equal sign ("=") in the expression only keys are matched and values can be anything. If there is an equal sign ("=") in the expression, the key is to the left and the value to the right. An exclamation sign ("!") before the equal sign means: A tag with that key, but not the value(s) to the right of the equal sign. A leading or trailing asterisk ("\*") can be used for substring or prefix matching, respectively. Commas (",") can be used to separate several keys or values. All filter expressions are case-sensitive. There is no way to escape the special characters such as "=", "\*" and ",". You can not mix comma-expressions and "\*"-expressions. The filter expressions specified in a file and/or on the command line are matched in the order they are given. To achieve best performance, put expressions expected to match more often first. # DIAGNOSTICS **osmium tags-count** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium tags-count** keeps all counters in memory. For a large OSM file and unrestricted keys or, worse, tags, this can use quite a lot of memory. (Counting all tags on a full planet file will use about 16 GByte RAM.) Use the filter expressions to restrict the counting to the keys or tags you are actually interested in. # EXAMPLES Count all keys in Spain and display most common keys first: osmium tags-count spain.osm.pbf Count all building keys in Madrid: osmium tags-count madrid.osm.pbf building Count all building tags on ways in Madrid, order by name: osmium tags-count -t way --sort=name-asc madrid.osm.pbf 'building=*' Count all relation types in Sevilla that appear at least 100 times: osmium tags-count -t relation -m 100 sevilla.osm.pbf 'type=*' Count all tags in the input file. Note that this might need quite a lot of memory! osmium tags-count input.osm.pbf '*=*' # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html) * [Osmium website](https://osmcode.org/osmium-tool/) * [Taginfo](https://github.com/taginfo/taginfo/) osmium-tool-1.17.0/man/osmium-tags-filter.md000066400000000000000000000135571474143067200207340ustar00rootroot00000000000000 # NAME osmium-tags-filter - filter objects matching specified keys/tags # SYNOPSIS **osmium tags-filter** \[*OPTIONS*\] *OSM-FILE* *FILTER-EXPRESSION*...\ **osmium tags-filter** \[*OPTIONS*\] \--expressions=*FILE* *OSM-FILE* # DESCRIPTION Get objects matching at least one of the specified expressions from the input and write them to the output. Expressions can either be specified on the command line or in an expressions file. See the **FILTER EXPRESSIONS** section for a description of the filter expression format. All objects matching the expressions will be read from *OSM-FILE* and written to the output. All objects referenced from those objects will also be added to the output unless the option **\--omit-referenced/-R** is used. This applies to nodes referenced in ways and members referenced in relations. If the option **\--omit-referenced/-R** is used, the input file is read only once, otherwise the input file will possibly be read up to three times. Objects will be written out in the order they are found in the *OSM-FILE*. The command will only work correctly on history files if the **\--omit-referenced/-R** option is used. The command can not be used on change files. # OPTIONS -e FILE, \--expressions=FILE : Read expressions from the specified file, one per line. Empty lines are ignored. Everything after the comment character (#) is also ignored. See the **FILTER EXPRESSIONS** section for further details. -i, \--invert-match : Invert the sense of matching. Exclude all objects with matching tags. -R, \--omit-referenced : Omit the nodes referenced from matching ways and members referenced from matching relations. -t, \--remove-tags : Remove tags from objects that are not matching the filter expression but are included to complete references (nodes in ways and members of relations). If an object is both matching the filter and used as a reference it will keep its tags. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # FILTER EXPRESSIONS A filter expression specifies a tag or tags that should be found in the data and the type of object (node, way, or relation) that should be matched. The object type(s) comes first, then a slash (/) and then the rest of the expression. Object types are specified as 'n' (for nodes), 'w' (for ways), 'r' (for relations), and 'a' (for areas - closed ways with 4 or more nodes and relations with `type=multipolygon` or `type=boundary` tag). Any combination of them can be used. If the object type is not specified, the expression matches all object types. Some examples: n/amenity : Matches all nodes with the key "amenity". nw/highway : Matches all nodes or ways with the key "highway". /note : Matches objects of any type with the key "note". note : Matches objects of any type with the key "note". w/highway=primary : Matches all ways with the key "highway" and value "primary". w/highway!=primary : Matches all ways with the key "highway" and a value other than "primary". r/type=multipolygon,boundary : Matches all relations with key "type" and value "multipolygon" or "boundary". w/name,name:de=Kastanienallee,Kastanienstrasse : Matches any way with a "name" or "name:de" tag with the value "Kastanienallee" or "Kastanienstrasse". n/addr:\* : Matches all nodes with any key starting with "addr:" n/name=\*Paris : Matches all nodes with a name that contains the word "Paris". a/building : Matches any closed ways with 4 or more nodes or relations tagged "building". Relations must also have a tag "type=multipolygon" or "type=boundary". If there is no equal sign ("=") in the expression only keys are matched and values can be anything. If there is an equal sign ("=") in the expression, the key is to the left and the value to the right. An exclamation sign ("!") before the equal sign means: A tag with that key, but not the value(s) to the right of the equal sign. A leading or trailing asterisk ("\*") can be used for substring or prefix matching, respectively. Commas (",") can be used to separate several keys or values. All filter expressions are case-sensitive. There is no way to escape the special characters such as "=", "\*" and ",". You can not mix comma-expressions and "\*"-expressions. The filter expressions specified in a file and/or on the command line are matched in the order they are given. To achieve best performance, put expressions expected to match more often first. Area matches (with leading "a/") do not check whether the matched object is a valid (multi)polygon, they only check whether an object might possibly be turned into a (multi)polygon. This is the case for all closed ways (where the first and last node are the same) with 4 or more nodes and for all relations that have an additional "type=multipolygon" or "type=boundary" tag. # DIAGNOSTICS **osmium tags-filter** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium tags-filter** does all its work on the fly and only keeps tables of object IDs it needs in main memory. If the **\--omit-referenced/-R** option is used, no IDs are kept in memory. # EXAMPLES Get all amenity nodes from the Berlin PBF file: osmium tags-filter -o amenties.osm.pbf berlin.osm.pbf n/amenity Get all objects (nodes, ways, or relations) with a `note` tag: osmium tags-filter -R -o notes.osm.pbf berlin.osm.pbf note Get all nodes and ways with a `highway` tag and all relations tagged with `type=restriction` plus all referenced objects: osmium tags-filter -o filtered.osm.pbf planet.osm.pbf \ nw/highway r/type=restriction # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium-time-filter.md000066400000000000000000000036261474143067200207300ustar00rootroot00000000000000 # NAME osmium-time-filter - filter OSM data by time from a history file # SYNOPSIS **osmium time-filter** \[*OPTIONS*\] *OSM-HISTORY-FILE* \[*TIME*\]\ **osmium time-filter** \[*OPTIONS*\] *OSM-HISTORY-FILE* *FROM-TIME* *TO-TIME* # DESCRIPTION Copy all objects that were valid at the given *TIME* or in the time period between *FROM-TIME* (inclusive) and *TO-TIME* (not inclusive) from the input file into the output file. If no time is given, the current time is used. Usually the *INPUT-FILE* will be an OSM data file with history. If both *FROM-TIME* and *TO-TIME* are given, the result will also have history data, it will also include deleted versions of objects. If only a single point in time was given, the result will be a normal OSM file without history containing no deleted objects. The format for the timestamps is "yyyy-mm-ddThh:mm:ssZ". This commands reads its input file only once and writes its output file in one go so it can be streamed, ie. it can read from STDIN and write to STDOUT. @MAN_COMMON_OPTIONS@ @MAN_PROGRESS_OPTIONS@ @MAN_INPUT_OPTIONS@ @MAN_OUTPUT_OPTIONS@ # DIAGNOSTICS **osmium time-filter** exits with exit code 0 ~ if everything went alright, 1 ~ if there was an error processing the data, or 2 ~ if there was a problem with the command line arguments. # MEMORY USAGE **osmium time-filter** does all its work on the fly and doesn't keep much data in main memory. # EXAMPLES Extract current planet file from history planet: osmium time-filter -o planet.osm.pbf history-planet.osh.pbf Extract planet data how it appeared on January 1 2008 from history planet: osmium time-filter -o planet-20080101.osm.pbf history-planet.osh.pbf 2008-01-01T00:00:00Z # SEE ALSO * [**osmium**(1)](osmium.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/osmium.md000066400000000000000000000077211474143067200165110ustar00rootroot00000000000000 # NAME osmium - multipurpose tool for working with OpenStreetMap data # SYNOPSIS **osmium** *COMMAND* \[*ARG*...\]\ **osmium** \--version # DESCRIPTION Multipurpose tool for working with OpenStreetMap data. Run **osmium help** *COMMAND* to get more information about a command. This will only work on Linux and OS/X systems and only if the `man` command is available and working correctly. # OPTIONS -h, \--help : Show usage and list of commands. \--version : Show program version. # COMMANDS add-locations-to-ways : add node locations to ways in OSM file apply-changes : apply OSM change file(s) to OSM data file cat : concatenate OSM files and convert to different formats changeset-filter : filter changesets from OSM changeset files check-refs : check referential integrity of OSM file derive-changes : create OSM change file from two OSM files diff : display differences between OSM files export : export OSM data extract : create geographical extracts from an OSM file fileinfo : show information about an OSM file getid : get objects from OSM file by ID getparents : get parents of objects from OSM file help : show help about commands merge : merge several OSM files into one merge-changes : merge several OSM change files into one removeid : remove OSM objects with specified IDs renumber : renumber object IDs show : show OSM file sort : sort OSM files tags-filter : filter OSM data based on tags time-filter : filter OSM data by time from a history file # COMMON OPTIONS Most commands support the following options: -h, \--help : Show short usage information. -v, \--verbose : Set verbose mode. The program will output information about what it is doing to STDERR. # MEMORY USAGE Osmium commands try to do their work as memory efficient as possible. But some osmium commands still need to load quite a bit of data into main memory. In some cases this means that only smaller datasets can be handled. Look into the man pages for the individual commands to learn more about their memory use. On most commands, if you use the **\--verbose/-v** option, osmium will print out the peak memory usage at the end. This is the actual amount of memory used including the program code itself, any needed libraries, and the data. (Printing of memory usage is currently only available on Linux systems.) If an osmium command exits with an "Out of memory" error, try running it with **\--verbose/-v** on smaller datasets to get an idea how much memory it needs. On Linux a program that uses a lot of memory can be killed by the kernel without the program being notified. If you see osmium dieing without any apparent reason, this might be the case. Search on the Internet for "OOM killer" to find out more about this. # SEE ALSO * [**osmium-add-locations-to-ways**(1)](osmium-add-locations-to-ways.html), [**osmium-apply-changes**(1)](osmium-apply-changes.html), [**osmium-cat**(1)](osmium-cat.html), [**osmium-changeset-filter**(1)](osmium-changeset-filter.html), [**osmium-check-refs**(1)](osmium-check-refs.html), [**osmium-derive-changes**(1)](osmium-derive-changes.html), [**osmium-diff**(1)](osmium-diff.html), [**osmium-export**(1)](osmium-export.html), [**osmium-extract**(1)](osmium-extract.html), [**osmium-fileinfo**(1)](osmium-fileinfo.html), [**osmium-getid**(1)](osmium-getid.html), [**osmium-getparents**(1)](osmium-getparents.html), [**osmium-merge**(1)](osmium-merge.html), [**osmium-merge-changes**(1)](osmium-merge-changes.html), [**osmium-renumber**(1)](osmium-renumber.html), [**osmium-show**(1)](osmium-show.html), [**osmium-sort**(1)](osmium-sort.html), [**osmium-tags-filter**(1)](osmium-tags-filter.html), [**osmium-time-filter**(1)](osmium-time-filter.html), [**osmium-file-formats**(5)](osmium-file-formats.html), [**osmium-index-types**(5)](osmium-index-types.html), [**osmium-output-headers**(5)](osmium-output-headers.html) * [Osmium website](https://osmcode.org/osmium-tool/) osmium-tool-1.17.0/man/output-options.md000066400000000000000000000022101474143067200202150ustar00rootroot00000000000000 # OUTPUT 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. \--fsync : Call fsync after writing the output file to force flushing buffers to disk. \--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=VALUE : Add output header option. This command line option can be used multiple times for different OPTIONs. See the *osmium-output-headers(5)* man page for a list of available header options. For some commands you can use the special format "OPTION!" (ie. an exclamation mark after the OPTION and no value set) to set the value to the same as in the input file. osmium-tool-1.17.0/man/progress-options.md000066400000000000000000000010261474143067200205250ustar00rootroot00000000000000 \--progress : Show progress bar. Usually a progress bar is only displayed if STDOUT and STDERR are detected to be TTY. With this option a progress bar is always shown. Note that a progress bar will never be shown when reading from STDIN or a pipe. \--no-progress : Do not show progress bar. Usually a progress bar is displayed if STDOUT and STDERR are detected to be a TTY. With this option the progress bar is suppressed. Note that a progress bar will never be shown when reading from STDIN or a pipe. osmium-tool-1.17.0/osmium-wrapper.in000077500000000000000000000007531474143067200174230ustar00rootroot00000000000000#!/bin/sh #----------------------------------------------------------------------------- # # This is a small wrapper for the osmium binary that is only used to call it # from the build directory, ie when it is not installed. It sets the MANPATH # so the help facility will work and then calls the osmium proper. # #----------------------------------------------------------------------------- export MANPATH=$MANPATH:@PROJECT_BINARY_DIR@/man: exec @PROJECT_BINARY_DIR@/src/osmium "$@" osmium-tool-1.17.0/scripts/000077500000000000000000000000001474143067200155635ustar00rootroot00000000000000osmium-tool-1.17.0/scripts/osm-history-splitter2osmium-extract-config.sh000077500000000000000000000012761474143067200265200ustar00rootroot00000000000000#!/bin/sh # # Convert a config file in the format for the osm-history-splitter into a # config file for the "osmium extract" command. # if [ -n "$1" ]; then exec <$1 fi echo '{' echo ' "extracts": [' while read output type region; do echo ' {' echo " \"output\": \"$output\"," if [ "$type" = "BBOX" ]; then echo " \"bbox\": [$region]" elif [ "$type" = "OSM" -o "$type" = "POLY" ]; then lctype=`echo $type | tr 'A-Z' 'a-z'` cat << __END__ "polygon": { "file_name": "$region", "file_type": "$lctype" } __END__ fi echo ' },' done echo ' ]' echo '}' osmium-tool-1.17.0/src/000077500000000000000000000000001474143067200146635ustar00rootroot00000000000000osmium-tool-1.17.0/src/CMakeLists.txt000066400000000000000000000007161474143067200174270ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool # #----------------------------------------------------------------------------- add_executable(osmium main.cpp commands.cpp ${PROJECT_BINARY_DIR}/src/version.cpp ${OSMIUM_SOURCE_FILES} ) target_link_libraries(osmium ${Boost_LIBRARIES} ${OSMIUM_LIBRARIES}) set_pthread_on_target(osmium) install(TARGETS osmium DESTINATION bin) osmium-tool-1.17.0/src/cmd.cpp000066400000000000000000000137651474143067200161460ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" #include "exception.hpp" #include #include #include #include #include #include #include #include #include #include po::options_description Command::add_common_options(const bool with_progress) { po::options_description options{"COMMON OPTIONS"}; auto opts = options.add_options() ("help,h", "Show usage help") ("verbose,v", "Set verbose mode") ; if (with_progress) { opts("progress", "Display progress bar") ("no-progress", "Suppress display of progress bar"); } return options; } bool Command::setup_common(const boost::program_options::variables_map& vm, const po::options_description& desc) { if (vm.count("help")) { std::cout << "Usage: " << synopsis() << "\n\n" << m_command_factory.get_description(name()) << "\n" << desc << "\nUse 'osmium help " << name() << "' to display the manual page.\n"; return false; } if (vm.count("verbose")) { m_vout.verbose(true); } return true; } void Command::setup_progress(const boost::program_options::variables_map& vm) { if (vm.count("progress") && vm.count("no-progress")) { throw argument_error{"Can not use --progress and --no-progress together."}; } if (vm.count("progress")) { m_display_progress = display_progress_type::always; } if (vm.count("no-progress")) { m_display_progress = display_progress_type::never; } } void Command::setup_object_type_nwrc(const boost::program_options::variables_map& vm) { if (vm.count("object-type")) { m_osm_entity_bits = osmium::osm_entity_bits::nothing; for (const auto& t : vm["object-type"].as>()) { if (t == "n" || t == "node") { m_osm_entity_bits |= osmium::osm_entity_bits::node; } else if (t == "w" || t == "way") { m_osm_entity_bits |= osmium::osm_entity_bits::way; } else if (t == "r" || t == "relation") { m_osm_entity_bits |= osmium::osm_entity_bits::relation; } else if (t == "c" || t == "changeset") { m_osm_entity_bits |= osmium::osm_entity_bits::changeset; } else { throw argument_error{std::string{"Unknown object type '"} + t + "' (Allowed are 'node', 'way', 'relation', and 'changeset')."}; } } } else { m_osm_entity_bits = osmium::osm_entity_bits::all; } } void Command::setup_object_type_nwr(const boost::program_options::variables_map& vm) { if (vm.count("object-type")) { m_osm_entity_bits = osmium::osm_entity_bits::nothing; for (const auto& t : vm["object-type"].as>()) { if (t == "n" || t == "node") { m_osm_entity_bits |= osmium::osm_entity_bits::node; } else if (t == "w" || t == "way") { m_osm_entity_bits |= osmium::osm_entity_bits::way; } else if (t == "r" || t == "relation") { m_osm_entity_bits |= osmium::osm_entity_bits::relation; } else { throw argument_error{std::string{"Unknown object type '"} + t + "' (Allowed are 'node', 'way', and 'relation')."}; } } } else { m_osm_entity_bits = osmium::osm_entity_bits::nwr; } } void Command::show_object_types(osmium::VerboseOutput& vout) { vout << " object types:"; if (osm_entity_bits() & osmium::osm_entity_bits::node) { vout << " node"; } if (osm_entity_bits() & osmium::osm_entity_bits::way) { vout << " way"; } if (osm_entity_bits() & osmium::osm_entity_bits::relation) { vout << " relation"; } if (osm_entity_bits() & osmium::osm_entity_bits::changeset) { vout << " changeset"; } m_vout << '\n'; } void Command::print_arguments(const std::string& command) { if (m_vout.verbose()) { m_vout << "Started osmium " << command << '\n' << " " << get_osmium_long_version() << '\n' << " " << get_libosmium_version() << '\n' << "Command line options and default settings:\n"; show_arguments(); } } void Command::show_memory_used() { const osmium::MemoryUsage mem; if (mem.current() > 0) { m_vout << "Peak memory used: " << mem.peak() << " MBytes\n"; } } std::string check_index_type(const std::string& index_type_name, bool allow_none) { if (allow_none && index_type_name == "none") { return index_type_name; } std::string type{index_type_name}; const auto pos = type.find(','); if (pos != std::string::npos) { type.resize(pos); } const auto& map_factory = osmium::index::MapFactory::instance(); if (!map_factory.has_map_type(type)) { throw argument_error{"Unknown index type '" + index_type_name + "'. Use --show-index-types or -I to get a list."}; } return index_type_name; } osmium-tool-1.17.0/src/cmd.hpp000066400000000000000000000213601474143067200161410ustar00rootroot00000000000000#ifndef CMD_HPP #define CMD_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "option_clean.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include const char* get_osmium_version() noexcept; const char* get_osmium_long_version() noexcept; const char* get_libosmium_version() noexcept; class CommandFactory; namespace po = boost::program_options; /** * Virtual base class for commands that can be called from the command line. */ class Command { osmium::osm_entity_bits::type m_osm_entity_bits = osmium::osm_entity_bits::all; enum class display_progress_type { never = 0, on_tty = 1, always = 2 } m_display_progress = display_progress_type::on_tty; protected: const CommandFactory& m_command_factory; osmium::VerboseOutput m_vout{false}; OptionClean m_clean; public: explicit Command(const CommandFactory& command_factory) : m_command_factory(command_factory) { } virtual ~Command() { } // This function parses the command line arguments for a // command. // It returns true if the parsing was successful and the run() // function should be called. It returns false if the work is // done and run() should not be called. // It throws if there was a problem with the arguments. // // This function should not attempt to open any files or // do any other actual work. That will happen in the run() // function. virtual bool setup(const std::vector&) { return true; } // Show command line arguments. This is only called when the // verbose option is true; virtual void show_arguments() { } // Run the actual command. // It returns true if everything ran successfully. // It returns false if there was an error. virtual bool run() = 0; // The name of the command. virtual const char* name() const noexcept = 0; // The command line usage synopsis of the command. virtual const char* synopsis() const noexcept = 0; static po::options_description add_common_options(bool with_progress = true); bool setup_common(const boost::program_options::variables_map& vm, const po::options_description& desc); void setup_progress(const boost::program_options::variables_map& vm); void setup_object_type_nwrc(const boost::program_options::variables_map& vm); void setup_object_type_nwr(const boost::program_options::variables_map& vm); void show_object_types(osmium::VerboseOutput& vout); void print_arguments(const std::string& command); void show_memory_used(); osmium::osm_entity_bits::type osm_entity_bits() const { return m_osm_entity_bits; } bool display_progress_internal() const { switch (m_display_progress) { case display_progress_type::on_tty: return osmium::isatty(1) && osmium::isatty(2); // if STDOUT and STDERR are a TTY case display_progress_type::always: return true; default: break; } return false; } }; // class Command class with_single_osm_input { protected: std::string m_input_filename; std::string m_input_format; osmium::io::File m_input_file; public: void setup_input_file(const boost::program_options::variables_map& vm); static po::options_description add_single_input_options(); void show_single_input_arguments(osmium::VerboseOutput& vout); const osmium::io::File& input_file() const { return m_input_file; } /// Is the input file STDIN? bool any_input_is_stdin() const noexcept { return m_input_file.filename().empty(); } }; // class with_single_osm_input class with_multiple_osm_inputs { protected: std::vector m_input_filenames; std::string m_input_format; std::vector m_input_files; public: void setup_input_files(const boost::program_options::variables_map& vm); static po::options_description add_multiple_inputs_options(); void show_multiple_inputs_arguments(osmium::VerboseOutput& vout); const std::vector& input_files() const { return m_input_files; } /// Is any of the input files STDIN? bool any_input_is_stdin() const noexcept { return std::any_of(m_input_files.cbegin(), m_input_files.cend(), [](const osmium::io::File& file) { return file.filename().empty(); }); } }; // class with_multiple_osm_inputs class CommandWithSingleOSMInput : public Command, public with_single_osm_input { public: explicit CommandWithSingleOSMInput(const CommandFactory& command_factory) : Command(command_factory) { } bool display_progress() const { return display_progress_internal() && !any_input_is_stdin(); } }; // class CommandWithSingleOSMInput class CommandWithMultipleOSMInputs : public Command, public with_multiple_osm_inputs { public: explicit CommandWithMultipleOSMInputs(const CommandFactory& command_factory) : Command(command_factory) { } bool display_progress() const { return display_progress_internal() && !any_input_is_stdin(); } }; // class CommandWithMultipleOSMInputs void init_header(osmium::io::Header& header, const osmium::io::Header& input_header, const std::vector& options); class with_osm_output { protected: std::string m_generator; std::vector m_output_headers; std::string m_output_filename; std::string m_output_format; osmium::io::File m_output_file; osmium::io::overwrite m_output_overwrite = osmium::io::overwrite::no; osmium::io::fsync m_fsync = osmium::io::fsync::no; public: with_osm_output() : m_generator("osmium/") { m_generator.append(get_osmium_version()); } void init_output_file(const po::variables_map& vm); void check_output_file(); void setup_output_file(const po::variables_map& vm); static po::options_description add_output_options(); void show_output_arguments(osmium::VerboseOutput& vout); const osmium::io::File& output_file() const { return m_output_file; } void setup_header(osmium::io::Header& header) const; void setup_header(osmium::io::Header& header, const osmium::io::Header& input_header) const; osmium::io::overwrite output_overwrite() const { return m_output_overwrite; } }; // class with_osm_output /** * All commands than can be called from the command line are registered * with this factory. When the program is running it uses this factory * to create the command object from the class depending on the name of * the command. */ class CommandFactory { using create_command_type = std::function()>; struct command_info { std::string description; // description of command for help create_command_type create; // function that creates C++ object }; std::map m_commands; public: bool register_command(const std::string& name, const std::string& description, create_command_type&& create_function); // Return a vector with names and descriptions of all commands std::vector> help() const; int max_command_name_length() const; std::string get_description(const std::string& name) const; // This will create a C++ command object from the given name and // return it wrapped in a unique_ptr. std::unique_ptr create_command(const std::string& name) const; }; // class CommandFactory void register_commands(CommandFactory& cmd_factory); std::string check_index_type(const std::string& index_type_name, bool allow_none = false); #endif // CMD_HPP osmium-tool-1.17.0/src/cmd_factory.cpp000066400000000000000000000042431474143067200176640ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" #include #include #include #include #include bool CommandFactory::register_command(const std::string& name, const std::string& description, create_command_type&& create_function) { const command_info info{description, std::move(create_function)}; return m_commands.emplace(name, info).second; } std::vector> CommandFactory::help() const { std::vector> commands; commands.reserve(m_commands.size()); for (const auto& cmd : m_commands) { commands.emplace_back(cmd.first, cmd.second.description); } return commands; } int CommandFactory::max_command_name_length() const { osmium::max_op max_width; for (const auto& cmd : m_commands) { max_width.update(static_cast(cmd.first.length())); } return max_width(); } std::string CommandFactory::get_description(const std::string& name) const { const auto it = m_commands.find(name); if (it == m_commands.end()) { return ""; } return it->second.description; } std::unique_ptr CommandFactory::create_command(const std::string& name) const { const auto it = m_commands.find(name); if (it == m_commands.end()) { return std::unique_ptr{}; } return std::unique_ptr{(it->second.create)()}; } osmium-tool-1.17.0/src/command_add_locations_to_ways.cpp000066400000000000000000000207001474143067200234340ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_add_locations_to_ways.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandAddLocationsToWays::setup(const std::vector& arguments) { const std::string default_index_type{"flex_mem"}; po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("index-type,i", po::value()->default_value(default_index_type), "Index type for positive IDs") ("index-type-neg", po::value()->default_value(default_index_type), "Index type for negative IDs") ("show-index-types,I", "Show available index types") ("keep-member-nodes", "Keep node members of relations") ("keep-untagged-nodes,n", "Keep untagged nodes") ("ignore-missing-nodes", "Ignore missing nodes") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_multiple_inputs_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filenames", po::value>(), "Input files") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filenames", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (vm.count("show-index-types")) { const auto& map_factory = osmium::index::MapFactory::instance(); for (const auto& map_type : map_factory.map_types()) { std::cout << map_type << '\n'; } return false; } if (vm.count("index-type")) { m_index_type_name_pos = check_index_type(vm["index-type"].as()); } if (vm.count("index-type-neg")) { m_index_type_name_neg = check_index_type(vm["index-type-neg"].as()); } if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_files(vm); setup_output_file(vm); if (vm.count("keep-untagged-nodes")) { m_keep_untagged_nodes = true; } if (vm.count("keep-member-nodes")) { m_keep_member_nodes = true; } if (vm.count("ignore-missing-nodes")) { m_ignore_missing_nodes = true; } // If we keep all nodes anyway, the member nodes don't need special consideration if (m_keep_untagged_nodes && m_keep_member_nodes) { std::cerr << "Warning! Option --keep-member-nodes is unnecessary when --keep-untagged-nodes is set.\n"; m_keep_member_nodes = false; } return true; } void CommandAddLocationsToWays::show_arguments() { show_multiple_inputs_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " index type (for positive ids): " << m_index_type_name_pos << '\n'; m_vout << " index type (for negative ids): " << m_index_type_name_neg << '\n'; m_vout << " keep untagged nodes: " << yes_no(m_keep_untagged_nodes); m_vout << " keep nodes that are relation members: " << yes_no(m_keep_member_nodes); m_vout << '\n'; } void CommandAddLocationsToWays::copy_data(osmium::ProgressBar& progress_bar, osmium::io::Reader& reader, osmium::io::Writer& writer, location_handler_type& location_handler) const { while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); osmium::apply(buffer, location_handler); if (m_keep_untagged_nodes) { writer(std::move(buffer)); } else { for (const auto& object : buffer) { if (object.type() == osmium::item_type::node) { const auto &node = static_cast(object); if (!node.tags().empty() || m_member_node_ids.get_binary_search(node.positive_id())) { writer(object); } } else { writer(object); } } } } } void CommandAddLocationsToWays::find_member_nodes() { for (const auto& input_file : m_input_files) { osmium::io::Reader reader{input_file, osmium::osm_entity_bits::relation, osmium::io::read_meta::no}; while (osmium::memory::Buffer buffer = reader.read()) { for (const auto& relation : buffer.select()) { for (const auto& member : relation.members()) { if (member.type() == osmium::item_type::node) { m_member_node_ids.set(member.positive_ref()); } } } } } m_member_node_ids.sort_unique(); } bool CommandAddLocationsToWays::run() { m_output_file.set("locations_on_ways"); osmium::io::Writer writer{m_output_file, m_output_overwrite, m_fsync}; if (m_keep_member_nodes) { m_vout << "Getting all nodes referenced from relations...\n"; find_member_nodes(); m_vout << "Found " << m_member_node_ids.size() << " nodes referenced from relations.\n"; } const auto& map_factory = osmium::index::MapFactory::instance(); auto location_index_pos = map_factory.create_map(m_index_type_name_pos); auto location_index_neg = map_factory.create_map(m_index_type_name_neg); location_handler_type location_handler{*location_index_pos, *location_index_neg}; if (m_ignore_missing_nodes) { location_handler.ignore_errors(); } if (m_input_files.size() == 1) { // single input file m_vout << "Copying input file '" << m_input_files[0].filename() << "'...\n"; osmium::io::Reader reader{m_input_files[0]}; osmium::io::Header header{reader.header()}; setup_header(header); writer.set_header(header); osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; copy_data(progress_bar, reader, writer, location_handler); progress_bar.done(); writer.close(); reader.close(); } else { // multiple input files osmium::io::Header header; setup_header(header); writer.set_header(header); osmium::ProgressBar progress_bar{file_size_sum(m_input_files), display_progress()}; for (const auto& input_file : m_input_files) { progress_bar.remove(); m_vout << "Copying input file '" << input_file.filename() << "'...\n"; osmium::io::Reader reader{input_file}; copy_data(progress_bar, reader, writer, location_handler); progress_bar.file_done(reader.file_size()); reader.close(); } progress_bar.done(); writer.close(); } const auto mem = location_index_pos->used_memory() + location_index_neg->used_memory(); m_vout << "About " << show_mbytes(mem) << " MBytes used for node location index (in main memory or on disk).\n"; show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_add_locations_to_ways.hpp000066400000000000000000000047611474143067200234520ustar00rootroot00000000000000#ifndef COMMAND_ADD_LOCATIONS_TO_WAYS_HPP #define COMMAND_ADD_LOCATIONS_TO_WAYS_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include #include #include #include using index_type = osmium::index::map::Map; using location_handler_type = osmium::handler::NodeLocationsForWays; class CommandAddLocationsToWays : public CommandWithMultipleOSMInputs, public with_osm_output { osmium::index::IdSetSmall m_member_node_ids; std::string m_index_type_name_pos; std::string m_index_type_name_neg; bool m_keep_untagged_nodes = false; bool m_keep_member_nodes = false; bool m_ignore_missing_nodes = false; void find_member_nodes(); void copy_data(osmium::ProgressBar& progress_bar, osmium::io::Reader& reader, osmium::io::Writer& writer, location_handler_type& location_handler) const; public: explicit CommandAddLocationsToWays(const CommandFactory& command_factory) : CommandWithMultipleOSMInputs(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "add-locations-to-ways"; } const char* synopsis() const noexcept override final { return "osmium add-locations-to-ways [OPTIONS] OSM-FILE..."; } }; // class CommandAddLocationsToWays #endif // COMMAND_ADD_LOCATIONS_TO_WAYS_HPP osmium-tool-1.17.0/src/command_apply_changes.cpp000066400000000000000000000330051474143067200217030ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_apply_changes.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using location_index_type = osmium::index::map::SparseMemArray; bool CommandApplyChanges::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("change-file-format", po::value(), "Format of the change file(s)") ("redact", "Redact (patch) OSM files") ("with-history,H", "Apply changes to history file") ("locations-on-ways", "Expect and update locations on ways") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "OSM input file") ("change-filenames", po::value>(), "OSM change input files") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); positional.add("change-filenames", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); setup_output_file(vm); if (vm.count("change-filenames")) { m_change_filenames = vm["change-filenames"].as>(); } else { throw argument_error{"Need data file and at least one change file on the command line."}; } if (vm.count("change-file-format")) { m_change_file_format = vm["change-file-format"].as(); } if (vm.count("locations-on-ways")) { m_locations_on_ways = true; } if (vm.count("with-history")) { if (m_locations_on_ways) { throw argument_error{"Can not use --with-history/-H and --locations-on-ways together."}; } m_with_history = true; m_output_file.set_has_multiple_object_versions(true); } else { if (m_input_file.has_multiple_object_versions() && m_output_file.has_multiple_object_versions()) { if (m_locations_on_ways) { throw argument_error{"Can not use --locations-on-ways on history files."}; } m_with_history = true; } else if (m_input_file.has_multiple_object_versions() != m_output_file.has_multiple_object_versions()) { throw argument_error{"Input and output file must both be OSM data files or both OSM history files (force with --with-history)."}; } } if (vm.count("redact")) { if (m_locations_on_ways) { throw argument_error{"Can not use --redact and --locations-on-ways together."}; } m_with_history = true; m_redact = true; m_output_file.set_has_multiple_object_versions(true); } return true; } void CommandApplyChanges::show_arguments() { m_vout << " input data file name: " << m_input_filename << "\n"; m_vout << " input change file names: \n"; for (const auto& fn : m_change_filenames) { m_vout << " " << fn << "\n"; } m_vout << " data file format: " << m_input_format << "\n"; m_vout << " change file format: " << m_change_file_format << "\n"; show_output_arguments(m_vout); m_vout << " reading and writing history file: " << yes_no(m_with_history); m_vout << " locations on ways: " << yes_no(m_locations_on_ways); } namespace { /** * Copy the first OSM object with a given Id to the output. Keep * track of the Id of each object to do this. * * We are using this functor class instead of a simple lambda, because the * lambda doesn't build on MSVC. */ class copy_first_with_id { osmium::io::Writer* writer; osmium::object_id_type id = 0; public: explicit copy_first_with_id(osmium::io::Writer* w) : writer(w) { } void operator()(const osmium::OSMObject& obj) { if (obj.id() != id) { if (obj.visible()) { (*writer)(obj); } id = obj.id(); } } }; // class copy_first_with_id void update_nodes_if_way(osmium::OSMObject* object, const location_index_type& location_index) { if (object->type() != osmium::item_type::way) { return; } for (auto& node_ref : static_cast(object)->nodes()) { auto location = location_index.get_noexcept(node_ref.positive_ref()); if (location) { node_ref.set_location(location); } } } } // anonymous namespace void CommandApplyChanges::apply_changes_and_write(osmium::ObjectPointerCollection &objects, const std::vector &changes, osmium::io::Reader &reader, osmium::io::Writer &writer) { objects.unique(osmium::object_equal_type_id{}); m_vout << "There are " << objects.size() << " unique objects in the change files\n"; osmium::index::IdSetSmall node_ids; m_vout << "Creating node index...\n"; for (const auto& buffer : changes) { for (const auto& way : buffer.select()) { for (const auto& nr : way.nodes()) { node_ids.set(nr.positive_ref()); } } } node_ids.sort_unique(); m_vout << "Node index has " << node_ids.size() << " entries\n"; m_vout << "Creating location index...\n"; location_index_type location_index; for (const auto& buffer : changes) { for (const auto& node : buffer.select()) { location_index.set(node.positive_id(), node.location()); } } m_vout << "Location index has " << location_index.size() << " entries\n"; m_vout << "Applying changes and writing them to output...\n"; auto it = objects.begin(); auto last_type = osmium::item_type::undefined; while (osmium::memory::Buffer buffer = reader.read()) { for (auto& object : buffer.select()) { if (object.type() < last_type) { throw std::runtime_error{"Input data out of order. Need nodes, ways, relations in ID order."}; } if (object.type() == osmium::item_type::node) { const auto& node = static_cast(object); if (node_ids.get_binary_search(node.positive_id())) { const auto location = location_index.get_noexcept(node.positive_id()); if (!location) { location_index.set(node.positive_id(), node.location()); } } } else if (object.type() == osmium::item_type::way) { if (last_type == osmium::item_type::node) { location_index.sort(); node_ids.clear(); } } last_type = object.type(); auto last_it = it; while (it != objects.end() && osmium::object_order_type_id_reverse_version{}(*it, object)) { if (it->visible()) { update_nodes_if_way(&*it, location_index); writer(*it); } last_it = it; ++it; } if (last_it == objects.end() || last_it->type() != object.type() || last_it->id() != object.id()) { update_nodes_if_way(&object, location_index); writer(object); } } } while (it != objects.end()) { if (it->visible()) { update_nodes_if_way(&*it, location_index); writer(*it); } ++it; } } bool CommandApplyChanges::run() { if (m_locations_on_ways) { m_output_file.set("locations_on_ways"); } m_vout << "Opening output file...\n"; osmium::io::Writer writer{m_output_file, m_output_overwrite, m_fsync}; std::vector changes; osmium::ObjectPointerCollection objects; m_vout << "Reading change file contents...\n"; for (const std::string& change_file_name : m_change_filenames) { if (change_file_name == "-" && m_change_file_format.empty()) { throw argument_error{"When reading the change file from STDIN you have to use\n" "the --change-file-format option to specify the file format."}; } const osmium::io::File file{change_file_name, m_change_file_format}; osmium::io::Reader reader{file, osmium::osm_entity_bits::object}; while (osmium::memory::Buffer buffer = reader.read()) { osmium::apply(buffer, objects); changes.push_back(std::move(buffer)); } reader.close(); } m_vout << "Opening input file...\n"; osmium::io::ReaderWithProgressBar reader{display_progress(), m_input_file, osmium::osm_entity_bits::object}; osmium::io::Header header; setup_header(header); if (m_with_history) { header.set_has_multiple_object_versions(true); } writer.set_header(header); if (m_with_history) { // For history files this is a straightforward sort of the change // files followed by a merge with the input file. m_vout << "Sorting change data...\n"; objects.sort(osmium::object_order_type_id_version()); m_vout << "Applying changes and writing them to output...\n"; const auto input = osmium::io::make_input_iterator_range(reader); auto out = osmium::io::make_output_iterator(writer); if (m_redact) { std::set_union(objects.begin(), objects.end(), input.begin(), input.end(), out, osmium::object_order_type_id_version_without_timestamp()); } else { std::set_union(objects.begin(), objects.end(), input.begin(), input.end(), out); } } else { // For normal data files we sort with the largest version of each // object first and then only copy this last version of any object // to the output. m_vout << "Sorting change data...\n"; // This is needed for a special case: When change files have been // created from extracts it is possible that they contain objects // with the same type, id, version, and timestamp. In that case we // still want to get the last object available. So we have to make // sure it appears first in the objects vector before doing the // stable sort. std::reverse(objects.ptr_begin(), objects.ptr_end()); objects.sort(osmium::object_order_type_id_reverse_version{}); if (m_locations_on_ways) { apply_changes_and_write(objects, changes, reader, writer); } else { m_vout << "Applying changes and writing them to output...\n"; const auto input = osmium::io::make_input_iterator_range(reader); auto output_it = boost::make_function_output_iterator(copy_first_with_id(&writer)); std::set_union(objects.begin(), objects.end(), input.begin(), input.end(), output_it, osmium::object_order_type_id_reverse_version()); } } writer.close(); reader.close(); show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_apply_changes.hpp000066400000000000000000000042221474143067200217070ustar00rootroot00000000000000#ifndef COMMAND_APPLY_CHANGES_HPP #define COMMAND_APPLY_CHANGES_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include class CommandApplyChanges : public CommandWithSingleOSMInput, public with_osm_output { std::vector m_change_filenames; std::string m_change_file_format; bool m_with_history = false; bool m_locations_on_ways = false; bool m_redact = false; void apply_changes_and_write(osmium::ObjectPointerCollection &objects, const std::vector &changes, osmium::io::Reader &reader, osmium::io::Writer &writer); public: explicit CommandApplyChanges(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "apply-changes"; } const char* synopsis() const noexcept override final { return "osmium apply-changes [OPTIONS] OSM-FILE OSM-CHANGE-FILE..."; } }; // class CommandApplyChanges #endif // COMMAND_APPLY_CHANGES_HPP osmium-tool-1.17.0/src/command_cat.cpp000066400000000000000000000173461474143067200176470ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_cat.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include bool CommandCat::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("object-type,t", po::value>(), "Read only objects of given type (node, way, relation, changeset)") ("clean,c", po::value>(), "Clean attribute (version, changeset, timestamp, uid, user)") ("buffer-data", "Buffer all data in memory before writing it out") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_multiple_inputs_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filenames", po::value>(), "Input files") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filenames", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_object_type_nwrc(vm); setup_input_files(vm); setup_output_file(vm); m_clean.setup(vm); if (vm.count("buffer-data")) { m_buffer_data = true; } return true; } void CommandCat::show_arguments() { show_multiple_inputs_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; show_object_types(m_vout); m_vout << " attributes to clean: " << m_clean.to_string() << '\n'; } void CommandCat::copy(osmium::ProgressBar& progress_bar, osmium::io::Reader& reader, osmium::io::Writer& writer) const { while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); m_clean.apply_to(buffer); writer(std::move(buffer)); } } std::size_t CommandCat::read_buffers(osmium::ProgressBar& progress_bar, osmium::io::Reader& reader, std::vector& buffers) { std::size_t size = 0; while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); m_clean.apply_to(buffer); size += buffer.committed(); buffers.emplace_back(std::move(buffer)); } return size; } void CommandCat::write_buffers(osmium::ProgressBar& progress_bar, std::vector& buffers, osmium::io::Writer& writer) { std::size_t size = 0; for (auto&& buffer : buffers) { size += buffer.committed(); writer(std::move(buffer)); progress_bar.update(size); } } namespace { void report_filename(osmium::VerboseOutput* vout, const osmium::io::File& file, const osmium::io::Reader& reader) { assert(vout); const auto size = reader.file_size(); const auto& name = file.filename(); if (size == 0) { if (name.empty()) { *vout << "Reading from stdin...\n"; } else { *vout << "Reading input file '" << name << "'...\n"; } } else { *vout << "Reading input file '" << name << "' (" << size << " bytes)...\n"; } } } // anonymous namespace bool CommandCat::run() { std::size_t bytes_written = 0; if (m_input_files.size() == 1) { // single input file osmium::io::Reader reader{m_input_files[0], osm_entity_bits()}; osmium::io::Header header{reader.header()}; report_filename(&m_vout, m_input_files[0], reader); setup_header(header); osmium::io::Writer writer{m_output_file, header, m_output_overwrite, m_fsync}; if (m_buffer_data) { std::vector buffers; osmium::ProgressBar progress_bar_reader{reader.file_size(), display_progress()}; const std::size_t size = read_buffers(progress_bar_reader, reader, buffers); progress_bar_reader.done(); m_vout << "All data read.\n"; show_memory_used(); m_vout << "Writing data...\n"; osmium::ProgressBar progress_bar_writer{size, display_progress()}; write_buffers(progress_bar_writer, buffers, writer); progress_bar_writer.done(); } else { osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; copy(progress_bar, reader, writer); progress_bar.done(); } bytes_written = writer.close(); reader.close(); } else { // multiple input files osmium::io::Header header; setup_header(header); osmium::io::Writer writer{m_output_file, header, m_output_overwrite, m_fsync}; if (m_buffer_data) { std::vector buffers; std::size_t size = 0; osmium::ProgressBar progress_bar_reader{file_size_sum(m_input_files), display_progress()}; for (const auto& input_file : m_input_files) { progress_bar_reader.remove(); osmium::io::Reader reader{input_file, osm_entity_bits()}; report_filename(&m_vout, input_file, reader); size += read_buffers(progress_bar_reader, reader, buffers); progress_bar_reader.file_done(reader.file_size()); reader.close(); } progress_bar_reader.done(); m_vout << "All data read.\n"; show_memory_used(); m_vout << "Writing data...\n"; osmium::ProgressBar progress_bar_writer{size, display_progress()}; write_buffers(progress_bar_writer, buffers, writer); bytes_written = writer.close(); progress_bar_writer.done(); } else { osmium::ProgressBar progress_bar{file_size_sum(m_input_files), display_progress()}; for (const auto& input_file : m_input_files) { progress_bar.remove(); osmium::io::Reader reader{input_file, osm_entity_bits()}; report_filename(&m_vout, input_file, reader); copy(progress_bar, reader, writer); progress_bar.file_done(reader.file_size()); reader.close(); } bytes_written = writer.close(); progress_bar.done(); } } if (bytes_written > 0) { m_vout << "Wrote " << bytes_written << " bytes.\n"; } show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_cat.hpp000066400000000000000000000037751474143067200176550ustar00rootroot00000000000000#ifndef COMMAND_CAT_HPP #define COMMAND_CAT_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include class CommandCat : public CommandWithMultipleOSMInputs, public with_osm_output { bool m_buffer_data = false; void copy(osmium::ProgressBar& progress_bar, osmium::io::Reader& reader, osmium::io::Writer& writer) const; std::size_t read_buffers(osmium::ProgressBar& progress_bar, osmium::io::Reader& reader, std::vector& buffers); void write_buffers(osmium::ProgressBar& progress_bar, std::vector& buffers, osmium::io::Writer& writer); public: explicit CommandCat(const CommandFactory& command_factory) : CommandWithMultipleOSMInputs(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "cat"; } const char* synopsis() const noexcept override final { return "osmium cat [OPTIONS] OSM-FILE..."; } }; // class CommandCat #endif // COMMAND_CAT_HPP osmium-tool-1.17.0/src/command_changeset_filter.cpp000066400000000000000000000204341474143067200223760ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_changeset_filter.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandChangesetFilter::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("with-discussion,d", "Changesets with discussions (comments)") ("without-discussion,D", "Changesets without discussions (no comments)") ("with-changes,c", "Changesets with changes") ("without-changes,C", "Changesets without any changes") ("open", "Open changesets") ("closed", "Closed changesets") ("user,u", po::value(), "Changesets by given user") ("uid,U", po::value(), "Changesets by given user ID") ("after,a", po::value(), "Changesets opened after this time") ("before,b", po::value(), "Changesets closed before this time") ("bbox,B", po::value(), "Changesets overlapping this bounding box") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "OSM input file") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); setup_output_file(vm); if (vm.count("with-discussion")) { m_with_discussion = true; } if (vm.count("without-discussion")) { m_without_discussion = true; } if (vm.count("with-changes")) { m_with_changes = true; } if (vm.count("without-changes")) { m_without_changes = true; } if (vm.count("open")) { m_open = true; } if (vm.count("closed")) { m_closed = true; } if (vm.count("uid")) { m_uid = vm["uid"].as(); } if (vm.count("user")) { m_user = vm["user"].as(); } if (vm.count("after")) { auto ts = vm["after"].as(); try { m_after = osmium::Timestamp(ts); } catch (const std::invalid_argument&) { throw argument_error{"Wrong format for --after/-a timestamp (use YYYY-MM-DDThh:mm:ssZ)."}; } } if (vm.count("before")) { auto ts = vm["before"].as(); try { m_before = osmium::Timestamp(ts); } catch (const std::invalid_argument&) { throw argument_error{"Wrong format for --before/-b timestamp (use YYYY-MM-DDThh:mm:ssZ)."}; } } if (vm.count("bbox")) { m_box = parse_bbox(vm["bbox"].as(), "--bbox/-B"); } if (m_with_discussion && m_without_discussion) { throw argument_error{"You can not use --with-discussion/-d and --without-discussion/-D together."}; } if (m_with_changes && m_without_changes) { throw argument_error{"You can not use --with-changes/-c and --without-changes/-C together."}; } if (m_open && m_closed) { throw argument_error{"You can not use --open and --closed together."}; } if (m_after > m_before) { throw argument_error{"Timestamp 'after' is after 'before'."}; } return true; } void CommandChangesetFilter::show_arguments() { show_single_input_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " changesets must\n"; if (m_with_discussion) { m_vout << " - have a discussion\n"; } if (m_without_discussion) { m_vout << " - not have a discussion\n"; } if (m_with_changes) { m_vout << " - have at least one change\n"; } if (m_without_changes) { m_vout << " - not have any changes\n"; } if (m_open) { m_vout << " - be open\n"; } if (m_closed) { m_vout << " - be closed\n"; } if (m_uid != 0) { m_vout << " - be from uid " << m_uid << "\n"; } if (!m_user.empty()) { m_vout << " - be from user '" << m_user << "'\n"; } if (m_after > osmium::start_of_time()) { m_vout << " - be closed after " << m_after.to_iso() << " or still open\n"; } if (m_before < osmium::end_of_time()) { m_vout << " - be created before " << m_before.to_iso() << "\n"; } } namespace { bool changeset_after(const osmium::Changeset& changeset, osmium::Timestamp time) { return changeset.open() || changeset.closed_at() >= time; } bool changeset_before(const osmium::Changeset& changeset, osmium::Timestamp time) { return changeset.created_at() <= time; } } // anonymous namespace bool CommandChangesetFilter::run() { m_vout << "Opening input file...\n"; osmium::io::Reader reader{m_input_file, osmium::osm_entity_bits::changeset}; auto input = osmium::io::make_input_iterator_range(reader); osmium::io::Header header{reader.header()}; setup_header(header); m_vout << "Opening output file...\n"; osmium::io::Writer writer{m_output_file, header, m_output_overwrite, m_fsync}; auto out = osmium::io::make_output_iterator(writer); m_vout << "Filtering data...\n"; osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; int count = 0; std::copy_if(input.begin(), input.end(), out, [this, &count, &progress_bar, &reader](const osmium::Changeset& changeset) { if (++count > 10000) { progress_bar.update(reader.offset()); count = 0; } return (!m_with_discussion || changeset.num_comments() > 0) && (!m_without_discussion || changeset.num_comments() == 0) && (!m_with_changes || changeset.num_changes() > 0) && (!m_without_changes || changeset.num_changes() == 0) && (!m_open || changeset.open()) && (!m_closed || changeset.closed()) && (m_uid == 0 || changeset.uid() == m_uid) && (m_user.empty() || m_user == changeset.user()) && changeset_after(changeset, m_after) && changeset_before(changeset, m_before) && (!m_box.valid() || (changeset.bounds().valid() && osmium::geom::overlaps(changeset.bounds(), m_box))); }); progress_bar.done(); writer.close(); reader.close(); show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_changeset_filter.hpp000066400000000000000000000041051474143067200224000ustar00rootroot00000000000000#ifndef COMMAND_CHANGESET_FILTER_HPP #define COMMAND_CHANGESET_FILTER_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include class CommandChangesetFilter : public CommandWithSingleOSMInput, public with_osm_output { std::string m_user; osmium::Box m_box; osmium::Timestamp m_after = osmium::start_of_time(); osmium::Timestamp m_before = osmium::end_of_time(); osmium::user_id_type m_uid = 0; bool m_with_discussion = false; bool m_without_discussion = false; bool m_with_changes = false; bool m_without_changes = false; bool m_open = false; bool m_closed = false; public: explicit CommandChangesetFilter(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "changeset-filter"; } const char* synopsis() const noexcept override final { return "osmium changeset-filter [OPTIONS] OSM-CHANGESET-FILE"; } }; // class CommandChangesetFilter #endif // COMMAND_CHANGESET_FILTER_HPP osmium-tool-1.17.0/src/command_check_refs.cpp000066400000000000000000000247501474143067200211710ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_check_refs.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandCheckRefs::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("show-ids,i", "Show IDs of missing objects") ("check-relations,r", "Also check relations") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "Input file") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); if (vm.count("show-ids")) { m_show_ids = true; } if (vm.count("check-relations")) { m_check_relations = true; } return true; } void CommandCheckRefs::show_arguments() { show_single_input_arguments(m_vout); m_vout << " other options:\n"; m_vout << " show ids: " << yes_no(m_show_ids); m_vout << " check relations: " << yes_no(m_check_relations); } class RefCheckHandler : public osmium::handler::Handler { osmium::nwr_array> m_idset_pos; osmium::nwr_array> m_idset_neg; std::vector> m_relation_refs; osmium::handler::CheckOrder m_check_order; uint64_t m_node_count = 0; uint64_t m_way_count = 0; uint64_t m_relation_count = 0; uint64_t m_missing_nodes_in_ways = 0; uint64_t m_missing_nodes_in_relations = 0; uint64_t m_missing_ways_in_relations = 0; osmium::VerboseOutput* m_vout; osmium::ProgressBar* m_progress_bar; bool m_show_ids; bool m_check_relations; void set(osmium::item_type type, osmium::object_id_type id) { (id > 0 ? m_idset_pos(type) : m_idset_neg(type)).set(std::abs(id)); } bool get(osmium::item_type type, osmium::object_id_type id) const noexcept { return (id > 0 ? m_idset_pos(type) : m_idset_neg(type)).get(std::abs(id)); } public: RefCheckHandler(osmium::VerboseOutput* vout, osmium::ProgressBar* progress_bar, bool show_ids, bool check_relations) : m_vout(vout), m_progress_bar(progress_bar), m_show_ids(show_ids), m_check_relations(check_relations) { assert(vout); assert(progress_bar); } uint64_t node_count() const noexcept { return m_node_count; } uint64_t way_count() const noexcept { return m_way_count; } uint64_t relation_count() const noexcept { return m_relation_count; } uint64_t missing_nodes_in_ways() const noexcept { return m_missing_nodes_in_ways; } uint64_t missing_nodes_in_relations() const noexcept { return m_missing_nodes_in_relations; } uint64_t missing_ways_in_relations() const noexcept { return m_missing_ways_in_relations; } uint64_t missing_relations_in_relations() const noexcept { return m_relation_refs.size(); } void find_missing_relations() { std::sort(m_relation_refs.begin(), m_relation_refs.end()); m_relation_refs.erase( std::remove_if(m_relation_refs.begin(), m_relation_refs.end(), [this](std::pair refs){ return get(osmium::item_type::relation, refs.first); }), m_relation_refs.end() ); } bool no_errors() const noexcept { return missing_nodes_in_ways() == 0 && missing_nodes_in_relations() == 0 && missing_ways_in_relations() == 0 && missing_relations_in_relations() == 0; } void node(const osmium::Node& node) { m_check_order.node(node); if (m_node_count == 0) { m_progress_bar->remove(); *m_vout << "Reading nodes...\n"; } ++m_node_count; set(osmium::item_type::node, node.id()); } void way(const osmium::Way& way) { m_check_order.way(way); if (m_way_count == 0) { m_progress_bar->remove(); *m_vout << "Reading ways...\n"; } ++m_way_count; if (m_check_relations) { set(osmium::item_type::way, way.id()); } for (const auto& node_ref : way.nodes()) { if (!get(osmium::item_type::node, node_ref.ref())) { ++m_missing_nodes_in_ways; if (m_show_ids) { std::cout << "n" << node_ref.ref() << " in w" << way.id() << "\n"; } } } } void relation(const osmium::Relation& relation) { m_check_order.relation(relation); if (m_relation_count == 0) { m_progress_bar->remove(); *m_vout << "Reading relations...\n"; } ++m_relation_count; if (m_check_relations) { set(osmium::item_type::relation, relation.id()); for (const auto& member : relation.members()) { switch (member.type()) { case osmium::item_type::node: if (!get(osmium::item_type::node, member.ref())) { ++m_missing_nodes_in_relations; set(osmium::item_type::node, member.ref()); if (m_show_ids) { std::cout << "n" << member.ref() << " in r" << relation.id() << "\n"; } } break; case osmium::item_type::way: if (!get(osmium::item_type::way, member.ref())) { ++m_missing_ways_in_relations; set(osmium::item_type::way, member.ref()); if (m_show_ids) { std::cout << "w" << member.ref() << " in r" << relation.id() << "\n"; } } break; case osmium::item_type::relation: if (member.ref() > relation.id() || !get(osmium::item_type::relation, member.ref())) { m_relation_refs.emplace_back(member.ref(), relation.id()); } break; default: break; } } } } void show_missing_relation_ids() { for (const auto& refs : m_relation_refs) { std::cout << "r" << refs.first << " in r" << refs.second << "\n"; } } std::size_t used_memory() const noexcept { return m_idset_pos(osmium::item_type::node).used_memory() + m_idset_pos(osmium::item_type::way).used_memory() + m_idset_pos(osmium::item_type::relation).used_memory() + m_idset_neg(osmium::item_type::node).used_memory() + m_idset_neg(osmium::item_type::way).used_memory() + m_idset_neg(osmium::item_type::relation).used_memory() + (m_relation_refs.capacity() * sizeof(decltype(m_relation_refs)::value_type)); } }; // class RefCheckHandler bool CommandCheckRefs::run() { osmium::io::Reader reader{m_input_file}; osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; RefCheckHandler handler{&m_vout, &progress_bar, m_show_ids, m_check_relations}; while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); osmium::apply(buffer, handler); } progress_bar.done(); reader.close(); if (m_check_relations) { handler.find_missing_relations(); if (m_show_ids) { handler.show_missing_relation_ids(); } } std::cerr << "There are " << handler.node_count() << " nodes, " << handler.way_count() << " ways, and " << handler.relation_count() << " relations in this file.\n"; if (m_check_relations) { std::cerr << "Nodes in ways missing: " << handler.missing_nodes_in_ways() << "\n"; std::cerr << "Nodes in relations missing: " << handler.missing_nodes_in_relations() << "\n"; std::cerr << "Ways in relations missing: " << handler.missing_ways_in_relations() << "\n"; std::cerr << "Relations in relations missing: " << handler.missing_relations_in_relations() << "\n"; } else { std::cerr << "Nodes in ways missing: " << handler.missing_nodes_in_ways() << "\n"; } m_vout << "Memory used for indexes: " << show_mbytes(handler.used_memory()) << " MBytes\n"; show_memory_used(); m_vout << "Done.\n"; return handler.no_errors(); } osmium-tool-1.17.0/src/command_check_refs.hpp000066400000000000000000000031151474143067200211660ustar00rootroot00000000000000#ifndef COMMAND_CHECK_REFS_HPP #define COMMAND_CHECK_REFS_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include class CommandCheckRefs : public CommandWithSingleOSMInput { bool m_show_ids = false; bool m_check_relations = false; public: explicit CommandCheckRefs(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "check-refs"; } const char* synopsis() const noexcept override final { return "osmium check-refs [OPTIONS] OSM-DATA-FILE"; } }; // class CommandCheckRefs #endif // COMMAND_CHECK_REFS_HPP osmium-tool-1.17.0/src/command_create_locations_index.cpp000066400000000000000000000105641474143067200236000ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_create_locations_index.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandCreateLocationsIndex::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("index-file,i", po::value(), "Index file name (required)") ("update,u", "Update existing index file") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "Input file") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); if (vm.count("index-file")) { m_index_file_name = vm["index-file"].as(); } else { throw argument_error{"Missing --index-file,-i option."}; } if (vm.count("update")) { m_update = true; } return true; } void CommandCreateLocationsIndex::show_arguments() { show_single_input_arguments(m_vout); m_vout << " other options:\n"; m_vout << " index file: " << m_index_file_name << '\n'; m_vout << " allow update of existing index file: " << yes_no(m_update); } bool CommandCreateLocationsIndex::run() { int flags = O_RDWR | O_CREAT; // NOLINT(hicpp-signed-bitwise) if (!m_update) { flags |= O_EXCL; // NOLINT(hicpp-signed-bitwise) } #ifdef _WIN32 flags |= O_BINARY; // NOLINT(hicpp-signed-bitwise) #endif const int fd = ::open(m_index_file_name.c_str(), flags, 0666); if (fd == -1) { if (errno == EEXIST) { throw argument_error{"Index file exists and you haven't specified --update/-u."}; } throw std::system_error{errno, std::system_category(), std::string("Can not open index file '") + m_index_file_name + "'"}; } osmium::index::map::DenseFileArray location_index{fd}; m_vout << "Reading input file '" << m_input_file.filename() << "'\n"; osmium::io::Reader reader{m_input_file, osmium::osm_entity_bits::node}; osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; while (const auto buffer = reader.read()) { progress_bar.update(reader.offset()); osmium::apply(buffer, [&](const osmium::Node& node) { location_index.set(node.positive_id(), node.location()); }); } progress_bar.done(); reader.close(); m_vout << "About " << (location_index.used_memory() / (1024LLU * 1024LLU * 1024LLU)) << " GBytes used for node location index on disk.\n"; m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_create_locations_index.hpp000066400000000000000000000032601474143067200236000ustar00rootroot00000000000000#ifndef COMMAND_CREATE_LOCATIONS_INDEX_HPP #define COMMAND_CREATE_LOCATIONS_INDEX_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include class CommandCreateLocationsIndex : public CommandWithSingleOSMInput { std::string m_index_file_name; bool m_update = false; public: explicit CommandCreateLocationsIndex(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "create-locations-index"; } const char* synopsis() const noexcept override final { return "osmium create-locations-index -i INDEX-FILE [OPTIONS] OSM-FILE"; } }; // class CommandCreateLocationsIndex #endif // COMMAND_CREATE_LOCATIONS_INDEX_HPP osmium-tool-1.17.0/src/command_derive_changes.cpp000066400000000000000000000147041474143067200220410ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_derive_changes.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandDeriveChanges::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("increment-version", "Increment version of deleted objects") ("keep-details", "Keep tags (and nodes of ways, members of relations) of deleted objects") ("update-timestamp", "Set timestamp of deleted objects to current time") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_multiple_inputs_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filenames", po::value>(), "Input files") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filenames", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_files(vm); setup_output_file(vm); if (m_input_files.size() != 2) { throw argument_error{"You need exactly two input files for this command."}; } if (vm.count("increment-version")) { m_increment_version = true; } if (vm.count("keep-details")) { m_keep_details = true; } if (vm.count("update-timestamp")) { m_update_timestamp = true; } return true; } void CommandDeriveChanges::show_arguments() { show_multiple_inputs_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " on deleted objects:\n"; m_vout << " increment version: " << yes_no(m_increment_version); m_vout << " keep details: " << yes_no(m_keep_details); m_vout << " update timestamp: " << yes_no(m_update_timestamp); } void CommandDeriveChanges::write_deleted(osmium::io::Writer& writer, osmium::OSMObject& object) { if (m_increment_version) { object.set_version(object.version() + 1); } if (m_update_timestamp) { object.set_timestamp(std::time(nullptr)); } if (m_keep_details) { object.set_visible(false); writer(object); } else { using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) if (object.type() == osmium::item_type::node) { osmium::builder::add_node(m_buffer, _deleted(), _id(object.id()), _version(object.version()), _timestamp(object.timestamp()) ); } else if (object.type() == osmium::item_type::way) { osmium::builder::add_way(m_buffer, _deleted(), _id(object.id()), _version(object.version()), _timestamp(object.timestamp()) ); } else if (object.type() == osmium::item_type::relation) { osmium::builder::add_relation(m_buffer, _deleted(), _id(object.id()), _version(object.version()), _timestamp(object.timestamp()) ); } writer(m_buffer.get(0)); m_buffer.clear(); } } bool CommandDeriveChanges::run() { m_vout << "Opening output file...\n"; if (m_output_file.format() != osmium::io::file_format::xml || !m_output_file.is_true("xml_change_format")) { warning("Output format chosen is not the XML change format. Use .osc(.gz|bz2) as suffix or -f option.\n"); } osmium::io::Writer writer{m_output_file, m_output_overwrite, m_fsync}; m_vout << "Opening input files...\n"; osmium::io::Reader reader1{m_input_files[0], osmium::osm_entity_bits::object}; osmium::io::ReaderWithProgressBar reader2{display_progress(), m_input_files[1], osmium::osm_entity_bits::object}; auto in1 = osmium::io::make_input_iterator_range(reader1); auto in2 = osmium::io::make_input_iterator_range(reader2); auto it1 = in1.begin(); auto it2 = in2.begin(); auto end1 = in1.end(); auto end2 = in2.end(); osmium::io::Header header; setup_header(header); writer.set_header(header); reader2.progress_bar().remove(); m_vout << "Deriving changes...\n"; while (it1 != end1 || it2 != end2) { if (it2 == end2) { write_deleted(writer, *it1); ++it1; } else if (it1 == end1 || *it2 < *it1) { writer(*it2); ++it2; } else if (*it1 < *it2) { if (it2->id() != it1->id()) { write_deleted(writer, *it1); } ++it1; } else { /* *it1 == *it2 */ ++it1; ++it2; } } writer.close(); reader2.close(); reader1.close(); show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_derive_changes.hpp000066400000000000000000000036351474143067200220470ustar00rootroot00000000000000#ifndef COMMAND_DERIVE_CHANGES_HPP #define COMMAND_DERIVE_CHANGES_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include class CommandDeriveChanges : public CommandWithMultipleOSMInputs, public with_osm_output { osmium::memory::Buffer m_buffer{128}; bool m_keep_details = false; bool m_update_timestamp = false; bool m_increment_version = false; public: explicit CommandDeriveChanges(const CommandFactory& command_factory) : CommandWithMultipleOSMInputs(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; void write_deleted(osmium::io::Writer& writer, osmium::OSMObject& object); bool run() override final; const char* name() const noexcept override final { return "derive-changes"; } const char* synopsis() const noexcept override final { return "osmium derive-changes [OPTIONS] OSM-FILE1 OSM-FILE2"; } }; // class CommandDeriveChanges #endif // COMMAND_DERIVE_CHANGES_HPP osmium-tool-1.17.0/src/command_diff.cpp000066400000000000000000000303251474143067200200000ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_diff.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandDiff::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("ignore-changeset", "Ignore changeset id when comparing objects") ("ignore-uid", "Ignore user id when comparing objects") ("ignore-user", "Ignore user name when comparing objects") ("object-type,t", po::value>(), "Read only objects of given type (node, way, relation)") ("output,o", po::value(), "Output file") ("output-format,f", po::value(), "Format of output file") ("overwrite,O", "Allow existing output file to be overwritten") ("quiet,q", "Report only when files differ") ("summary,s", "Show summary on STDERR") ("suppress-common,c", "Suppress common objects") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_multiple_inputs_options()}; po::options_description hidden; hidden.add_options() ("input-filenames", po::value>(), "Input files") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filenames", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_object_type_nwr(vm); setup_input_files(vm); if (m_input_files.size() != 2) { throw argument_error("You need exactly two input files for this command."); } if (vm.count("ignore-changeset")) { m_ignore_attrs_changeset = true; } if (vm.count("ignore-uid")) { m_ignore_attrs_uid = true; } if (vm.count("ignore-user")) { m_ignore_attrs_user = true; } if (vm.count("output")) { m_output_filename = vm["output"].as(); } if (vm.count("output-format")) { m_output_format = vm["output-format"].as(); } if (vm.count("overwrite")) { m_output_overwrite = osmium::io::overwrite::allow; } if (vm.count("summary")) { m_show_summary = true; } if (vm.count("quiet")) { if (vm.count("output") || vm.count("output-format") || vm.count("overwrite") || vm.count("suppress-common")) { throw argument_error("Do not use --quiet/-q with any of the output options."); } m_output_action = "none"; m_output_format = "no output"; } if (m_output_format == "compact") { m_output_action = "compact"; } if (m_output_action.empty()) { if (m_output_format.empty() && (m_output_filename.empty() || m_output_filename == "-")) { m_output_format = "compact"; m_output_action = "compact"; } else { m_output_action = "osm"; m_output_file = osmium::io::File{m_output_filename, m_output_format}; m_output_file.check(); std::string metadata{"version+timestamp"}; if (!m_ignore_attrs_changeset) { metadata += "+changeset"; } if (!m_ignore_attrs_uid) { metadata += "+uid"; } if (!m_ignore_attrs_changeset) { metadata += "+user"; } m_output_file.set("add_metadata", metadata); auto f = m_output_file.format(); if (f != osmium::io::file_format::opl && f != osmium::io::file_format::debug) { throw argument_error("File format does not support diff output. Use 'compact', 'opl' or 'debug' format."); } } } if (vm.count("suppress-common")) { m_suppress_common = true; } return true; } void CommandDiff::show_arguments() { show_multiple_inputs_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " show summary: " << yes_no(m_show_summary); m_vout << " suppress common objects: " << yes_no(m_suppress_common); show_object_types(m_vout); } class OutputAction { public: OutputAction() noexcept = default; virtual ~OutputAction() noexcept = default; OutputAction(const OutputAction&) = delete; OutputAction& operator=(const OutputAction&) = delete; OutputAction(OutputAction&&) noexcept = delete; OutputAction& operator=(OutputAction&&) noexcept = delete; virtual void left(const osmium::OSMObject& /* object */) { } virtual void right(const osmium::OSMObject& /* object */) { } virtual void same(const osmium::OSMObject& /* object */) { } virtual void different(const osmium::OSMObject& /* left */, const osmium::OSMObject& /* right */) { } }; // class OutputAction class OutputActionCompact : public OutputAction { int m_fd; void print(const char diff, const osmium::OSMObject& object) const { std::stringstream ss; ss << diff << osmium::item_type_to_char(object.type()) << object.id() << " v" << object.version() << '\n'; osmium::io::detail::reliable_write(m_fd, ss.str().c_str(), ss.str().size()); } public: explicit OutputActionCompact(int fd) noexcept : m_fd(fd) { } void left(const osmium::OSMObject& object) override { print('-', object); } void right(const osmium::OSMObject& object) override { print('+', object); } void same(const osmium::OSMObject& object) override { print(' ', object); } void different(const osmium::OSMObject& left, const osmium::OSMObject& /* right */) override { print('*', left); } }; // class OutputActionCompact class OutputActionOSM : public OutputAction { osmium::io::Writer m_writer; public: OutputActionOSM(const osmium::io::File& file, osmium::io::overwrite ow) : m_writer(file, ow) { } void left(const osmium::OSMObject& object) override { m_writer(object); } void right(const osmium::OSMObject& object) override { m_writer(object); } void same(const osmium::OSMObject& object) override { m_writer(object); } void different(const osmium::OSMObject& left, const osmium::OSMObject& right) override { m_writer(left); m_writer(right); } }; // class OutputActionOSM void CommandDiff::update_object_crc(osmium::CRC* crc, const osmium::OSMObject &object) const { crc->update_bool(object.visible()); crc->update(object.timestamp()); crc->update(object.tags()); if (!m_ignore_attrs_changeset) { crc->update_int32(object.changeset()); } if (!m_ignore_attrs_uid) { crc->update_int32(object.uid()); } if (!m_ignore_attrs_user) { crc->update_string(object.user()); } } bool CommandDiff::run() { osmium::io::Reader reader1{m_input_files[0], osm_entity_bits()}; osmium::io::ReaderWithProgressBar reader2{display_progress(), m_input_files[1], osm_entity_bits()}; auto in1 = osmium::io::make_input_iterator_range(reader1); auto in2 = osmium::io::make_input_iterator_range(reader2); auto it1 = in1.begin(); auto it2 = in2.begin(); auto end1 = in1.end(); auto end2 = in2.end(); std::unique_ptr action; if (m_output_action == "compact") { const int fd = osmium::io::detail::open_for_writing(m_output_filename, m_output_overwrite); action = std::make_unique(fd); } else if (m_output_action == "osm") { m_output_file.set("diff"); action = std::make_unique(m_output_file, m_output_overwrite); } uint64_t count_left = 0; uint64_t count_right = 0; uint64_t count_same = 0; uint64_t count_different = 0; while (it1 != end1 || it2 != end2) { if (it2 == end2) { it1->set_diff(osmium::diff_indicator_type::left); ++count_left; if (action) { action->left(*it1); } ++it1; } else if (it1 == end1 || *it2 < *it1) { it2->set_diff(osmium::diff_indicator_type::right); ++count_right; if (action) { action->right(*it2); } ++it2; } else if (*it1 < *it2) { it1->set_diff(osmium::diff_indicator_type::left); ++count_left; if (action) { action->left(*it1); } ++it1; } else { /* *it1 == *it2 */ osmium::CRC crc1; osmium::CRC crc2; update_object_crc(&crc1, *it1); update_object_crc(&crc2, *it2); switch (it1->type()) { case osmium::item_type::node: crc1.update(static_cast(*it1).location()); crc2.update(static_cast(*it2).location()); break; case osmium::item_type::way: crc1.update(static_cast(*it1).nodes()); crc2.update(static_cast(*it2).nodes()); break; case osmium::item_type::relation: crc1.update(static_cast(*it1).members()); crc2.update(static_cast(*it2).members()); break; default: break; } if (crc1().checksum() == crc2().checksum()) { ++count_same; if (!m_suppress_common) { it1->set_diff(osmium::diff_indicator_type::both); it2->set_diff(osmium::diff_indicator_type::both); if (action) { action->same(*it1); } } } else { ++count_different; it1->set_diff(osmium::diff_indicator_type::left); it2->set_diff(osmium::diff_indicator_type::right); if (action) { action->different(*it1, *it2); } } ++it1; ++it2; } } if (m_show_summary) { std::cerr << "Summary: left=" << count_left << " right=" << count_right << " same=" << count_same << " different=" << count_different << "\n"; } show_memory_used(); m_vout << "Done.\n"; return count_left == 0 && count_right == 0 && count_different == 0; } osmium-tool-1.17.0/src/command_diff.hpp000066400000000000000000000036111474143067200200030ustar00rootroot00000000000000#ifndef COMMAND_DIFF_HPP #define COMMAND_DIFF_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include class CommandDiff : public CommandWithMultipleOSMInputs, public with_osm_output { std::string m_output_action; bool m_ignore_attrs_changeset = false; bool m_ignore_attrs_uid = false; bool m_ignore_attrs_user = false; bool m_show_summary = false; bool m_suppress_common = false; void update_object_crc(osmium::CRC* crc, const osmium::OSMObject &object) const; public: explicit CommandDiff(const CommandFactory& command_factory) : CommandWithMultipleOSMInputs(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "diff"; } const char* synopsis() const noexcept override final { return "osmium diff [OPTIONS] OSM-FILE1 OSM-FILE2"; } }; // class CommandDiff #endif // COMMAND_DIFF_HPP osmium-tool-1.17.0/src/command_export.cpp000066400000000000000000000564211474143067200204160ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_export.hpp" #include "exception.hpp" #include "util.hpp" #include "export/export_format_json.hpp" #include "export/export_format_pg.hpp" #include "export/export_format_text.hpp" #include "export/export_handler.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { std::string get_attr_string(const nlohmann::json& object, const char* key) { const auto it = object.find(key); if (it == object.end()) { return {}; } if (it->is_string()) { return it->template get(); } if (it->is_boolean() && it->template get()) { return std::string{"@"} + key; } return {}; } Ruleset parse_tags_ruleset(const nlohmann::json& object, const char* key) { Ruleset ruleset; const auto json = object.find(key); if (json == object.end() || json->is_null()) { // When this is not set, the default is "other". This is later // changed to "any" if both linear_tags and area_tags are missing. ruleset.set_rule_type(tags_filter_rule_type::other); return ruleset; } if (json->is_boolean()) { if (json->template get()) { ruleset.set_rule_type(tags_filter_rule_type::any); } else { ruleset.set_rule_type(tags_filter_rule_type::none); } return ruleset; } if (!json->is_array()) { throw config_error{std::string{"'"} + key + "' member in top-level object must be false, true, null, or an array."}; } if (json->empty()) { std::cerr << "Warning! An empty array for 'linear_tags' or 'area_tags' matches any tags.\n" << " Please use 'true' instead of the array.\n"; ruleset.set_rule_type(tags_filter_rule_type::any); return ruleset; } ruleset.set_rule_type(tags_filter_rule_type::list); for (const auto& value : *json) { if (!value.is_string()) { throw config_error{std::string{"Array elements in '"} + key + "' must be strings."}; } const auto str = value.template get(); if (!str.empty()) { ruleset.add_rule(str); } } return ruleset; } bool parse_string_array(const nlohmann::json& object, const char* key, std::vector* result) { const auto json = object.find(key); if (json == object.end()) { return false; } if (!json->is_array()) { throw config_error{std::string{"'"} + key + "' member in top-level object must be array."}; } for (const auto& value : *json) { if (!value.is_string()) { throw config_error{std::string{"Array elements in '"} + key + "' must be strings."}; } const auto str = value.template get(); if (!str.empty()) { result->emplace_back(str); } } return true; } } // anonymous namespace void CommandExport::parse_attributes(const nlohmann::json& attributes) { if (!attributes.is_object()) { throw config_error{"'attributes' member must be an object."}; } m_options.type = get_attr_string(attributes, "type"); m_options.id = get_attr_string(attributes, "id"); m_options.version = get_attr_string(attributes, "version"); m_options.changeset = get_attr_string(attributes, "changeset"); m_options.timestamp = get_attr_string(attributes, "timestamp"); m_options.uid = get_attr_string(attributes, "uid"); m_options.user = get_attr_string(attributes, "user"); m_options.way_nodes = get_attr_string(attributes, "way_nodes"); } void CommandExport::parse_format_options(const nlohmann::json& options) { if (!options.is_object()) { throw config_error{"'format_options' member must be an object."}; } for (const auto &item : options.items()) { const auto type = item.value().type(); const auto &key = item.key(); switch (type) { case nlohmann::json::value_t::null: m_options.format_options.set(key, false); break; case nlohmann::json::value_t::boolean: m_options.format_options.set(key, item.value().template get()); break; case nlohmann::json::value_t::object: throw config_error{"Option value for key '" + std::string(key) + "' can not be of type object."}; case nlohmann::json::value_t::array: throw config_error{"Option value for key '" + std::string(key) + "' can not be an array."}; break; case nlohmann::json::value_t::string: m_options.format_options.set(key, item.value().template get()); break; case nlohmann::json::value_t::number_integer: m_options.format_options.set(key, std::to_string(item.value().template get())); break; case nlohmann::json::value_t::number_unsigned: m_options.format_options.set(key, std::to_string(item.value().template get())); break; case nlohmann::json::value_t::number_float: m_options.format_options.set(key, std::to_string(item.value().template get())); break; default: throw config_error{"Unknown type"}; } } } void CommandExport::parse_config_file() { std::ifstream config_file{m_config_file_name}; nlohmann::json doc = nlohmann::json::parse(config_file); if (!doc.is_object()) { throw config_error{"Top-level value must be an object."}; } const auto json_attr = doc.find("attributes"); if (json_attr != doc.end()) { parse_attributes(*json_attr); } const auto json_opts = doc.find("format_options"); if (json_opts != doc.end()) { parse_format_options(*json_opts); } m_linear_ruleset = parse_tags_ruleset(doc, "linear_tags"); m_area_ruleset = parse_tags_ruleset(doc, "area_tags"); if (m_linear_ruleset.rule_type() == tags_filter_rule_type::other && m_area_ruleset.rule_type() == tags_filter_rule_type::other) { m_linear_ruleset.set_rule_type(tags_filter_rule_type::any); m_area_ruleset.set_rule_type(tags_filter_rule_type::any); } parse_string_array(doc, "include_tags", &m_include_tags); parse_string_array(doc, "exclude_tags", &m_exclude_tags); } void CommandExport::canonicalize_output_format() { for (auto& c : m_output_format) { c = static_cast(std::tolower(c)); } if (m_output_format == "json") { m_output_format = "geojson"; return; } if (m_output_format == "jsonseq") { m_output_format = "geojsonseq"; return; } if (m_output_format == "txt") { m_output_format = "text"; return; } } bool CommandExport::setup(const std::vector& arguments) { const std::string default_index_type{"flex_mem"}; po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("add-unique-id,u", po::value(), "Add unique id to each feature ('counter' or 'type_id')") ("config,c", po::value(), "Config file") ("format-option,x", po::value>(), "Output format options") ("fsync", "Call fsync after writing file") ("geometry-types", po::value(), "Geometry types that should be written (default: 'point,linestring,polygon')") ("index-type,i", po::value()->default_value(default_index_type), "Index type to use") ("keep-untagged,n", "Keep features that don't have any tags") ("output,o", po::value(), "Output file (default: STDOUT)") ("output-format,f", po::value(), "Output format (default depends on output file suffix)") ("overwrite,O", "Allow existing output file to be overwritten") ("print-default-config,C", "Print default config on STDOUT") ("show-errors,e", "Output any geometry errors on STDOUT") ("stop-on-error,E", "Stop on the first error encountered") ("show-index-types,I", "Show available index types") ("attributes,a", po::value(), "Comma-separated list of attributes to add to the output (default: none)") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "OSM input file") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (vm.count("print-default-config")) { std::cout << R"({ "attributes": { "type": false, "id": false, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "format_options": { }, "linear_tags": true, "area_tags": true, "exclude_tags": [], "include_tags": [] } )"; return false; } if (vm.count("show-index-types")) { const auto& map_factory = osmium::index::MapFactory::instance(); for (const auto& map_type : map_factory.map_types()) { std::cout << map_type << '\n'; } std::cout << "none\n"; return false; } if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); if (vm.count("output")) { m_output_filename = vm["output"].as(); const auto pos = m_output_filename.rfind('.'); if (pos != std::string::npos) { m_output_format = m_output_filename.substr(pos + 1); } } else { m_output_filename = "-"; } if (vm.count("output-format")) { m_output_format = vm["output-format"].as(); } canonicalize_output_format(); if (m_output_format != "geojson" && m_output_format != "geojsonseq" && m_output_format != "pg" && m_output_format != "text") { throw argument_error{"Set output format with --output-format or -f to 'geojson', 'geojsonseq', 'pg', or 'text'."}; } // Set defaults for output format options depending on output format if (m_output_format == "geojsonseq") { m_options.format_options.set("print_record_separator", true); } if (m_output_format == "pg") { m_options.format_options.set("tags_type", "json"); } if (vm.count("config")) { m_config_file_name = vm["config"].as(); try { parse_config_file(); } catch (const nlohmann::json::parse_error& e) { std::cerr << "Error while reading config file '" << m_config_file_name << "':\n"; throw config_error{std::string{"JSON error at offset "} + std::to_string(e.byte) + ": " + e.what()}; } catch (const config_error&) { std::cerr << "Error while reading config file '" << m_config_file_name << "':\n"; throw; } } if (vm.count("add-unique-id")) { const std::string value = vm["add-unique-id"].as(); if (value == "counter") { m_options.unique_id = unique_id_type::counter; } else if (value == "type_id") { m_options.unique_id = unique_id_type::type_id; } else { throw argument_error{"Unknown --add-unique-id, -u setting. Use 'counter' or 'type_id'."}; } } if (vm.count("fsync")) { m_fsync = osmium::io::fsync::yes; } if (vm.count("geometry-types")) { m_geometry_types.clear(); const auto types = osmium::split_string(vm["geometry-types"].as(), ','); for (const auto& type : types) { if (type == "point") { m_geometry_types.point = true; } else if (type == "linestring") { m_geometry_types.linestring = true; } else if (type == "polygon") { m_geometry_types.polygon = true; } else if (type == "multipolygon") { m_geometry_types.polygon = true; } else { throw argument_error{"Unknown geometry type in --geometry-types option: " + type + "."}; } } if (m_geometry_types.empty()) { throw argument_error{"No geometry types in --geometry-types option."}; } } if (vm.count("attributes")) { const auto attrs = osmium::split_string(vm["attributes"].as(), ','); for (const auto& attr : attrs) { if (attr == "type") { m_options.type = "@type"; } else if (attr == "id") { m_options.id = "@id"; } else if (attr == "version") { m_options.version = "@version"; } else if (attr == "changeset") { m_options.changeset = "@changeset"; } else if (attr == "timestamp") { m_options.timestamp = "@timestamp"; } else if (attr == "uid") { m_options.uid = "@uid"; } else if (attr == "user") { m_options.user = "@user"; } else if (attr == "way_nodes") { m_options.way_nodes = "@way_nodes"; } else { throw argument_error{"Unknown attribute in --attributes option: " + attr + "."}; } } } if (vm.count("index-type")) { m_index_type_name = check_index_type(vm["index-type"].as(), true); } if (vm.count("keep-untagged")) { m_options.keep_untagged = true; } if (vm.count("overwrite")) { m_output_overwrite = osmium::io::overwrite::allow; } if (vm.count("format-option")) { for (const auto& str : vm["format-option"].as>()) { m_options.format_options.set(str); } } if (vm.count("show-errors")) { m_show_errors = true; } if (vm.count("stop-on-error")) { m_show_errors = true; m_stop_on_error = true; } if (!m_include_tags.empty() && !m_exclude_tags.empty()) { throw config_error{"Setting both 'include_tags' and 'exclude_tags' is not allowed."}; } if (!m_include_tags.empty()) { initialize_tags_filter(m_options.tags_filter, false, m_include_tags); } else if (!m_exclude_tags.empty()) { initialize_tags_filter(m_options.tags_filter, true, m_exclude_tags); } if (m_input_file.filename().empty()) { throw config_error{"Can not read from STDIN, because input file has to be read twice."}; } return true; } namespace { void print_taglist(osmium::VerboseOutput* vout, const std::vector& strings) { assert(vout); for (const auto& str : strings) { *vout << " " << str << '\n'; } } void print_ruleset(osmium::VerboseOutput* vout, const Ruleset& ruleset) { assert(vout); switch (ruleset.rule_type()) { case tags_filter_rule_type::none: *vout << "none\n"; break; case tags_filter_rule_type::any: *vout << "any\n"; break; case tags_filter_rule_type::list: *vout << "one of the following:\n"; print_taglist(vout, ruleset.tags()); break; case tags_filter_rule_type::other: *vout << "if other tag list doesn't match\n"; break; } } const char* print_unique_id_type(unique_id_type unique_id) { switch (unique_id) { case unique_id_type::counter: return "counter"; case unique_id_type::type_id: return "type and id"; default: break; } return "no"; } std::unique_ptr create_handler(const std::string& output_format, const std::string& output_filename, osmium::io::overwrite overwrite, osmium::io::fsync fsync, const options_type& options) { if (output_format == "geojson" || output_format == "geojsonseq") { return std::make_unique(output_format, output_filename, overwrite, fsync, options); } if (output_format == "pg") { return std::make_unique(output_format, output_filename, overwrite, fsync, options); } if (output_format == "text") { return std::make_unique(output_format, output_filename, overwrite, fsync, options); } throw argument_error{"Unknown output format"}; } } // anonymous namespace void CommandExport::show_arguments() { show_single_input_arguments(m_vout); m_vout << " output options:\n"; m_vout << " file name: " << m_output_filename << '\n'; m_vout << " file format: " << m_output_format << '\n'; m_vout << " overwrite: " << yes_no(m_output_overwrite == osmium::io::overwrite::allow); m_vout << " fsync: " << yes_no(m_fsync == osmium::io::fsync::yes); m_vout << " attributes:\n"; m_vout << " type: " << (m_options.type.empty() ? "(omitted)" : m_options.type) << '\n'; m_vout << " id: " << (m_options.id.empty() ? "(omitted)" : m_options.id) << '\n'; m_vout << " version: " << (m_options.version.empty() ? "(omitted)" : m_options.version) << '\n'; m_vout << " changeset: " << (m_options.changeset.empty() ? "(omitted)" : m_options.changeset) << '\n'; m_vout << " timestamp: " << (m_options.timestamp.empty() ? "(omitted)" : m_options.timestamp) << '\n'; m_vout << " uid: " << (m_options.uid.empty() ? "(omitted)" : m_options.uid) << '\n'; m_vout << " user: " << (m_options.user.empty() ? "(omitted)" : m_options.user) << '\n'; m_vout << " way_nodes: " << (m_options.way_nodes.empty() ? "(omitted)" : m_options.way_nodes) << '\n'; if (!m_options.format_options.empty()) { m_vout << " output format options:\n"; for (const auto& option : m_options.format_options) { m_vout << " " << option.first << " = " << option.second << '\n'; } } m_vout << " linear tags: "; print_ruleset(&m_vout, m_linear_ruleset); m_vout << " area tags: "; print_ruleset(&m_vout, m_area_ruleset); if (!m_include_tags.empty()) { m_vout << " include only these tags:\n"; print_taglist(&m_vout, m_include_tags); } else if (!m_exclude_tags.empty()) { m_vout << " exclude these tags:\n"; print_taglist(&m_vout, m_exclude_tags); } m_vout << " other options:\n"; m_vout << " index type: " << m_index_type_name << '\n'; m_vout << " add unique IDs: " << print_unique_id_type(m_options.unique_id) << '\n'; m_vout << " keep untagged features: " << yes_no(m_options.keep_untagged); } bool CommandExport::run() { auto handler = create_handler(m_output_format, m_output_filename, m_output_overwrite, m_fsync, m_options); if (m_vout.verbose()) { handler->debug_output(m_vout, m_output_filename); } const osmium::area::Assembler::config_type assembler_config; osmium::area::MultipolygonManager mp_manager{assembler_config}; m_vout << "First pass (of two) through input file (reading relations)...\n"; osmium::relations::read_relations(m_input_file, mp_manager); m_vout << "First pass done.\n"; m_vout << "Second pass (of two) through input file...\n"; m_linear_ruleset.init_filter(); m_area_ruleset.init_filter(); ExportHandler export_handler{std::move(handler), m_linear_ruleset, m_area_ruleset, m_geometry_types, m_show_errors, m_stop_on_error}; osmium::handler::CheckOrder check_order_handler; if (m_index_type_name == "none") { osmium::io::ReaderWithProgressBar reader{display_progress(), m_input_file}; osmium::apply(reader, check_order_handler, export_handler, mp_manager.handler([&export_handler](const osmium::memory::Buffer& buffer) { osmium::apply(buffer, export_handler); })); reader.close(); } else { const auto& map_factory = osmium::index::MapFactory::instance(); auto location_index_pos = map_factory.create_map(m_index_type_name); auto location_index_neg = map_factory.create_map(m_index_type_name); location_handler_type location_handler{*location_index_pos, *location_index_neg}; if (!m_stop_on_error) { location_handler.ignore_errors(); } osmium::io::ReaderWithProgressBar reader{display_progress(), m_input_filename}; osmium::apply(reader, check_order_handler, location_handler, export_handler, mp_manager.handler([&export_handler](const osmium::memory::Buffer& buffer) { osmium::apply(buffer, export_handler); })); reader.close(); m_vout << "About " << show_mbytes(location_index_pos->used_memory() + location_index_neg->used_memory()) << " MBytes used for node location index (in main memory or on disk).\n"; } if (m_stop_on_error) { const auto incomplete_relations = mp_manager.relations_database().count_relations(); if (incomplete_relations > 0) { throw osmium::geometry_error{"Found " + std::to_string(incomplete_relations) + " incomplete relation(s)"}; } } m_vout << "Second pass done.\n"; export_handler.close(); m_vout << "Wrote " << export_handler.count() << " features.\n"; m_vout << "Encountered " << export_handler.error_count() << " errors.\n"; show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_export.hpp000066400000000000000000000051701474143067200204160ustar00rootroot00000000000000#ifndef COMMAND_EXPORT_HPP #define COMMAND_EXPORT_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include "export/options.hpp" #include "export/ruleset.hpp" #include #include #include #include #include #include class CommandExport : public CommandWithSingleOSMInput { using index_type = osmium::index::map::Map; using location_handler_type = osmium::handler::NodeLocationsForWays; options_type m_options{}; Ruleset m_linear_ruleset; Ruleset m_area_ruleset; std::vector m_include_tags; std::vector m_exclude_tags; std::string m_config_file_name; std::string m_index_type_name; std::string m_output_filename; std::string m_output_format; geometry_types m_geometry_types; osmium::io::overwrite m_output_overwrite = osmium::io::overwrite::no; osmium::io::fsync m_fsync = osmium::io::fsync::no; bool m_show_errors = false; bool m_stop_on_error = false; void canonicalize_output_format(); void parse_attributes(const nlohmann::json& attributes); void parse_format_options(const nlohmann::json& options); void parse_config_file(); public: explicit CommandExport(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "export"; } const char* synopsis() const noexcept override final { return "osmium export [OPTIONS] OSM-FILE"; } }; // class CommandExport #endif // COMMAND_EXPORT_HPP osmium-tool-1.17.0/src/command_extract.cpp000066400000000000000000000573611474143067200205530ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_extract.hpp" #include "exception.hpp" #include "extract/extract_bbox.hpp" #include "extract/extract_polygon.hpp" #include "extract/geojson_file_parser.hpp" #include "extract/osm_file_parser.hpp" #include "extract/poly_file_parser.hpp" #include "extract/strategy_complete_ways.hpp" #include "extract/strategy_complete_ways_with_history.hpp" #include "extract/strategy_simple.hpp" #include "extract/strategy_smart.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN // Prevent winsock.h inclusion; avoid winsock2.h conflict # endif # include #endif #ifndef _WIN32 # include #endif namespace { constexpr const std::size_t max_extracts = 500; osmium::Box parse_bbox(const nlohmann::json& value) { if (value.is_array()) { if (value.size() != 4) { throw config_error{"'bbox' must be an array with exactly four elements."}; } if (!value[0].is_number() || !value[1].is_number() || !value[2].is_number() || !value[3].is_number()) { throw config_error{"'bbox' array elements must be numbers."}; } const auto value0 = value[0].template get(); const auto value1 = value[1].template get(); const auto value2 = value[2].template get(); const auto value3 = value[3].template get(); if (value0 < -180.0 || value0 > 180.0) { throw config_error{"Invalid coordinate in bbox: " + std::to_string(value0) + "."}; } if (value1 < -90.0 || value1 > 90.0) { throw config_error{"Invalid coordinate in bbox: " + std::to_string(value1) + "."}; } if (value2 < -180.0 || value2 > 180.0) { throw config_error{"Invalid coordinate in bbox: " + std::to_string(value2) + "."}; } if (value3 < -90.0 || value3 > 90.0) { throw config_error{"Invalid coordinate in bbox: " + std::to_string(value3) + "."}; } const osmium::Location location1{value0, value1}; const osmium::Location location2{value2, value3}; osmium::Box box; box.extend(location1); box.extend(location2); return box; } if (value.is_object()) { const auto left = value.find("left"); const auto right = value.find("right"); const auto top = value.find("top"); const auto bottom = value.find("bottom"); if (left != value.end() && right != value.end() && top != value.end() && bottom != value.end()) { if (left->is_number() && right->is_number() && top->is_number() && bottom->is_number()) { const auto left_value = left->template get(); const auto right_value = right->template get(); const auto top_value = top->template get(); const auto bottom_value = bottom->template get(); if (left_value < -180.0 || left_value > 180.0) { throw config_error{"Invalid coordinate in bbox: " + std::to_string(left_value) + "."}; } if (right_value < -180.0 || right_value > 180.0) { throw config_error{"Invalid coordinate in bbox: " + std::to_string(right_value) + "."}; } if (top_value < -90.0 || top_value > 90.0) { throw config_error{"Invalid coordinate in bbox: " + std::to_string(top_value) + "."}; } if (bottom_value < -90.0 || bottom_value > 90.0) { throw config_error{"Invalid coordinate in bbox: " + std::to_string(bottom_value) + "."}; } const osmium::Location bottom_left{left_value, bottom_value}; const osmium::Location top_right{right_value, top_value}; if (bottom_left.x() < top_right.x() && bottom_left.y() < top_right.y()) { return osmium::Box{bottom_left, top_right}; } throw config_error{"Need 'left' < 'right' and 'bottom' < 'top' in 'bbox' object."}; } throw config_error{"Members in 'bbox' object must be numbers."}; } throw config_error{"Need 'left', 'right', 'top', and 'bottom' members in 'bbox' object."}; } throw config_error{"'bbox' member is not an array or object."}; } #ifdef _WIN32 bool is_valid_driver_char(const char value) noexcept { return ((value | 0x20) - 'a') <= ('z' - 'a'); } bool is_path_rooted(const std::string& path) noexcept { const std::size_t len = path.size(); return (len >= 1 && (path[0] == '\\' || path[0] == '/')) || (len >= 2 && is_valid_driver_char(path[0]) && path[1] == ':'); } #endif std::size_t parse_multipolygon_object(const std::string& directory, std::string file_name, std::string file_type, osmium::memory::Buffer* buffer) { assert(buffer); if (file_name.empty()) { throw config_error{"Missing 'file_name' in '(multi)polygon' object."}; } #ifdef _WIN32 const bool is_relative = !is_path_rooted(file_name); #else const bool is_relative = file_name[0] != '/'; #endif if (is_relative) { // relative file name file_name = directory + file_name; } // If the file type is not set, try to deduce it from the file name // suffix. if (file_type.empty()) { if (ends_with(file_name, ".poly")) { file_type = "poly"; } else if (ends_with(file_name, ".json") || ends_with(file_name, ".geojson")) { file_type = "geojson"; } else { const std::string suffix{get_filename_suffix(file_name)}; const osmium::io::File osmfile{"", suffix}; if (osmfile.format() != osmium::io::file_format::unknown) { file_type = "osm"; } } } if (file_type == "osm") { try { OSMFileParser parser{*buffer, file_name}; return parser(); } catch (const std::system_error& e) { throw osmium::io_error{std::string{"While reading file '"} + file_name + "':\n" + e.what()}; } catch (const osmium::io_error& e) { throw osmium::io_error{std::string{"While reading file '"} + file_name + "':\n" + e.what()}; } catch (const osmium::out_of_order_error& e) { throw osmium::io_error{std::string{"While reading file '"} + file_name + "':\n" + e.what()}; } } else if (file_type == "geojson") { GeoJSONFileParser parser{*buffer, file_name}; try { return parser(); } catch (const config_error& e) { throw geojson_error{e.what()}; } } else if (file_type == "poly") { PolyFileParser parser{*buffer, file_name}; return parser(); } else if (file_type.empty()) { throw config_error{"Could not autodetect file type in '(multi)polygon' object. Add a 'file_type'."}; } throw config_error{std::string{"Unknown file type: '"} + file_type + "' in '(multi)polygon.file_type'"}; } std::size_t parse_multipolygon_object(const std::string& directory, const nlohmann::json& value, osmium::memory::Buffer* buffer) { assert(buffer); const std::string file_name{get_value_as_string(value, "file_name")}; const std::string file_type{get_value_as_string(value, "file_type")}; return parse_multipolygon_object(directory, file_name, file_type, buffer); } std::size_t parse_polygon(const std::string& directory, const nlohmann::json& value, osmium::memory::Buffer* buffer) { assert(buffer); if (value.is_array()) { return parse_polygon_array(value, buffer); } if (value.is_object()) { return parse_multipolygon_object(directory, value, buffer); } throw config_error{"Polygon must be an object or array."}; } std::size_t parse_multipolygon(const std::string& directory, const nlohmann::json& value, osmium::memory::Buffer* buffer) { assert(buffer); if (value.is_array()) { return parse_multipolygon_array(value, buffer); } if (value.is_object()) { return parse_multipolygon_object(directory, value, buffer); } throw config_error{"Multipolygon must be an object or array."}; } bool is_existing_directory(const char* name) { #ifdef _MSC_VER // Windows implementation // https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx struct _stat64 s{}; if (::_stati64(name, &s) != 0) { return false; } return (s.st_mode & _S_IFDIR) != 0; #else // Unix implementation struct stat s; // NOLINT clang-tidy if (::stat(name, &s) != 0) { return false; } return S_ISDIR(s.st_mode); // NOLINT(hicpp-signed-bitwise) #endif } } // anonymous namespace void CommandExtract::set_directory(const std::string& directory) { if (!is_existing_directory(directory.c_str())) { throw config_error{"Output directory is missing or not accessible: " + directory}; } m_output_directory = directory; if (m_output_directory.empty() || m_output_directory.back() != '/') { m_output_directory += '/'; } } void CommandExtract::parse_config_file() { std::ifstream config_file{m_config_file_name}; nlohmann::json doc = nlohmann::json::parse(config_file); if (!doc.is_object()) { throw config_error{"Top-level value must be an object."}; } const std::string directory{get_value_as_string(doc, "directory")}; if (!directory.empty() && m_output_directory.empty()) { m_vout << " Directory set to '" << directory << "'.\n"; set_directory(directory); } const auto json_extracts = doc.find("extracts"); if (json_extracts == doc.end()) { throw config_error{"Missing 'extracts' member in top-level object."}; } if (!json_extracts->is_array()) { throw config_error{"'extracts' member in top-level object must be array."}; } m_vout << " Reading extracts from config file...\n"; int extract_num = 1; for (const auto& item : *json_extracts) { std::string output; try { if (!item.is_object()) { throw config_error{"Members in 'extracts' array must be objects."}; } output = get_value_as_string(item, "output"); if (output.empty()) { throw config_error{"Missing 'output' field for extract."}; } m_vout << " Looking at extract '" << output << "'...\n"; const std::string output_format{get_value_as_string(item, "output_format")}; const std::string description{get_value_as_string(item, "description")}; const auto json_bbox = item.find("bbox"); const auto json_polygon = item.find("polygon"); const auto json_multipolygon = item.find("multipolygon"); osmium::io::File output_file{m_output_directory + output, output_format}; if (m_with_history) { output_file.set_has_multiple_object_versions(true); } else if (output_file.has_multiple_object_versions()) { throw config_error{"Looks like you are trying to write a history file, but option --with-history is not set."}; } if (json_bbox != item.end()) { m_extracts.push_back(std::make_unique(output_file, description, parse_bbox(*json_bbox))); } else if (json_polygon != item.end()) { m_extracts.push_back(std::make_unique(output_file, description, m_buffer, parse_polygon(m_config_directory, *json_polygon, &m_buffer))); } else if (json_multipolygon != item.end()) { m_extracts.push_back(std::make_unique(output_file, description, m_buffer, parse_multipolygon(m_config_directory, *json_multipolygon, &m_buffer))); } else { throw config_error{"Missing geometry for extract. Need 'bbox', 'polygon', or 'multipolygon'."}; } const auto json_output_header = item.find("output_header"); if (json_output_header != item.end()) { if (!json_output_header->is_object()) { throw config_error{"Optional 'output_header' field must be an object."}; } Extract& extract = *m_extracts.back(); for (auto const& header_item : json_output_header->items()) { if (header_item.value().is_null()) { extract.add_header_option(header_item.key()); } else { if (!header_item.value().is_string()) { throw config_error{"Values in 'output_header' object must be strings or null."}; } extract.add_header_option(header_item.key(), header_item.value().template get()); } } } } catch (const config_error& e) { std::string message{"In extract "}; message += std::to_string(extract_num); message += ": "; message += e.what(); throw config_error{message}; } catch (const poly_error&) { std::cerr << "Error while reading poly file for extract " << extract_num << " (" << output << "):\n"; throw; } catch (const geojson_error&) { std::cerr << "Error while reading GeoJSON file for extract " << extract_num << " (" << output << "):\n"; throw; } catch (const std::system_error&) { std::cerr << "Error while reading OSM file for extract " << extract_num << " (" << output << "):\n"; throw; } catch (const osmium::io_error&) { std::cerr << "Error while reading OSM file for extract " << extract_num << " (" << output << "):\n"; throw; } catch (const osmium::out_of_order_error&) { std::cerr << "Error while reading OSM file for extract " << extract_num << " (" << output << "):\n"; throw; } ++extract_num; } m_vout << '\n'; } std::unique_ptr CommandExtract::make_strategy(const std::string& name) { if (name == "simple") { if (m_with_history) { throw argument_error{"The 'simple' strategy is not supported for history files."}; } return std::make_unique(m_extracts, m_options); } if (name == "complete_ways") { if (m_with_history) { return std::make_unique(m_extracts, m_options); } return std::make_unique(m_extracts, m_options); } if (name == "smart") { if (m_with_history) { throw argument_error{"The 'smart' strategy is not supported for history files."}; } return std::make_unique(m_extracts, m_options); } throw argument_error{std::string{"Unknown extract strategy: '"} + name + "'."}; } bool CommandExtract::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("bbox,b", po::value(), "Bounding box") ("config,c", po::value(), "Config file") ("directory,d", po::value(), "Output directory (default: from config)") ("option,S", po::value>(), "Set strategy option") ("polygon,p", po::value(), "Polygon file") ("strategy,s", po::value()->default_value("complete_ways"), "Use named extract strategy") ("with-history,H", "Input file and output files are history files") ("set-bounds", "Sets bounds (bounding box) in header") ("clean", po::value>(), "Clean attribute (version, changeset, timestamp, uid, user)") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "OSM input file") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); init_output_file(vm); m_clean.setup(vm); if (vm.count("config") + vm.count("bbox") + vm.count("polygon") > 1) { throw argument_error{"Can only use one of --config/-c, --bbox/-b, or --polygon/-p."}; } if (vm.count("with-history")) { m_with_history = true; } if (vm.count("config")) { if (vm.count("directory")) { set_directory(vm["directory"].as()); } if (vm.count("output")) { warning("Ignoring --output/-o option.\n"); } if (vm.count("output-format")) { warning("Ignoring --output-format/-f option.\n"); } m_config_file_name = vm["config"].as(); const auto slash = m_config_file_name.find_last_of('/'); if (slash != std::string::npos) { m_config_directory = m_config_file_name; m_config_directory.resize(slash + 1); } } if (vm.count("bbox")) { if (vm.count("directory")) { warning("Ignoring --directory/-d option.\n"); } check_output_file(); if (m_with_history) { m_output_file.set_has_multiple_object_versions(true); } m_extracts.push_back(std::make_unique(m_output_file, "", parse_bbox(vm["bbox"].as(), "--box/-b"))); } if (vm.count("polygon")) { if (vm.count("directory")) { warning("Ignoring --directory/-d option.\n"); } check_output_file(); if (m_with_history) { m_output_file.set_has_multiple_object_versions(true); } m_extracts.push_back(std::make_unique(m_output_file, "", m_buffer, parse_multipolygon_object("./", vm["polygon"].as(), "", &m_buffer))); } if (vm.count("option")) { for (const auto& option : vm["option"].as>()) { m_options.set(option); } } if (vm.count("set-bounds")) { m_set_bounds = true; } if (vm.count("strategy")) { m_strategy_name = vm["strategy"].as(); } return true; } void CommandExtract::show_arguments() { show_single_input_arguments(m_vout); show_output_arguments(m_vout); m_vout << " strategy options:\n"; m_vout << " strategy: " << m_strategy_name << '\n'; m_vout << " with history: " << yes_no(m_with_history); m_vout << " other options:\n"; m_vout << " config file: " << m_config_file_name << '\n'; m_vout << " output directory: " << m_output_directory << '\n'; m_vout << " attributes to clean: " << m_clean.to_string() << '\n'; m_vout << '\n'; } void CommandExtract::show_extracts() { m_vout << "Extracts:\n"; int n = 1; for (const auto& e : m_extracts) { const char old_fill = std::cerr.fill(); m_vout << "[" << std::setw(2) << std::setfill('0') << n << "] Output: " << e->output() << '\n'; std::cerr.fill(old_fill); m_vout << " Format: " << e->output_format() << '\n'; m_vout << " Description: " << e->description() << '\n'; if (!e->header_options().empty()) { m_vout << " Header opts: "; bool first = true; for (const auto& opt : e->header_options()) { if (first) { first = false; } else { m_vout << " "; } m_vout << opt << '\n'; } } m_vout << " Envelope: " << e->envelope_as_text() << '\n'; m_vout << " Type: " << e->geometry_type() << '\n'; m_vout << " Geometry: " << e->geometry_as_text() << '\n'; ++n; } m_vout << '\n'; } bool CommandExtract::run() { if (!m_config_file_name.empty()) { m_vout << "Reading config file...\n"; try { parse_config_file(); } catch (const nlohmann::json::parse_error &e) { throw geojson_error{std::string{"In file '"} + m_config_file_name + "':\nJSON error at offset " + std::to_string(e.byte) + " : " + e.what()}; } catch (const config_error&) { std::cerr << "Error while reading config file '" << m_config_file_name << "':\n"; throw; } } if (m_extracts.empty()) { throw config_error{"No extract specified in config file or on the command line."}; } if (m_extracts.size() > max_extracts) { throw config_error{"Too many extracts specified in config file (Maximum: " + std::to_string(max_extracts) + ")."}; } show_extracts(); m_strategy = make_strategy(m_strategy_name); m_strategy->show_arguments(m_vout); osmium::io::Header header; osmium::io::Header input_header; if (m_input_file.filename().empty()) { setup_header(header); } else { osmium::io::Reader reader{m_input_file, osmium::osm_entity_bits::nothing}; input_header = reader.header(); setup_header(header, input_header); reader.close(); } header.set("sorting", "Type_then_ID"); if (m_with_history) { header.set_has_multiple_object_versions(true); } for (const auto& extract : m_extracts) { osmium::io::Header file_header{header}; if (m_set_bounds) { file_header.add_box(extract->envelope()); } init_header(file_header, input_header, extract->header_options()); extract->open_file(file_header, m_output_overwrite, m_fsync, &m_clean); } m_strategy->run(m_vout, display_progress(), m_input_file); for (const auto& extract : m_extracts) { extract->close_file(); } show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_extract.hpp000066400000000000000000000050511474143067200205450ustar00rootroot00000000000000#ifndef COMMAND_EXTRACT_HPP #define COMMAND_EXTRACT_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include "extract/extract.hpp" #include "extract/strategy.hpp" #include #include #include #include #include #include class CommandExtract : public CommandWithSingleOSMInput, public with_osm_output { static const std::size_t initial_buffer_size = 10 * 1024; std::vector> m_extracts; osmium::Options m_options; std::string m_config_file_name; std::string m_config_directory; std::string m_output_directory; std::string m_strategy_name; osmium::memory::Buffer m_buffer{initial_buffer_size, osmium::memory::Buffer::auto_grow::yes}; std::unique_ptr m_strategy; bool m_with_history = false; bool m_set_bounds = false; void parse_config_file(); void show_extracts(); void set_directory(const std::string& directory); std::unique_ptr make_strategy(const std::string& name); public: explicit CommandExtract(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "extract"; } const char* synopsis() const noexcept override final { return "osmium extract --config CONFIG-FILE [OPTIONS] OSM-FILE\n" " osmium extract --bbox LEFT,BOTTOM,RIGHT,TOP [OPTIONS] OSM-FILE\n" " osmium extract --polygon POLYGON-FILE [OPTIONS] OSM-FILE"; } }; // class CommandExtract #endif // COMMAND_EXTRACT_HPP osmium-tool-1.17.0/src/command_fileinfo.cpp000066400000000000000000000711421474143067200206650ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_fileinfo.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef _WIN32 # include #endif // Use ordered_json type if available. Tests rely on ordering. #if NLOHMANN_JSON_VERSION_MAJOR == 3 && NLOHMANN_JSON_VERSION_MINOR < 9 using json = nlohmann::json; #else using json = nlohmann::ordered_json; #endif /*************************************************************************/ struct InfoHandler : public osmium::handler::Handler { osmium::Box bounds; uint64_t changesets = 0; uint64_t nodes = 0; uint64_t ways = 0; uint64_t relations = 0; uint64_t buffers_count = 0; uint64_t buffers_size = 0; uint64_t buffers_capacity = 0; osmium::min_op smallest_changeset_id; osmium::min_op smallest_node_id; osmium::min_op smallest_way_id; osmium::min_op smallest_relation_id; osmium::max_op largest_changeset_id; osmium::max_op largest_node_id; osmium::max_op largest_way_id; osmium::max_op largest_relation_id; osmium::metadata_options metadata_all_objects{"all"}; osmium::metadata_options metadata_some_objects{"none"}; osmium::min_op first_timestamp; osmium::max_op last_timestamp; osmium::CRC crc32; bool ordered = true; bool multiple_versions = false; bool calculate_crc = false; osmium::item_type last_type = osmium::item_type::undefined; osmium::object_id_type last_id = 0; explicit InfoHandler(bool with_crc) : calculate_crc(with_crc) { } void changeset(const osmium::Changeset& changeset) { if (last_type == osmium::item_type::changeset) { if (last_id > changeset.id()) { ordered = false; } } else { last_type = osmium::item_type::changeset; } last_id = changeset.id(); if (calculate_crc) { crc32.update(changeset); } ++changesets; smallest_changeset_id.update(changeset.id()); largest_changeset_id.update(changeset.id()); } void osm_object(const osmium::OSMObject& object) { first_timestamp.update(object.timestamp()); last_timestamp.update(object.timestamp()); metadata_all_objects &= osmium::detect_available_metadata(object); metadata_some_objects |= osmium::detect_available_metadata(object); if (last_type == object.type()) { if (last_id == object.id()) { multiple_versions = true; } if (osmium::id_order{}(object.id(), last_id)) { ordered = false; } } else if (last_type != osmium::item_type::changeset && last_type > object.type()) { ordered = false; } last_type = object.type(); last_id = object.id(); } void node(const osmium::Node& node) { if (calculate_crc) { crc32.update(node); } bounds.extend(node.location()); ++nodes; smallest_node_id.update(node.id()); largest_node_id.update(node.id()); } void way(const osmium::Way& way) { if (calculate_crc) { crc32.update(way); } ++ways; smallest_way_id.update(way.id()); largest_way_id.update(way.id()); } void relation(const osmium::Relation& relation) { if (calculate_crc) { crc32.update(relation); } ++relations; smallest_relation_id.update(relation.id()); largest_relation_id.update(relation.id()); } }; // struct InfoHandler class Output { bool m_calculate_crc = false; public: Output() noexcept = default; virtual ~Output() noexcept = default; Output(const Output&) = delete; Output& operator=(const Output&) = delete; Output(Output&&) noexcept = delete; Output& operator=(Output&&) noexcept = delete; bool calculate_crc() const noexcept { return m_calculate_crc; } void set_crc(bool with_crc) noexcept { m_calculate_crc = with_crc; } virtual void file(const std::string& filename, const osmium::io::File& input_file) = 0; virtual void header(const osmium::io::Header& header) = 0; virtual void data(const osmium::io::Header& header, const InfoHandler& info_handler) = 0; virtual void output() { } }; // class Output namespace { osmium::object_id_type get_smallest(osmium::object_id_type id) noexcept { return id == osmium::min_op{}() ? 0 : id; } osmium::object_id_type get_largest(osmium::object_id_type id) noexcept { return id == osmium::max_op{}() ? 0 : id; } } // anonymous namespace class HumanReadableOutput : public Output { public: void file(const std::string& input_filename, const osmium::io::File& input_file) final { std::cout << "File:\n"; std::cout << " Name: " << input_filename << "\n"; std::cout << " Format: " << input_file.format() << "\n"; std::cout << " Compression: " << input_file.compression() << "\n"; if (!input_file.filename().empty()) { std::cout << " Size: " << file_size(input_file) << "\n"; } } void header(const osmium::io::Header& header) final { std::cout << "Header:\n"; std::cout << " Bounding boxes:\n"; for (const auto& box : header.boxes()) { std::cout << " " << box << "\n"; } std::cout << " With history: " << yes_no(header.has_multiple_object_versions()); std::cout << " Options:\n"; for (const auto& option : header) { std::cout << " " << option.first << "=" << option.second << "\n"; } } void data(const osmium::io::Header& header, const InfoHandler& info_handler) final { std::cout << "Data:\n"; std::cout << " Bounding box: " << info_handler.bounds << "\n"; if (info_handler.first_timestamp() != osmium::end_of_time()) { std::cout << " Timestamps:\n"; std::cout << " First: " << info_handler.first_timestamp() << "\n"; std::cout << " Last: " << info_handler.last_timestamp() << "\n"; } std::cout << " Objects ordered (by type and id): " << yes_no(info_handler.ordered); std::cout << " Multiple versions of same object: "; if (info_handler.ordered) { std::cout << yes_no(info_handler.multiple_versions); if (info_handler.multiple_versions != header.has_multiple_object_versions()) { std::cout << " WARNING! This is different from the setting in the header.\n"; } } else { std::cout << "unknown (because objects in file are unordered)\n"; } if (calculate_crc()) { std::cout << " CRC32: " << std::hex << info_handler.crc32().checksum() << std::dec << "\n"; } else { std::cout << " CRC32: not calculated (use --crc/-c to enable)\n"; } std::cout << " Number of changesets: " << info_handler.changesets << "\n"; std::cout << " Number of nodes: " << info_handler.nodes << "\n"; std::cout << " Number of ways: " << info_handler.ways << "\n"; std::cout << " Number of relations: " << info_handler.relations << "\n"; std::cout << " Smallest changeset ID: " << get_smallest(info_handler.smallest_changeset_id()) << "\n"; std::cout << " Smallest node ID: " << get_smallest(info_handler.smallest_node_id()) << "\n"; std::cout << " Smallest way ID: " << get_smallest(info_handler.smallest_way_id()) << "\n"; std::cout << " Smallest relation ID: " << get_smallest(info_handler.smallest_relation_id()) << "\n"; std::cout << " Largest changeset ID: " << get_largest(info_handler.largest_changeset_id()) << "\n"; std::cout << " Largest node ID: " << get_largest(info_handler.largest_node_id()) << "\n"; std::cout << " Largest way ID: " << get_largest(info_handler.largest_way_id()) << "\n"; std::cout << " Largest relation ID: " << get_largest(info_handler.largest_relation_id()) << "\n"; const auto num_objects = info_handler.changesets + info_handler.nodes + info_handler.ways + info_handler.relations; std::cout << " Number of buffers: " << info_handler.buffers_count; if (num_objects != 0) { std::cout << " (avg " << (num_objects / info_handler.buffers_count) << " objects per buffer)\n"; } else { std::cout << '\n'; } std::cout << " Sum of buffer sizes: " << info_handler.buffers_size << " (" << show_gbytes(info_handler.buffers_size) << " GB)\n"; if (info_handler.buffers_capacity != 0) { const auto fill_factor = std::round(100 * static_cast(info_handler.buffers_size) / static_cast(info_handler.buffers_capacity)); std::cout << " Sum of buffer capacities: " << info_handler.buffers_capacity << " (" << show_gbytes(info_handler.buffers_capacity) << " GB, " << fill_factor << "% full)\n"; } else { std::cout << " Sum of buffer capacities: 0 (0 GB)\n"; } std::cout << "Metadata:\n"; std::cout << " All objects have following metadata attributes: " << info_handler.metadata_all_objects << "\n"; std::cout << " Some objects have following metadata attributes: " << info_handler.metadata_some_objects << "\n"; } }; // class HumanReadableOutput class JSONOutput : public Output { json m_json; public: void file(const std::string& input_filename, const osmium::io::File& input_file) final { m_json["file"] = { {"name", input_filename}, {"format", osmium::io::as_string(input_file.format())}, {"compression", osmium::io::as_string(input_file.compression())} }; if (!input_file.filename().empty()) { m_json["file"]["size"] = static_cast(file_size(input_file)); } } void header(const osmium::io::Header& header) final { std::vector> boxes; for (const auto& box : header.boxes()) { boxes.emplace_back(std::vector{ box.bottom_left().lon(), box.bottom_left().lat(), box.top_right().lon(), box.top_right().lat() }); } json json_options; for (const auto& option : header) { json_options[option.first] = option.second; } m_json["header"] = { {"boxes", boxes}, {"with_history", header.has_multiple_object_versions()}, {"option", json_options} }; } void data(const osmium::io::Header& /*header*/, const InfoHandler& info_handler) final { json json_data = { {"bbox", { info_handler.bounds.bottom_left().lon(), info_handler.bounds.bottom_left().lat(), info_handler.bounds.top_right().lon(), info_handler.bounds.top_right().lat() }} }; if (info_handler.first_timestamp() != osmium::end_of_time()) { json_data["timestamp"] = { {"first", info_handler.first_timestamp().to_iso()}, {"last", info_handler.last_timestamp().to_iso()} }; } json_data["objects_ordered"] = info_handler.ordered; if (info_handler.ordered) { json_data["multiple_versions"] = info_handler.multiple_versions; } if (calculate_crc()) { std::stringstream ss; ss << std::hex << info_handler.crc32().checksum() << std::dec; json_data["crc32"] = ss.str().c_str(); } json_data["count"] = { {"changesets", info_handler.changesets}, {"nodes", info_handler.nodes}, {"ways", info_handler.ways}, {"relations", info_handler.relations} }; json_data["minid"] = { {"changesets", static_cast(get_smallest(info_handler.smallest_changeset_id()))}, {"nodes", static_cast(get_smallest(info_handler.smallest_node_id()))}, {"ways", static_cast(get_smallest(info_handler.smallest_way_id()))}, {"relations", static_cast(get_smallest(info_handler.smallest_relation_id()))} }; json_data["maxid"] = { {"changesets", static_cast(get_largest(info_handler.largest_changeset_id()))}, {"nodes", static_cast(get_largest(info_handler.largest_node_id()))}, {"ways", static_cast(get_largest(info_handler.largest_way_id()))}, {"relations", static_cast(get_largest(info_handler.largest_relation_id()))} }; json_data["buffers"] = { {"count", get_largest(static_cast(info_handler.buffers_count))}, {"size", get_largest(static_cast(info_handler.buffers_size))}, {"capacity", get_largest(static_cast(info_handler.buffers_capacity))} }; json_data["metadata"] = { {"all_objects", { {"version", info_handler.metadata_all_objects.version()}, {"timestamp", info_handler.metadata_all_objects.timestamp()}, {"changeset", info_handler.metadata_all_objects.changeset()}, {"user", info_handler.metadata_all_objects.user()}, {"uid", info_handler.metadata_all_objects.uid()}} }, {"some_objects", { {"version", info_handler.metadata_some_objects.version()}, {"timestamp", info_handler.metadata_some_objects.timestamp()}, {"changeset", info_handler.metadata_some_objects.changeset()}, {"user", info_handler.metadata_some_objects.user()}, {"uid", info_handler.metadata_some_objects.uid()}} } }; m_json["data"] = json_data; } void output() final { std::cout << std::setw(4) << m_json << "\n"; } }; // class JSONOutput class SimpleOutput : public Output { std::string m_get_value; public: explicit SimpleOutput(std::string get_value) : m_get_value(std::move(get_value)) { } void file(const std::string& input_filename, const osmium::io::File& input_file) final { if (m_get_value == "file.name") { std::cout << input_filename << "\n"; return; } if (m_get_value == "file.format") { std::cout << input_file.format() << "\n"; return; } if (m_get_value == "file.compression") { std::cout << input_file.compression() << "\n"; return; } if (m_get_value == "file.size") { if (input_file.filename().empty()) { std::cout << 0 << "\n"; } else { std::cout << file_size(input_file) << "\n"; } return; } } void header(const osmium::io::Header& header) final { if (m_get_value == "header.boxes") { for (const auto& box : header.boxes()) { std::cout << box << "\n"; } } if (m_get_value == "header.with_history") { std::cout << yes_no(header.has_multiple_object_versions()); return; } for (const auto& option : header) { std::string value_name{"header.option."}; value_name.append(option.first); if (m_get_value == value_name) { std::cout << option.second << "\n"; } } } void data(const osmium::io::Header& /*header*/, const InfoHandler& info_handler) final { if (m_get_value == "data.bbox") { std::cout << info_handler.bounds << "\n"; return; } if (m_get_value == "data.timestamp.first") { if (info_handler.first_timestamp() == osmium::end_of_time()) { std::cout << "\n"; } else { std::cout << info_handler.first_timestamp() << "\n"; } return; } if (m_get_value == "data.timestamp.last") { if (info_handler.first_timestamp() == osmium::end_of_time()) { std::cout << "\n"; } else { std::cout << info_handler.last_timestamp() << "\n"; } return; } if (m_get_value == "data.objects_ordered") { std::cout << (info_handler.ordered ? "yes\n" : "no\n"); return; } if (m_get_value == "data.multiple_versions") { if (info_handler.ordered) { std::cout << (info_handler.multiple_versions ? "yes\n" : "no\n"); } else { std::cout << "unknown\n"; } return; } if (m_get_value == "data.crc32") { std::cout << std::hex << info_handler.crc32().checksum() << std::dec << "\n"; return; } if (m_get_value == "data.count.changesets") { std::cout << info_handler.changesets << "\n"; return; } if (m_get_value == "data.count.nodes") { std::cout << info_handler.nodes << "\n"; return; } if (m_get_value == "data.count.ways") { std::cout << info_handler.ways << "\n"; return; } if (m_get_value == "data.count.relations") { std::cout << info_handler.relations << "\n"; return; } if (m_get_value == "data.minid.changesets") { std::cout << get_smallest(info_handler.smallest_changeset_id()) << "\n"; return; } if (m_get_value == "data.minid.nodes") { std::cout << get_smallest(info_handler.smallest_node_id()) << "\n"; return; } if (m_get_value == "data.minid.ways") { std::cout << get_smallest(info_handler.smallest_way_id()) << "\n"; return; } if (m_get_value == "data.minid.relations") { std::cout << get_smallest(info_handler.smallest_relation_id()) << "\n"; return; } if (m_get_value == "data.maxid.changesets") { std::cout << get_largest(info_handler.largest_changeset_id()) << "\n"; return; } if (m_get_value == "data.maxid.nodes") { std::cout << get_largest(info_handler.largest_node_id()) << "\n"; return; } if (m_get_value == "data.maxid.ways") { std::cout << get_largest(info_handler.largest_way_id()) << "\n"; return; } if (m_get_value == "data.maxid.relations") { std::cout << get_largest(info_handler.largest_relation_id()) << "\n"; return; } if (m_get_value == "data.buffers.count") { std::cout << info_handler.buffers_count << "\n"; return; } if (m_get_value == "data.buffers.size") { std::cout << info_handler.buffers_size << "\n"; return; } if (m_get_value == "data.buffers.capacity") { std::cout << info_handler.buffers_capacity << "\n"; return; } if (m_get_value == "metadata.all_objects.version") { std::cout << (info_handler.metadata_all_objects.version() ? "yes\n" : "no\n"); return; } if (m_get_value == "metadata.all_objects.timestamp") { std::cout << (info_handler.metadata_all_objects.timestamp() ? "yes\n" : "no\n"); return; } if (m_get_value == "metadata.all_objects.changeset") { std::cout << (info_handler.metadata_all_objects.changeset() ? "yes\n" : "no\n"); return; } if (m_get_value == "metadata.all_objects.uid") { std::cout << (info_handler.metadata_all_objects.uid() ? "yes\n" : "no\n"); return; } if (m_get_value == "metadata.all_objects.user") { std::cout << (info_handler.metadata_all_objects.user() ? "yes\n" : "no\n"); return; } if (m_get_value == "metadata.some_objects.version") { std::cout << (info_handler.metadata_some_objects.version() ? "yes\n" : "no\n"); return; } if (m_get_value == "metadata.some_objects.timestamp") { std::cout << (info_handler.metadata_some_objects.timestamp() ? "yes\n" : "no\n"); return; } if (m_get_value == "metadata.some_objects.changeset") { std::cout << (info_handler.metadata_some_objects.changeset() ? "yes\n" : "no\n"); return; } if (m_get_value == "metadata.some_objects.uid") { std::cout << (info_handler.metadata_some_objects.uid() ? "yes\n" : "no\n"); return; } if (m_get_value == "metadata.some_objects.user") { std::cout << (info_handler.metadata_some_objects.user() ? "yes\n" : "no\n"); return; } } }; // class SimpleOutput /*************************************************************************/ bool CommandFileinfo::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("extended,e", "Extended output") ("get,g", po::value(), "Get value") ("show-variables,G", "Show variables for --get option") ("json,j", "JSON output") ("crc,c", "Calculate CRC") ("no-crc", "Do not calculate CRC") ("object-type,t", po::value>(), "Read only objects of given type (node, way, relation, changeset)") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "Input file") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_object_type_nwrc(vm); if (vm.count("extended")) { m_extended = true; } if (vm.count("json")) { m_json_output = true; } if (vm.count("crc") && vm.count("no-crc")) { throw argument_error{"Can not use --crc/-c option and --no-crc at the same time."}; } if (m_extended && (vm.count("crc") || (m_json_output && !vm.count("no-crc")))) { m_calculate_crc = true; } const std::vector known_values = { "file.name", "file.format", "file.compression", "file.size", "header.boxes", "header.with_history", "header.option.generator", "header.option.osmosis_replication_base_url", "header.option.osmosis_replication_sequence_number", "header.option.osmosis_replication_timestamp", "header.option.pbf_dense_nodes", "header.option.timestamp", "header.option.version", "data.bbox", "data.timestamp.first", "data.timestamp.last", "data.objects_ordered", "data.multiple_versions", "data.crc32", "data.count.nodes", "data.count.ways", "data.count.relations", "data.count.changesets", "data.minid.nodes", "data.minid.ways", "data.minid.relations", "data.minid.changesets", "data.maxid.nodes", "data.maxid.ways", "data.maxid.relations", "data.maxid.changesets", "data.buffers.count", "data.buffers.size", "data.buffers.capacity", "metadata.all_objects.version", "metadata.all_objects.timestamp", "metadata.all_objects.changeset", "metadata.all_objects.uid", "metadata.all_objects.user", "metadata.some_objects.version", "metadata.some_objects.timestamp", "metadata.some_objects.changeset", "metadata.some_objects.uid", "metadata.some_objects.user" }; if (vm.count("show-variables")) { std::copy(known_values.cbegin(), known_values.cend(), std::ostream_iterator(std::cout, "\n")); return false; } setup_input_file(vm); if (vm.count("get")) { m_get_value = vm["get"].as(); if (m_get_value.substr(0, 14) != "header.option.") { const auto& f = std::find(known_values.cbegin(), known_values.cend(), m_get_value); if (f == known_values.cend()) { throw argument_error{std::string{"Unknown value for --get/-g option '"} + m_get_value + "'. Use --show-variables/-G to see list of known values."}; } } if (m_get_value.substr(0, 5) == "data." && !m_extended) { throw argument_error{"You need to set --extended/-e for any 'data.*' variables to be available."}; } m_calculate_crc = (m_get_value == "data.crc32"); } if (vm.count("get") && vm.count("json")) { throw argument_error{"You can not use --get/-g and --json/-j together."}; } return true; } void CommandFileinfo::show_arguments() { show_single_input_arguments(m_vout); m_vout << " other options:\n"; show_object_types(m_vout); m_vout << " extended output: " << (m_extended ? "yes\n" : "no\n"); m_vout << " calculate CRC: " << (m_calculate_crc ? "yes\n" : "no\n"); } bool CommandFileinfo::run() { std::unique_ptr output; if (m_json_output) { output = std::make_unique(); } else if (m_get_value.empty()) { output = std::make_unique(); } else { output = std::make_unique(m_get_value); } output->set_crc(m_calculate_crc); output->file(m_input_filename, m_input_file); osmium::io::Reader reader{m_input_file, m_extended ? osm_entity_bits() : osmium::osm_entity_bits::nothing}; const osmium::io::Header header{reader.header()}; output->header(header); if (m_extended) { InfoHandler info_handler{m_calculate_crc}; osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); ++info_handler.buffers_count; info_handler.buffers_size += buffer.committed(); info_handler.buffers_capacity += buffer.capacity(); osmium::apply(buffer, info_handler); } progress_bar.done(); output->data(header, info_handler); } reader.close(); output->output(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_fileinfo.hpp000066400000000000000000000031661474143067200206730ustar00rootroot00000000000000#ifndef COMMAND_FILEINFO_HPP #define COMMAND_FILEINFO_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include class CommandFileinfo : public CommandWithSingleOSMInput { std::string m_get_value; bool m_extended = false; bool m_json_output = false; bool m_calculate_crc = false; public: explicit CommandFileinfo(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "fileinfo"; } const char* synopsis() const noexcept override final { return "osmium fileinfo [OPTIONS] OSM-FILE"; } }; // class CommandFileinfo #endif // COMMAND_FILEINFO_HPP osmium-tool-1.17.0/src/command_getid.cpp000066400000000000000000000333721474143067200201710ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_getid.hpp" #include "exception.hpp" #include "id_file.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include std::size_t CommandGetId::count_ids() const noexcept { return m_ids(osmium::item_type::node).size() + m_ids(osmium::item_type::way).size() + m_ids(osmium::item_type::relation).size(); } bool CommandGetId::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("default-type", po::value()->default_value("node"), "Default item type") ("id-file,i", po::value>(), "Read OSM IDs from text file") ("id-osm-file,I", po::value>(), "Read OSM IDs from OSM file") ("with-history,H", "Make it work with history files") ("add-referenced,r", "Recursively add referenced objects") ("remove-tags,t", "Remove tags from objects not explicitly requested") ("verbose-ids", "Print all requested and missing IDs") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "OSM input file") ("ids", po::value>(), "OSM IDs") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); positional.add("ids", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); setup_output_file(vm); if (vm.count("add-referenced")) { if (m_input_filename.empty() || m_input_filename == "-") { throw argument_error{"Can not read OSM input from STDIN when --add-referenced/-r option is used."}; } m_add_referenced_objects = true; } if (vm.count("with-history")) { m_work_with_history = true; } if (vm.count("default-type")) { m_default_item_type = parse_item_type(vm["default-type"].as()); } if (vm.count("remove-tags")) { m_remove_tags = true; if (!m_add_referenced_objects) { std::cerr << "Warning! Without -r/--add-referenced use of -t/--remove-tags isn't doing anything.\n"; } } if (vm.count("verbose-ids")) { m_vout.verbose(true); m_verbose_ids = true; } if (vm.count("id-file")) { for (const std::string& filename : vm["id-file"].as>()) { if (filename == "-") { if (m_input_filename.empty() || m_input_filename == "-") { throw argument_error{"Can not read OSM input and IDs both from STDIN."}; } m_vout << "Reading IDs from STDIN...\n"; read_id_file(std::cin, m_ids, m_default_item_type); } else { std::ifstream id_file{filename}; if (!id_file.is_open()) { throw argument_error{"Could not open file '" + filename + "'"}; } m_vout << "Reading ID file...\n"; read_id_file(id_file, m_ids, m_default_item_type); } } } if (vm.count("id-osm-file")) { for (const std::string& filename : vm["id-osm-file"].as>()) { m_vout << "Reading OSM ID file...\n"; read_id_osm_file(filename, m_ids); } } if (vm.count("ids")) { std::string sids; for (const auto& s : vm["ids"].as>()) { sids += s + " "; } for (const auto& s : osmium::split_string(sids, "\t ;,/|", true)) { parse_and_add_id(s, m_ids, m_default_item_type); } } if (no_ids(m_ids)) { throw argument_error{"Please specify IDs to look for on command line or with option --id-file/-i or --id-osm-file/-I."}; } m_matching_ids = m_ids; return true; } void CommandGetId::show_arguments() { show_single_input_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " add referenced objects: " << yes_no(m_add_referenced_objects); if (m_add_referenced_objects) { m_vout << " remove tags on non-matching objects: " << yes_no(m_remove_tags); } m_vout << " work with history files: " << yes_no(m_work_with_history); m_vout << " default object type: " << osmium::item_type_to_name(m_default_item_type) << "\n"; if (m_verbose_ids) { m_vout << " looking for these ids:\n"; m_vout << " nodes:"; for (const auto id : m_ids(osmium::item_type::node)) { m_vout << " " << id; } m_vout << "\n"; m_vout << " ways:"; for (const auto id : m_ids(osmium::item_type::way)) { m_vout << " " << id; } m_vout << "\n"; m_vout << " relations:"; for (const auto id : m_ids(osmium::item_type::relation)) { m_vout << " " << id; } m_vout << "\n"; } else { m_vout << " looking for " << m_ids(osmium::item_type::node).size() << " node ID(s), " << m_ids(osmium::item_type::way).size() << " way ID(s), and " << m_ids(osmium::item_type::relation).size() << " relation ID(s)\n"; } } osmium::osm_entity_bits::type CommandGetId::get_needed_types() const { osmium::osm_entity_bits::type types = osmium::osm_entity_bits::nothing; if (!m_ids(osmium::item_type::node).empty()) { types |= osmium::osm_entity_bits::node; } if (!m_ids(osmium::item_type::way).empty()) { types |= osmium::osm_entity_bits::way; } if (!m_ids(osmium::item_type::relation).empty()) { types |= osmium::osm_entity_bits::relation; } return types; } namespace { void print_missing_ids(const char* type, const osmium::index::IdSetDense& set) { if (set.empty()) { return; } std::cerr << "Missing " << type << " IDs:"; for (const auto id : set) { std::cerr << ' ' << id; } std::cerr << '\n'; } } // anonymous namespace void CommandGetId::mark_rel_ids(const osmium::index::RelationsMapIndex& rel_in_rel, osmium::unsigned_object_id_type parent_id) { rel_in_rel.for_each(parent_id, [&](osmium::unsigned_object_id_type member_id) { if (m_ids(osmium::item_type::relation).check_and_set(member_id)) { mark_rel_ids(rel_in_rel, member_id); } }); } bool CommandGetId::find_relations_in_relations() { m_vout << " Reading input file to find relations in relations...\n"; osmium::index::RelationsMapStash stash; osmium::io::Reader reader{m_input_file, osmium::osm_entity_bits::relation, osmium::io::read_meta::no}; while (osmium::memory::Buffer buffer = reader.read()) { for (const auto& relation : buffer.select()) { for (const auto& member : relation.members()) { if (member.type() == osmium::item_type::relation) { stash.add(member.ref(), relation.id()); } else if (m_ids(osmium::item_type::relation).get(relation.positive_id())) { if (member.type() == osmium::item_type::node) { m_ids(osmium::item_type::node).set(member.positive_ref()); } else if (member.type() == osmium::item_type::way) { m_ids(osmium::item_type::way).set(member.positive_ref()); } } } } } reader.close(); if (stash.empty()) { return false; } const auto rel_in_rel = stash.build_parent_to_member_index(); for (const auto id : m_ids(osmium::item_type::relation)) { mark_rel_ids(rel_in_rel, id); } return true; } void CommandGetId::find_nodes_and_ways_in_relations() { m_vout << " Reading input file to find nodes/ways in relations...\n"; osmium::io::Reader reader{m_input_file, osmium::osm_entity_bits::relation, osmium::io::read_meta::no}; while (osmium::memory::Buffer buffer = reader.read()) { for (const auto& relation : buffer.select()) { if (m_ids(osmium::item_type::relation).get(relation.positive_id())) { for (const auto& member : relation.members()) { if (member.type() == osmium::item_type::node) { m_ids(osmium::item_type::node).set(member.positive_ref()); } else if (member.type() == osmium::item_type::way) { m_ids(osmium::item_type::way).set(member.positive_ref()); } } } } } reader.close(); } void CommandGetId::find_nodes_in_ways() { m_vout << " Reading input file to find nodes in ways...\n"; osmium::io::Reader reader{m_input_file, osmium::osm_entity_bits::way, osmium::io::read_meta::no}; while (osmium::memory::Buffer buffer = reader.read()) { for (const auto& way : buffer.select()) { if (m_ids(osmium::item_type::way).get(way.positive_id())) { add_nodes(way, m_ids); } } } reader.close(); } void CommandGetId::find_referenced_objects() { m_vout << "Following references...\n"; // If there are any relations we are looking for, we need to run // find_relations_in_relations() to get the member IDs of all types. bool todo = !m_ids(osmium::item_type::relation).empty(); if (todo) { todo = find_relations_in_relations(); } if (todo) { // If find_relations_in_relations() returned true, it means it found // relation members that were not in the original relations ID list. // This means we need to run find_nodes_and_ways_in_relations() to // make sure we have all node and way members of those relations, too. find_nodes_and_ways_in_relations(); } if (!m_ids(osmium::item_type::way).empty()) { find_nodes_in_ways(); } m_vout << "Done following references.\n"; } bool CommandGetId::run() { m_vout << "Opening output file...\n"; osmium::io::Writer writer{m_output_file, m_output_overwrite, m_fsync}; if (m_add_referenced_objects) { find_referenced_objects(); } m_vout << "Opening input file...\n"; osmium::io::Reader reader{m_input_file, get_needed_types()}; osmium::io::Header header{reader.header()}; setup_header(header); writer.set_header(header); m_vout << "Copying matching objects to output file...\n"; osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); for (auto& object : buffer.select()) { if (m_matching_ids(object.type()).get(object.positive_id())) { if (!m_work_with_history) { m_ids(object.type()).unset(object.positive_id()); } writer(object); } else if (m_ids(object.type()).get(object.positive_id())) { if (!m_work_with_history) { m_ids(object.type()).unset(object.positive_id()); } if (m_remove_tags) { object.remove_tags(); } writer(object); } } } progress_bar.done(); m_vout << "Closing output file...\n"; writer.close(); m_vout << "Closing input file...\n"; reader.close(); if (!m_work_with_history) { if (no_ids(m_ids)) { m_vout << "Found all objects.\n"; } else { m_vout << "Did not find " << count_ids() << " object(s).\n"; if (m_verbose_ids) { print_missing_ids("node", m_ids(osmium::item_type::node)); print_missing_ids("way", m_ids(osmium::item_type::way)); print_missing_ids("relation", m_ids(osmium::item_type::relation)); } } } show_memory_used(); m_vout << "Done.\n"; return m_work_with_history || no_ids(m_ids); } osmium-tool-1.17.0/src/command_getid.hpp000066400000000000000000000052671474143067200202000ustar00rootroot00000000000000#ifndef COMMAND_GETID_HPP #define COMMAND_GETID_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include #include #include #include #include #include #include class CommandGetId : public CommandWithSingleOSMInput, public with_osm_output { osmium::nwr_array> m_matching_ids; osmium::nwr_array> m_ids; osmium::item_type m_default_item_type = osmium::item_type::node; bool m_add_referenced_objects = false; bool m_work_with_history = false; bool m_remove_tags = false; bool m_verbose_ids = false; osmium::osm_entity_bits::type get_needed_types() const; std::size_t count_ids() const noexcept; void find_referenced_objects(); void mark_rel_ids(const osmium::index::RelationsMapIndex& rel_in_rel, osmium::unsigned_object_id_type parent_id); bool find_relations_in_relations(); void find_nodes_and_ways_in_relations(); void find_nodes_in_ways(); public: explicit CommandGetId(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "getid"; } const char* synopsis() const noexcept override final { return "osmium getid [OPTIONS] OSM-FILE ID...\n" " osmium getid [OPTIONS] OSM-FILE -i ID-FILE\n" " osmium getid [OPTIONS] OSM-FILE -I ID-OSM-FILE"; } }; // class CommandGetId #endif // COMMAND_GETID_HPP osmium-tool-1.17.0/src/command_getparents.cpp000066400000000000000000000201761474143067200212470ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_getparents.hpp" #include "exception.hpp" #include "id_file.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandGetParents::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("default-type", po::value()->default_value("node"), "Default item type") ("id-file,i", po::value>(), "Read OSM IDs from text file") ("id-osm-file,I", po::value>(), "Read OSM IDs from OSM file") ("add-self,s", "Add objects with specified IDs themselves") ("verbose-ids", "Print all requested IDs") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "OSM input file") ("ids", po::value>(), "OSM IDs") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); positional.add("ids", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); setup_output_file(vm); if (vm.count("add-self")) { m_add_self = true; } if (vm.count("default-type")) { m_default_item_type = parse_item_type(vm["default-type"].as()); } if (vm.count("verbose-ids")) { m_vout.verbose(true); m_verbose_ids = true; } if (vm.count("id-file")) { for (const std::string& filename : vm["id-file"].as>()) { if (filename == "-") { if (m_input_filename.empty() || m_input_filename == "-") { throw argument_error{"Can not read OSM input and IDs both from STDIN."}; } m_vout << "Reading IDs from STDIN...\n"; read_id_file(std::cin, m_ids, m_default_item_type); } else { std::ifstream id_file{filename}; if (!id_file.is_open()) { throw argument_error{"Could not open file '" + filename + "'"}; } m_vout << "Reading ID file...\n"; read_id_file(id_file, m_ids, m_default_item_type); } } } if (vm.count("id-osm-file")) { for (const std::string& filename : vm["id-osm-file"].as>()) { m_vout << "Reading OSM ID file...\n"; read_id_osm_file(filename, m_ids); } } if (vm.count("ids")) { std::string sids; for (const auto& s : vm["ids"].as>()) { sids += s + " "; } for (const auto& s : osmium::split_string(sids, "\t ;,/|", true)) { parse_and_add_id(s, m_ids, m_default_item_type); } } if (no_ids(m_ids)) { throw argument_error{"Please specify IDs to look for on command line or with option --id-file/-i or --id-osm-file/-I."}; } return true; } void CommandGetParents::show_arguments() { show_single_input_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " add self: " << yes_no(m_add_self); m_vout << " default object type: " << osmium::item_type_to_name(m_default_item_type) << "\n"; if (m_verbose_ids) { m_vout << " looking for these ids:\n"; m_vout << " nodes:"; for (const auto id : m_ids(osmium::item_type::node)) { m_vout << " " << id; } m_vout << "\n"; m_vout << " ways:"; for (const auto id : m_ids(osmium::item_type::way)) { m_vout << " " << id; } m_vout << "\n"; m_vout << " relations:"; for (const auto id : m_ids(osmium::item_type::relation)) { m_vout << " " << id; } m_vout << "\n"; } else { m_vout << " looking for " << m_ids(osmium::item_type::node).size() << " node ID(s), " << m_ids(osmium::item_type::way).size() << " way ID(s), and " << m_ids(osmium::item_type::relation).size() << " relation ID(s)\n"; } } osmium::osm_entity_bits::type CommandGetParents::get_needed_types() const { osmium::osm_entity_bits::type types = osmium::osm_entity_bits::relation; if (!m_ids(osmium::item_type::node).empty()) { if (m_add_self) { types |= osmium::osm_entity_bits::node; } types |= osmium::osm_entity_bits::way; } if (!m_ids(osmium::item_type::way).empty()) { if (m_add_self) { types |= osmium::osm_entity_bits::way; } } return types; } bool CommandGetParents::run() { m_vout << "Opening input file...\n"; osmium::io::Reader reader{m_input_file, get_needed_types()}; m_vout << "Opening output file...\n"; osmium::io::Header header{reader.header()}; setup_header(header); osmium::io::Writer writer{m_output_file, header, m_output_overwrite, m_fsync}; m_vout << "Copying matching objects to output file...\n"; osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); for (const auto& object : buffer.select()) { if (m_add_self && m_ids(object.type()).get(object.positive_id())) { writer(object); continue; } if (object.type() == osmium::item_type::way) { const auto& way = static_cast(object); for (const auto& nr : way.nodes()) { if (m_ids(osmium::item_type::node).get(nr.positive_ref())) { writer(object); break; } } } else if (object.type() == osmium::item_type::relation) { const auto& relation = static_cast(object); for (const auto& member : relation.members()) { if (m_ids(member.type()).get(member.positive_ref())) { writer(object); break; } } } } } progress_bar.done(); m_vout << "Closing output file...\n"; writer.close(); m_vout << "Closing input file...\n"; reader.close(); show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_getparents.hpp000066400000000000000000000045341474143067200212540ustar00rootroot00000000000000#ifndef COMMAND_GETPARENTS_HPP #define COMMAND_GETPARENTS_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include #include #include #include #include #include #include class CommandGetParents : public CommandWithSingleOSMInput, public with_osm_output { osmium::nwr_array> m_ids; osmium::item_type m_default_item_type = osmium::item_type::node; bool m_add_self = false; bool m_verbose_ids = false; osmium::osm_entity_bits::type get_needed_types() const; void add_nodes(const osmium::Way& way); void add_members(const osmium::Relation& relation); public: explicit CommandGetParents(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "getparents"; } const char* synopsis() const noexcept override final { return "osmium getparents [OPTIONS] OSM-FILE ID...\n" " osmium getparents [OPTIONS] OSM-FILE -i ID-FILE\n" " osmium getparents [OPTIONS] OSM-FILE -I ID-OSM-FILE"; } }; // class CommandGetParents #endif // COMMAND_GETPARENTS_HPP osmium-tool-1.17.0/src/command_help.cpp000066400000000000000000000066331474143067200200250ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_help.hpp" #include #include #include #include #ifndef _WIN32 # include #endif bool CommandHelp::setup(const std::vector& arguments) { m_topic = arguments.empty() ? "help" : arguments.front(); return true; } namespace { void show_help(const std::string& topic, const std::string& info) { #ifndef _WIN32 // show man page on non-Windows systems std::string manpage{"osmium-"}; manpage += topic; ::execlp("man", "man", manpage.c_str(), nullptr); // if exec fails, fall thru #endif // show info string and link on Windows systems std::cout << info << "\n"; std::cout << "You'll find more documentation at https://osmcode.org/osmium-tool/\n"; } } // anonymous namespace bool CommandHelp::run() { const auto commands = m_command_factory.help(); if (m_topic == "help") { std::cout << "Usage: " << synopsis() << "\n\nCOMMANDS:\n"; // print command names and descriptions in a nice table for (const auto& cmd : commands) { std::cout << " " << std::setw(m_command_factory.max_command_name_length()) << std::left << cmd.first << std::setw(0) << " " << cmd.second << "\n"; } std::cout << "\nTOPICS:\n" " file-formats File formats supported by Osmium\n" " index-types Index types for storing node locations\n" " output-headers Header options that can be set on output files\n"; std::cout << "\nUse 'osmium COMMAND -h' for short usage information.\n" "Use 'osmium help COMMAND' for detailed information on a specific command.\n" "Use 'osmium help TOPIC' for detailed information on a specific topic.\n"; return true; } const auto description = m_command_factory.get_description(m_topic); if (!description.empty()) { show_help(m_topic, std::string{"osmium "} + m_topic + ": " + description); return true; } if (m_topic == "file-formats") { show_help("file-formats", "osmium file-formats: Supported formats are 'xml', 'pbf', and 'opl'."); return true; } if (m_topic == "index-types") { show_help("index-types", ""); return true; } if (m_topic == "output-headers") { show_help("output-headers", ""); return true; } std::cerr << "Unknown help topic '" << m_topic << "'.\n"; return false; } osmium-tool-1.17.0/src/command_help.hpp000066400000000000000000000027101474143067200200220ustar00rootroot00000000000000#ifndef COMMAND_HELP_HPP #define COMMAND_HELP_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include class CommandHelp : public Command { std::string m_topic; public: explicit CommandHelp(const CommandFactory& command_factory) : Command(command_factory) { } bool setup(const std::vector& arguments) override final; bool run() override final; const char* name() const noexcept override final { return "help"; } const char* synopsis() const noexcept override final { return "osmium COMMAND [ARG...]\n" " osmium --version"; } }; // class CommandHelp #endif // COMMAND_HELP_HPP osmium-tool-1.17.0/src/command_merge.cpp000066400000000000000000000212331474143067200201650ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_merge.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandMerge::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("with-history,H", "Do not warn about input files with multiple object versions") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_multiple_inputs_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filenames", po::value>(), "Input files") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filenames", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_files(vm); setup_output_file(vm); if (vm.count("with-history")) { m_with_history = true; } return true; } void CommandMerge::show_arguments() { show_multiple_inputs_arguments(m_vout); show_output_arguments(m_vout); } namespace { class DataSource { using it_type = osmium::io::InputIterator; std::unique_ptr m_reader; std::string m_name; it_type m_iterator; osmium::item_type m_last_type = osmium::item_type::node; osmium::object_id_type m_last_id = 0; osmium::object_version_type m_last_version = 0; bool m_warning; public: explicit DataSource(const osmium::io::File& file, bool with_history) : m_reader(std::make_unique(file)), m_name(file.filename()), m_iterator(*m_reader), m_warning(!with_history) { if (m_iterator != it_type{}) { m_last_type = m_iterator->type(); m_last_id = m_iterator->id(); m_last_version = m_iterator->version(); } } bool empty() const noexcept { return m_iterator == it_type{}; } bool next() { ++m_iterator; if (m_iterator == it_type{}) { // reached end of file return false; } if (m_iterator->type() < m_last_type) { throw std::runtime_error{"Objects in input file '" + m_name + "' out of order (must be nodes, then ways, then relations)."}; } if (m_iterator->type() > m_last_type) { m_last_type = m_iterator->type(); m_last_id = m_iterator->id(); m_last_version = m_iterator->version(); return true; } if (m_iterator->id() < m_last_id) { throw std::runtime_error{"Objects in input file '" + m_name + "' out of order (smaller ids must come first)."}; } if (m_iterator->id() > m_last_id) { m_last_id = m_iterator->id(); m_last_version = m_iterator->version(); return true; } if (m_iterator->version() < m_last_version) { throw std::runtime_error{"Objects in input file '" + m_name + "' out of order (smaller version must come first)."}; } if (m_iterator->version() == m_last_version) { throw std::runtime_error{"Two objects in input file '" + m_name + "' with same version."}; } if (m_warning) { std::cerr << "Warning: Multiple objects with same id in input file '" + m_name + "'!\n"; std::cerr << "If you are reading history files, this is to be expected. Use --with-history to disable warning.\n"; m_warning = false; } m_last_version = m_iterator->version(); return true; } const osmium::OSMObject* get() noexcept { return &*m_iterator; } std::size_t offset() const noexcept { return m_reader->offset(); } }; // DataSource class QueueElement { const osmium::OSMObject* m_object; int m_data_source_index; public: QueueElement(const osmium::OSMObject* object, int data_source_index) noexcept : m_object(object), m_data_source_index(data_source_index) { } const osmium::OSMObject& object() const noexcept { return *m_object; } int data_source_index() const noexcept { return m_data_source_index; } }; // QueueElement bool operator<(const QueueElement& lhs, const QueueElement& rhs) noexcept { return lhs.object() > rhs.object(); } bool operator==(const QueueElement& lhs, const QueueElement& rhs) noexcept { return lhs.object() == rhs.object(); } bool operator!=(const QueueElement& lhs, const QueueElement& rhs) noexcept { return !(lhs == rhs); } } // anonymous namespace bool CommandMerge::run() { m_vout << "Opening output file...\n"; osmium::io::Header header; setup_header(header); osmium::io::Writer writer{m_output_file, header, m_output_overwrite, m_fsync}; if (m_input_files.size() == 1) { m_vout << "Single input file. Copying to output file...\n"; osmium::io::ReaderWithProgressBar reader{display_progress(), m_input_files[0]}; while (osmium::memory::Buffer buffer = reader.read()) { writer(std::move(buffer)); } } else { m_vout << "Merging " << m_input_files.size() << " input files to output file...\n"; osmium::ProgressBar progress_bar{file_size_sum(m_input_files), display_progress()}; std::vector data_sources; data_sources.reserve(m_input_files.size()); std::priority_queue queue; int index = 0; for (const osmium::io::File& file : m_input_files) { data_sources.emplace_back(file, m_with_history); if (!data_sources.back().empty()) { queue.emplace(data_sources.back().get(), index); } ++index; } int n = 0; while (!queue.empty()) { const auto element = queue.top(); queue.pop(); if (queue.empty() || element != queue.top()) { writer(element.object()); } const int dsindex = element.data_source_index(); if (data_sources[dsindex].next()) { queue.emplace(data_sources[dsindex].get(), dsindex); } if (n++ > 10000) { n = 0; progress_bar.update(std::accumulate(data_sources.cbegin(), data_sources.cend(), static_cast(0), [](std::size_t sum, const DataSource& source){ return sum + source.offset(); })); } } } m_vout << "Closing output file...\n"; writer.close(); show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_merge.hpp000066400000000000000000000030441474143067200201720ustar00rootroot00000000000000#ifndef COMMAND_MERGE_HPP #define COMMAND_MERGE_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include class CommandMerge : public CommandWithMultipleOSMInputs, public with_osm_output { bool m_with_history = false; public: explicit CommandMerge(const CommandFactory& command_factory) : CommandWithMultipleOSMInputs(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "merge"; } const char* synopsis() const noexcept override final { return "osmium merge [OPTIONS] OSM-FILE..."; } }; // class CommandMerge #endif // COMMAND_MERGE_HPP osmium-tool-1.17.0/src/command_merge_changes.cpp000066400000000000000000000126001474143067200216530ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_merge_changes.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandMergeChanges::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("simplify,s", "Simplify change") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_multiple_inputs_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filenames", po::value>(), "Input files") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filenames", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_files(vm); setup_output_file(vm); if (vm.count("simplify")) { m_simplify_change = true; } return true; } void CommandMergeChanges::show_arguments() { show_multiple_inputs_arguments(m_vout); show_output_arguments(m_vout); } bool CommandMergeChanges::run() { m_vout << "Opening output file...\n"; osmium::io::Header header; setup_header(header); osmium::io::Writer writer{m_output_file, header, m_output_overwrite, m_fsync}; auto out = osmium::io::make_output_iterator(writer); // this will contain all the buffers with the input data std::vector changes; osmium::ObjectPointerCollection objects; // read all input files, keep the buffers around and add pointer // to each object to objects collection. m_vout << "Reading change file contents...\n"; osmium::ProgressBar progress_bar{file_size_sum(m_input_files), display_progress()}; for (const osmium::io::File& change_file : m_input_files) { osmium::io::Reader reader{change_file, osmium::osm_entity_bits::object}; while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); osmium::apply(buffer, objects); changes.push_back(std::move(buffer)); } progress_bar.file_done(reader.file_size()); reader.close(); } progress_bar.done(); // Now we sort all objects and write them in order into the // output_buffer, flushing the output_buffer whenever it is full. if (m_simplify_change) { // If the --simplify option was given we sort with the // largest version of each object first and then only // copy this last version of any object to the output_buffer. m_vout << "Sorting change data...\n"; // This is needed for a special case: When change files have been // created from extracts it is possible that they contain objects // with the same type, id, version, and timestamp. In that case we // still want to get the last object available. So we have to make // sure it appears first in the objects vector before doing the // stable sort. std::reverse(objects.ptr_begin(), objects.ptr_end()); objects.sort(osmium::object_order_type_id_reverse_version()); m_vout << "Writing last version of each object to output...\n"; std::unique_copy(objects.cbegin(), objects.cend(), out, osmium::object_equal_type_id()); } else { // If the --simplify option was not given, this // is a straightforward sort and copy. m_vout << "Sorting change data...\n"; objects.sort(osmium::object_order_type_id_version()); m_vout << "Writing all objects to output...\n"; std::copy(objects.cbegin(), objects.cend(), out); } m_vout << "Closing output file...\n"; writer.close(); show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_merge_changes.hpp000066400000000000000000000031531474143067200216630ustar00rootroot00000000000000#ifndef COMMAND_MERGE_CHANGES_HPP #define COMMAND_MERGE_CHANGES_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include class CommandMergeChanges : public CommandWithMultipleOSMInputs, public with_osm_output { bool m_simplify_change = false; public: explicit CommandMergeChanges(const CommandFactory& command_factory) : CommandWithMultipleOSMInputs(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "merge-changes"; } const char* synopsis() const noexcept override final { return "osmium merge-changes [OPTIONS] OSM-CHANGE-FILE..."; } }; // class CommandMergeChanges #endif // COMMAND_MERGE_CHANGES_HPP osmium-tool-1.17.0/src/command_query_locations_index.cpp000066400000000000000000000124501474143067200234760ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_query_locations_index.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandQueryLocationsIndex::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("index-file,i", po::value(), "Index file name (required)") ("dump", "Dump all locations to STDOUT") ; const po::options_description opts_common{add_common_options(false)}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("node-id", po::value(), "Node ID") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("node-id", 1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } init_output_file(vm); if (vm.count("index-file")) { m_index_file_name = vm["index-file"].as(); } else { throw argument_error{"Missing --index-file,-i option."}; } if (vm.count("dump")) { m_dump = true; if ((m_output_filename.empty() || m_output_filename == "-") && m_output_format.empty()) { m_output_format = "opl,add_metadata=none"; } if (m_output_format.empty()) { m_output_file = osmium::io::File{m_output_filename}; m_output_file.set("add_metadata", "none"); } else { m_output_file = osmium::io::File{m_output_filename, m_output_format}; } m_output_file.check(); } if (vm.count("node-id")) { if (m_dump) { throw argument_error{"Either use --dump or use node ID, not both."}; } const auto id = vm["node-id"].as(); const auto r = osmium::string_to_object_id(id.c_str(), osmium::osm_entity_bits::node, osmium::item_type::node); m_id = r.second; } else if (!m_dump) { throw argument_error{"Missing node ID on command line."}; } return true; } void CommandQueryLocationsIndex::show_arguments() { show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " index file: " << m_index_file_name << '\n'; } bool CommandQueryLocationsIndex::run() { const int fd = ::open(m_index_file_name.c_str(), O_RDWR); if (fd == -1) { throw std::system_error{errno, std::system_category(), std::string("Can not open index file '") + m_index_file_name + "'"}; } const osmium::index::map::DenseFileArray location_index{fd}; if (m_dump) { const std::size_t max_buffer_size = 11UL * 1024UL * 1024UL; osmium::memory::Buffer buffer{max_buffer_size}; m_vout << "Opening output file...\n"; osmium::io::Header header{}; setup_header(header); osmium::io::Writer writer{m_output_file, header, m_output_overwrite, m_fsync}; m_vout << "Dumping index as OSM file...\n"; for (std::size_t i = 0; i < location_index.size(); ++i) { if (location_index.get_noexcept(i).valid()) { osmium::builder::NodeBuilder builder{buffer}; builder.set_id(static_cast(i)); builder.set_location(location_index.get_noexcept(i)); } buffer.commit(); if (buffer.committed() > 10UL * 1024UL * 1024UL) { writer(std::move(buffer)); buffer = osmium::memory::Buffer{max_buffer_size}; } } if (buffer.committed() > 0) { writer(std::move(buffer)); } } else { m_vout << "Looking up location in index...\n"; const auto location = location_index.get(m_id); std::cout << location << '\n'; } m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_query_locations_index.hpp000066400000000000000000000033371474143067200235070ustar00rootroot00000000000000#ifndef COMMAND_QUERY_LOCATIONS_INDEX_HPP #define COMMAND_QUERY_LOCATIONS_INDEX_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include class CommandQueryLocationsIndex : public Command, public with_osm_output { std::string m_index_file_name; osmium::object_id_type m_id = 0; bool m_dump = false; public: explicit CommandQueryLocationsIndex(const CommandFactory& command_factory) : Command(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "query-locations-index"; } const char* synopsis() const noexcept override final { return "osmium query-locations-index -i INDEX-FILE [OPTIONS] NODE-ID"; } }; // class CommandQueryLocationsIndex #endif // COMMAND_QUERY_LOCATIONS_INDEX_HPP osmium-tool-1.17.0/src/command_removeid.cpp000066400000000000000000000136071474143067200207060ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_removeid.hpp" #include "exception.hpp" #include "id_file.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandRemoveId::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("default-type", po::value()->default_value("node"), "Default item type") ("id-file,i", po::value>(), "Read OSM IDs from text file") ("id-osm-file,I", po::value>(), "Read OSM IDs from OSM file") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "OSM input file") ("ids", po::value>(), "OSM IDs") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); positional.add("ids", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); setup_output_file(vm); if (vm.count("default-type")) { m_default_item_type = parse_item_type(vm["default-type"].as()); } if (vm.count("id-file")) { for (const std::string& filename : vm["id-file"].as>()) { if (filename == "-") { if (m_input_filename.empty() || m_input_filename == "-") { throw argument_error{"Can not read OSM input and IDs both from STDIN."}; } m_vout << "Reading IDs from STDIN...\n"; read_id_file(std::cin, m_ids, m_default_item_type); } else { std::ifstream id_file{filename}; if (!id_file.is_open()) { throw argument_error{"Could not open file '" + filename + "'"}; } m_vout << "Reading ID file...\n"; read_id_file(id_file, m_ids, m_default_item_type); } } } if (vm.count("id-osm-file")) { for (const std::string& filename : vm["id-osm-file"].as>()) { m_vout << "Reading OSM ID file...\n"; read_id_osm_file(filename, m_ids); } } if (vm.count("ids")) { std::string sids; for (const auto& s : vm["ids"].as>()) { sids += s + " "; } for (const auto& s : osmium::split_string(sids, "\t ;,/|", true)) { parse_and_add_id(s, m_ids, m_default_item_type); } } if (no_ids(m_ids)) { throw argument_error{"Please specify IDs to look for on command line or with option --id-file/-i or --id-osm-file/-I."}; } return true; } void CommandRemoveId::show_arguments() { show_single_input_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " default object type: " << osmium::item_type_to_name(m_default_item_type) << "\n"; m_vout << " removing " << m_ids(osmium::item_type::node).size() << " node ID(s), " << m_ids(osmium::item_type::way).size() << " way ID(s), and " << m_ids(osmium::item_type::relation).size() << " relation ID(s)\n"; } bool CommandRemoveId::run() { m_vout << "Opening input file...\n"; osmium::io::Reader reader{m_input_file, osmium::osm_entity_bits::nwr}; m_vout << "Opening output file...\n"; osmium::io::Header header{reader.header()}; setup_header(header); osmium::io::Writer writer{m_output_file, header, m_output_overwrite, m_fsync}; m_vout << "Copying non-matching objects to output file...\n"; osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); for (auto& object : buffer.select()) { if (!m_ids(object.type()).get(object.positive_id())) { writer(object); } } } progress_bar.done(); m_vout << "Closing output file...\n"; writer.close(); m_vout << "Closing input file...\n"; reader.close(); show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_removeid.hpp000066400000000000000000000041501474143067200207040ustar00rootroot00000000000000#ifndef COMMAND_REMOVEID_HPP #define COMMAND_REMOVEID_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include #include #include #include #include #include #include class CommandRemoveId : public CommandWithSingleOSMInput, public with_osm_output { osmium::nwr_array> m_ids; osmium::item_type m_default_item_type = osmium::item_type::node; public: explicit CommandRemoveId(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "removeid"; } const char* synopsis() const noexcept override final { return "osmium removeid [OPTIONS] OSM-FILE ID...\n" " osmium removeid [OPTIONS] OSM-FILE -i ID-FILE\n" " osmium removeid [OPTIONS] OSM-FILE -I ID-OSM-FILE"; } }; // class CommandRemoveId #endif // COMMAND_REMOVEID_HPP osmium-tool-1.17.0/src/command_renumber.cpp000066400000000000000000000357771474143067200207270ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_renumber.hpp" #include "exception.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 # include #endif osmium::object_id_type id_map::add_offset_to_id(osmium::object_id_type id) const noexcept { if (m_start_id < 0) { return -id + m_start_id + 1; } return id + m_start_id - 1; } osmium::object_id_type id_map::operator()(osmium::object_id_type id) { // Search for id in m_extra_ids and return if found. const auto it = m_extra_ids.find(id); if (it != m_extra_ids.end()) { return add_offset_to_id(it->second); } // New ID is larger than all existing IDs. Add it to end and return. if (m_ids.empty() || osmium::id_order{}(m_ids.back(), id)) { m_ids.push_back(id); return add_offset_to_id(static_cast(m_ids.size())); } const auto element = std::lower_bound(m_ids.cbegin(), m_ids.cend(), id, osmium::id_order{}); // Old ID not found in m_ids, add to m_extra_ids. if (element == m_ids.cend() || *element != id) { m_ids.push_back(m_ids.back()); m_extra_ids[id] = static_cast(m_ids.size()); return add_offset_to_id(static_cast(m_ids.size())); } // Old ID found in m_ids, return. return add_offset_to_id(static_cast(std::distance(m_ids.cbegin(), element) + 1)); } void id_map::write(int fd) { for (const auto& m : m_extra_ids) { m_ids[m.second - 1] = m.first; } osmium::io::detail::reliable_write( fd, reinterpret_cast(m_ids.data()), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) sizeof(osmium::object_id_type) * m_ids.size() ); } void id_map::print(osmium::object_id_type new_id) { for (const auto& m : m_extra_ids) { m_ids[m.second - 1] = m.first; } for (const auto& id : m_ids) { std::cout << id << ' ' << new_id << '\n'; if (new_id > 0) { ++new_id; } else { --new_id; } } } void id_map::read(int fd, std::size_t file_size) { const auto num_elements = file_size / sizeof(osmium::object_id_type); m_ids.reserve(num_elements); const osmium::TypedMemoryMapping mapping{num_elements, osmium::MemoryMapping::mapping_mode::readonly, fd}; osmium::object_id_type last_id = 0; for (const osmium::object_id_type id : mapping) { if (osmium::id_order{}(last_id, id)) { m_ids.push_back(id); last_id = id; } else { m_ids.push_back(last_id); m_extra_ids[id] = static_cast(m_ids.size()); } } } namespace { osmium::object_id_type get_start_id(const std::string& s) { const auto id = osmium::string_to_object_id(s.c_str()); if (id == 0) { return 1; } return id; } } // anonymous namespace void CommandRenumber::set_start_ids(const std::string& str) { const auto start_ids = osmium::split_string(str, ','); if (start_ids.size() == 1) { const auto id = get_start_id(start_ids[0]); m_id_map(osmium::item_type::node).set_start_id(id); m_id_map(osmium::item_type::way).set_start_id(id); m_id_map(osmium::item_type::relation).set_start_id(id); } else if (start_ids.size() == 3) { m_id_map(osmium::item_type::node).set_start_id(get_start_id(start_ids[0])); m_id_map(osmium::item_type::way).set_start_id(get_start_id(start_ids[1])); m_id_map(osmium::item_type::relation).set_start_id(get_start_id(start_ids[2])); } else { throw argument_error{"The --start-id/s option must be followed by exactly 1 ID or 3 IDs separated by commas"}; } } void CommandRenumber::show_index(const std::string& type) { auto t = osmium::item_type::undefined; if (type == "n" || type == "node") { t = osmium::item_type::node; } else if (type == "w" || type == "way") { t = osmium::item_type::way; } else if (type == "r" || type == "relation") { t = osmium::item_type::relation; } else { throw argument_error{"Invalid value for --show-index option. Allowed are 'node', 'way', or 'relation'"}; } read_start_ids_file(); read_index(t); m_id_map(t).print(m_id_map(t).start_id()); } bool CommandRenumber::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("index-directory,i", po::value(), "Index directory") ("object-type,t", po::value>(), "Renumber only objects of given type (node, way, relation)") ("show-index", po::value(), "Show contents of index file") ("start-id,s", po::value(), "Comma separated list of first node, way, and relation id to use (default: 1,1,1)") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "Input file") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (vm.count("index-directory")) { m_index_directory = vm["index-directory"].as(); } if (vm.count("show-index")) { show_index(vm["show-index"].as()); return false; } if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_object_type_nwr(vm); setup_input_file(vm); setup_output_file(vm); if (vm.count("start-id")) { set_start_ids(vm["start-id"].as()); } return true; } void CommandRenumber::show_arguments() { show_single_input_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " index directory: " << m_index_directory << "\n"; m_vout << " object types that will be renumbered and their start IDs:"; if (osm_entity_bits() & osmium::osm_entity_bits::node) { m_vout << " node (" << m_id_map(osmium::item_type::node).start_id() << ')'; } if (osm_entity_bits() & osmium::osm_entity_bits::way) { m_vout << " way (" << m_id_map(osmium::item_type::way).start_id() << ')'; } if (osm_entity_bits() & osmium::osm_entity_bits::relation) { m_vout << " relation (" << m_id_map(osmium::item_type::relation).start_id() << ')'; } m_vout << "\n"; } void CommandRenumber::renumber(osmium::memory::Buffer& buffer) { for (auto& object : buffer.select()) { switch (object.type()) { case osmium::item_type::node: if (osm_entity_bits() & osmium::osm_entity_bits::node) { m_check_order.node(static_cast(object)); object.set_id(m_id_map(osmium::item_type::node)(object.id())); } break; case osmium::item_type::way: if (osm_entity_bits() & osmium::osm_entity_bits::way) { m_check_order.way(static_cast(object)); object.set_id(m_id_map(osmium::item_type::way)(object.id())); } if (osm_entity_bits() & osmium::osm_entity_bits::node) { for (auto& ref : static_cast(object).nodes()) { ref.set_ref(m_id_map(osmium::item_type::node)(ref.ref())); } } break; case osmium::item_type::relation: if (osm_entity_bits() & osmium::osm_entity_bits::relation) { m_check_order.relation(static_cast(object)); object.set_id(m_id_map(osmium::item_type::relation)(object.id())); } for (auto& member : static_cast(object).members()) { if (osm_entity_bits() & osmium::osm_entity_bits::from_item_type(member.type())) { member.set_ref(m_id_map(member.type())(member.ref())); } } break; default: break; } } } std::string CommandRenumber::filename(const char* name) const { return m_index_directory + "/" + name + ".idx"; } void CommandRenumber::read_index(osmium::item_type type) { const std::string f{filename(osmium::item_type_to_name(type))}; const int fd = ::open(f.c_str(), O_RDWR); if (fd < 0) { // if the file is not there we don't have to read anything and can return if (errno == ENOENT) { return; } throw std::system_error{errno, std::system_category(), "Could not open file '" + f + "'"}; } #ifdef _WIN32 _setmode(fd, _O_BINARY); #endif const std::size_t file_size = osmium::file_size(fd); if (file_size % sizeof(osmium::object_id_type) != 0) { throw std::runtime_error{std::string{"Index file '"} + f + "' has wrong file size"}; } m_id_map(type).read(fd, file_size); close(fd); } void CommandRenumber::write_index(osmium::item_type type) { if (!(osm_entity_bits() & osmium::osm_entity_bits::from_item_type(type))) { return; } const std::string f{filename(osmium::item_type_to_name(type))}; const int fd = ::open(f.c_str(), O_WRONLY | O_CREAT, 0666); // NOLINT(hicpp-signed-bitwise) if (fd < 0) { throw std::system_error{errno, std::system_category(), "Could not open file '" + f + "'"}; } #ifdef _WIN32 _setmode(fd, _O_BINARY); #endif m_id_map(type).write(fd); close(fd); } namespace { void read_relations(const osmium::io::File& input_file, id_map* map) { osmium::io::Reader reader{input_file, osmium::osm_entity_bits::relation}; const auto input = osmium::io::make_input_iterator_range(reader); for (const osmium::Relation& relation : input) { (*map)(relation.id()); } reader.close(); } } // anonymous namespace void CommandRenumber::read_start_ids_file() { std::ifstream start_id_file{m_index_directory + "/start_ids"}; if (start_id_file.is_open()) { std::string line; start_id_file >> line; start_id_file.close(); set_start_ids(line); } } bool CommandRenumber::run() { if (!m_index_directory.empty()) { m_vout << "Reading index files...\n"; read_start_ids_file(); read_index(osmium::item_type::node); read_index(osmium::item_type::way); read_index(osmium::item_type::relation); m_vout << " Nodes index contains " << m_id_map(osmium::item_type::node).size() << " items\n"; m_vout << " Ways index contains " << m_id_map(osmium::item_type::way).size() << " items\n"; m_vout << " Relations index contains " << m_id_map(osmium::item_type::relation).size() << " items\n"; } if (osm_entity_bits() & osmium::osm_entity_bits::relation) { m_vout << "First pass (of two) through input file (reading relations)...\n"; read_relations(m_input_file, &m_id_map(osmium::item_type::relation)); m_vout << "First pass done.\n"; m_vout << "Second pass (of two) through input file...\n"; } else { m_vout << "Single pass through input file (because relation IDs are not mapped)...\n"; } osmium::io::Reader reader{m_input_file}; osmium::io::Header header = reader.header(); setup_header(header); header.set("xml_josm_upload", "false"); header.set("sorting", "Type_then_ID"); osmium::io::Writer writer{m_output_file, header, m_output_overwrite, m_fsync}; osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); renumber(buffer); writer(std::move(buffer)); } progress_bar.done(); reader.close(); m_vout << "Pass done.\n"; m_vout << "Closing output file...\n"; writer.close(); if (!m_index_directory.empty()) { m_vout << "Writing index files...\n"; std::ofstream start_id_file{m_index_directory + "/start_ids"}; start_id_file << m_id_map(osmium::item_type::node).start_id() << ',' << m_id_map(osmium::item_type::way).start_id() << ',' << m_id_map(osmium::item_type::relation).start_id() << '\n'; start_id_file.close(); write_index(osmium::item_type::node); write_index(osmium::item_type::way); write_index(osmium::item_type::relation); } if (osm_entity_bits() & osmium::osm_entity_bits::node) { m_vout << "Largest (referenced) node id: " << m_id_map(osmium::item_type::node).size() << "\n"; } if (osm_entity_bits() & osmium::osm_entity_bits::way) { m_vout << "Largest (referenced) way id: " << m_id_map(osmium::item_type::way).size() << "\n"; } if (osm_entity_bits() & osmium::osm_entity_bits::relation) { m_vout << "Largest (referenced) relation id: " << m_id_map(osmium::item_type::relation).size() << "\n"; } show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_renumber.hpp000066400000000000000000000110361474143067200207120ustar00rootroot00000000000000#ifndef COMMAND_RENUMBER_HPP #define COMMAND_RENUMBER_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include #include #include #include #include /** * Holds the mapping from old IDs to new IDs of one object type. */ class id_map { // Internally this uses two different means of storing the mapping: // // Most of the old IDs are stored in a sorted vector. The index into the // vector is the new ID. All IDs from the nodes, ways, and relations // themselves will end up here. std::vector m_ids; // For IDs that can't be written into the sorted vector because this would // destroy the sorting, a hash map is used. These are the IDs not read // in order, ie the node IDs referenced from the ways and the member IDs // referenced from the relations. std::unordered_map m_extra_ids; // Because we still have to allocate unique new IDs for the mappings // ending up in m_extra_ids, we add dummy IDs of the same value as the // last one to the end of the m_ids vector. This gives us new IDs without // destroying the ordering of m_ids. But to find a new ID from an old ID // in m_ids we have to take the first of potentially several identical // IDs we find (using std::lower_bound), its position is then the new ID. osmium::object_id_type m_start_id = 1; public: id_map() = default; osmium::object_id_type start_id() const noexcept { return m_start_id; } void set_start_id(osmium::object_id_type start_id) noexcept { m_start_id = start_id; } osmium::object_id_type add_offset_to_id(osmium::object_id_type id) const noexcept; // Map from old ID to new ID. If the old ID has been seen before, it will // be returned, otherwise a new ID will be allocated and stored. osmium::object_id_type operator()(osmium::object_id_type id); // Write the mappings into a file in binary form. This will first copy // the mappings from m_extra_ids into the m_ids vector. After this // operation this object becomes unusable! void write(int fd); void print(osmium::object_id_type new_id); // Read the mappings from a binary file into m_ids and m_extra_ids. void read(int fd, std::size_t file_size); // The number of mappings currently existing. Also the last allocated // new ID. std::size_t size() const noexcept { return m_ids.size(); } }; // class id_map class CommandRenumber : public CommandWithSingleOSMInput, public with_osm_output { std::string m_index_directory; osmium::handler::CheckOrder m_check_order; // id mappings for nodes, ways, and relations osmium::nwr_array m_id_map; void renumber(osmium::memory::Buffer& buffer); std::string filename(const char* name) const; void set_start_ids(const std::string& str); void read_start_ids_file(); void read_index(osmium::item_type type); void write_index(osmium::item_type type); void show_index(const std::string& type); public: explicit CommandRenumber(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "renumber"; } const char* synopsis() const noexcept override final { return "osmium renumber [OPTIONS] OSM-FILE"; } }; // class CommandRenumber #endif // COMMAND_RENUMBER_HPP osmium-tool-1.17.0/src/command_show.cpp000066400000000000000000000166121474143067200200530ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_show.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef _WIN32 # include #endif #ifndef _WIN32 void CommandShow::setup_pager_from_env() noexcept { m_pager = "less"; const char* pager = ::getenv("OSMIUM_PAGER"); // NOLINT(concurrency-mt-unsafe) if (pager) { m_pager = pager; } else { pager = ::getenv("PAGER"); // NOLINT(concurrency-mt-unsafe) if (pager) { m_pager = pager; } } if (m_pager == "cat") { m_pager = ""; } } #endif bool CommandShow::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("format-debug,d", "Use debug format") ("format-opl,o", "Use OPL format") ("format-xml,x", "Use XML format") #ifndef _WIN32 ("no-pager", "Do not run pager program") #endif ("object-type,t", po::value>(), "Read only objects of given type (node, way, relation, changeset)") ("output-format,f", po::value(), "Format of output file") ; const po::options_description opts_common{add_common_options(false)}; const po::options_description opts_input{add_single_input_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "Input file") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_object_type_nwrc(vm); setup_input_file(vm); #ifndef _WIN32 if (vm.count("no-pager")) { m_pager = ""; } else { setup_pager_from_env(); } #endif if (vm.count("output-format") && vm.count("format-debug") && vm.count("format-opl") && vm.count("format-xml")) { throw argument_error{"You can only use at most one of the following options: --output-format/-f, --format-debug/-d, --format-opl/-o, and --format-xml/-x."}; } if (vm.count("output-format")) { m_output_format = vm["output-format"].as(); } else if (vm.count("format-debug")) { m_output_format = "debug,color=true"; } else if (vm.count("format-opl")) { m_output_format = "opl"; } else if (vm.count("format-xml")) { m_output_format = "xml"; } else { const char* output_format_from_env = ::getenv("OSMIUM_SHOW_FORMAT"); // NOLINT(concurrency-mt-unsafe) if (output_format_from_env) { m_output_format = output_format_from_env; } } m_color_output = m_output_format.find("color=true") != std::string::npos; return true; } void CommandShow::show_arguments() { show_single_input_arguments(m_vout); m_vout << " other options:\n"; m_vout << " file format: " << m_output_format << "\n"; m_vout << " use color: " << yes_no(m_color_output); m_vout << " use pager: " << (m_pager.empty() ? "(no pager)" : m_pager) << "\n"; show_object_types(m_vout); } #ifndef _WIN32 namespace { int execute_pager(const std::string& pager, bool with_color) { int pipefd[2]; if (::pipe(pipefd) < 0) { throw std::system_error{errno, std::system_category(), "Could not run pager: pipe() call failed"}; } const pid_t pid = fork(); if (pid < 0) { throw std::system_error{errno, std::system_category(), "Could not run pager: fork() call failed"}; } if (pid == 0) { // child ::close(pipefd[1]); // close write end of the pipe ::close(0); // close stdin if (::dup2(pipefd[0], 0) < 0) { // put end of pipe as stdin throw std::system_error{errno, std::system_category(), "Could not run pager: dup2() call failed"}; } if (with_color && pager.size() >= 4 && pager.substr(pager.size() - 4, 4) == "less") { ::execlp(pager.c_str(), pager.c_str(), "-R", nullptr); } else { // execute pager without arguments ::execlp(pager.c_str(), pager.c_str(), nullptr); } // Exec will either succeed and never return here, or it fails and // we'll exit. throw std::system_error{errno, std::system_category(), "Could not run pager: execlp() call failed"}; } // parent ::close(pipefd[0]); // close read end of the pipe return pipefd[1]; } } // anonymous namespace #endif bool CommandShow::run() { osmium::io::Reader reader{m_input_file, osm_entity_bits()}; const osmium::io::Header header{reader.header()}; if (m_pager.empty()) { const osmium::io::File file{"-", m_output_format}; osmium::io::Writer writer{file, header}; while (osmium::memory::Buffer buffer = reader.read()) { writer(std::move(buffer)); } writer.close(); } else { #ifndef _WIN32 const int fd = execute_pager(m_pager, m_color_output); if (::dup2(fd, 1) < 0) { // put end of pipe as stdout throw std::system_error{errno, std::system_category(), "Could not run pager: dup2() call failed"}; } ::close(fd); const osmium::io::File file{"-", m_output_format}; osmium::io::Writer writer{file, header}; try { while (osmium::memory::Buffer buffer = reader.read()) { writer(std::move(buffer)); } } catch (const std::system_error& e) { if (e.code().value() != EPIPE) { throw; } } writer.close(); ::close(1); // close stdout to signal EOF to pager int status = 0; const int pid = ::wait(&status); if (pid < 0) { throw std::system_error{errno, std::system_category(), "Could not run pager: wait() call failed"}; } if (WIFEXITED(status) && WEXITSTATUS(status) == 1) { // NOLINT(hicpp-signed-bitwise) throw argument_error{std::string{"Could not run pager '"} + m_pager + "'"}; } #endif } reader.close(); return true; } osmium-tool-1.17.0/src/command_show.hpp000066400000000000000000000031641474143067200200560ustar00rootroot00000000000000#ifndef COMMAND_SHOW_HPP #define COMMAND_SHOW_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include class CommandShow : public CommandWithSingleOSMInput { std::string m_output_format{"debug,color=true"}; std::string m_pager; bool m_color_output = false; void setup_pager_from_env() noexcept; public: explicit CommandShow(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "show"; } const char* synopsis() const noexcept override final { return "osmium show [OPTIONS] OSM-FILE"; } }; // class CommandShow #endif // COMMAND_SHOW_HPP osmium-tool-1.17.0/src/command_sort.cpp000066400000000000000000000211111474143067200200500ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_sort.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandSort::setup(const std::vector& arguments) { const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_multiple_inputs_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filenames", po::value>(), "OSM input files") ("strategy,s", po::value(), "Strategy (default: simple)") ; po::options_description desc; desc.add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filenames", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_files(vm); setup_output_file(vm); if (vm.count("strategy")) { m_strategy = vm["strategy"].as(); if (m_strategy != "simple" && m_strategy != "multipass") { throw argument_error{"Unknown strategy: " + m_strategy}; } } if (m_strategy == "multipass") { if (std::any_of(m_input_filenames.cbegin(), m_input_filenames.cend(), [&](const std::string& name) { return name == "-"; })) { throw argument_error{"Can not read from STDIN when using multipass strategy"}; } } return true; } void CommandSort::show_arguments() { show_multiple_inputs_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " strategy: " << m_strategy << "\n"; } bool CommandSort::run_single_pass() { osmium::io::Writer writer{m_output_file, m_output_overwrite, m_fsync}; std::vector data; osmium::ObjectPointerCollection objects; osmium::Box bounding_box; uint64_t buffers_count = 0; uint64_t buffers_size = 0; uint64_t buffers_capacity = 0; m_vout << "Reading contents of input files...\n"; osmium::ProgressBar progress_bar{file_size_sum(m_input_files), display_progress()}; for (const auto& file : m_input_files) { osmium::io::Reader reader{file, osmium::osm_entity_bits::object}; const osmium::io::Header header{reader.header()}; bounding_box.extend(header.joined_boxes()); while (osmium::memory::Buffer buffer = reader.read()) { ++buffers_count; buffers_size += buffer.committed(); buffers_capacity += buffer.capacity(); progress_bar.update(reader.offset()); osmium::apply(buffer, objects); data.push_back(std::move(buffer)); } progress_bar.file_done(reader.file_size()); reader.close(); } progress_bar.done(); m_vout << "Number of buffers: " << buffers_count << "\n"; m_vout << "Sum of buffer sizes: " << buffers_size << " (" << show_gbytes(buffers_size) << " GB)\n"; if (buffers_capacity != 0) { const auto fill_factor = std::round(100 * static_cast(buffers_size) / static_cast(buffers_capacity)); m_vout << "Sum of buffer capacities: " << buffers_capacity << " (" << show_gbytes(buffers_capacity) << " GB, " << fill_factor << "% full)\n"; } else { m_vout << "Sum of buffer capacities: 0 (0 GB)\n"; } m_vout << "Opening output file...\n"; osmium::io::Header header; setup_header(header); header.set("sorting", "Type_then_ID"); if (bounding_box) { header.add_box(bounding_box); } writer.set_header(header); m_vout << "Sorting data...\n"; objects.sort(osmium::object_order_type_id_version()); m_vout << "Writing out sorted data...\n"; auto out = osmium::io::make_output_iterator(writer); std::copy(objects.begin(), objects.end(), out); m_vout << "Closing output file...\n"; writer.close(); show_memory_used(); m_vout << "Done.\n"; return true; } bool CommandSort::run_multi_pass() { osmium::io::Writer writer{m_output_file, m_output_overwrite, m_fsync}; osmium::Box bounding_box; m_vout << "Reading input file headers...\n"; for (const auto& file : m_input_files) { osmium::io::Reader reader{file, osmium::osm_entity_bits::nothing}; const osmium::io::Header header{reader.header()}; bounding_box.extend(header.joined_boxes()); reader.close(); } m_vout << "Opening output file...\n"; osmium::io::Header header; setup_header(header); if (bounding_box) { header.add_box(bounding_box); } writer.set_header(header); osmium::ProgressBar progress_bar{file_size_sum(m_input_files) * 3, display_progress()}; int pass = 1; for (const auto entity : {osmium::osm_entity_bits::node, osmium::osm_entity_bits::way, osmium::osm_entity_bits::relation}) { std::vector data; osmium::ObjectPointerCollection objects; uint64_t buffers_count = 0; uint64_t buffers_size = 0; uint64_t buffers_capacity = 0; m_vout << "Pass " << pass++ << "...\n"; m_vout << "Reading contents of input files...\n"; for (const auto& file : m_input_files) { osmium::io::Reader reader{file, entity}; const osmium::io::Header read_header{reader.header()}; bounding_box.extend(read_header.joined_boxes()); while (osmium::memory::Buffer buffer = reader.read()) { ++buffers_count; buffers_size += buffer.committed(); buffers_capacity += buffer.capacity(); progress_bar.update(reader.offset()); osmium::apply(buffer, objects); data.push_back(std::move(buffer)); } progress_bar.file_done(reader.file_size()); reader.close(); } if (m_vout.verbose()) { progress_bar.remove(); } m_vout << "Number of buffers: " << buffers_count << "\n"; m_vout << "Sum of buffer sizes: " << buffers_size << " (" << show_gbytes(buffers_size) << " GB)\n"; if (buffers_capacity != 0) { const auto fill_factor = std::round(100 * static_cast(buffers_size) / static_cast(buffers_capacity)); m_vout << "Sum of buffer capacities: " << buffers_capacity << " (" << show_gbytes(buffers_capacity) << " GB, " << fill_factor << "% full)\n"; } else { m_vout << "Sum of buffer capacities: 0 (0 GB)\n"; } m_vout << "Sorting data...\n"; objects.sort(osmium::object_order_type_id_version()); m_vout << "Writing out sorted data...\n"; auto out = osmium::io::make_output_iterator(writer); std::copy(objects.begin(), objects.end(), out); } progress_bar.done(); m_vout << "Closing output file...\n"; writer.close(); show_memory_used(); m_vout << "Done.\n"; return true; } bool CommandSort::run() { if (m_strategy == "simple") { return run_single_pass(); } return run_multi_pass(); } osmium-tool-1.17.0/src/command_sort.hpp000066400000000000000000000031321474143067200200600ustar00rootroot00000000000000#ifndef COMMAND_SORT_HPP #define COMMAND_SORT_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include class CommandSort : public CommandWithMultipleOSMInputs, public with_osm_output { std::string m_strategy{"simple"}; public: explicit CommandSort(const CommandFactory& command_factory) : CommandWithMultipleOSMInputs(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run_single_pass(); bool run_multi_pass(); bool run() override final; const char* name() const noexcept override final { return "sort"; } const char* synopsis() const noexcept override final { return "osmium sort [OPTIONS] OSM-FILE..."; } }; // class CommandSort #endif // COMMAND_SORT_HPP osmium-tool-1.17.0/src/command_tags_count.cpp000066400000000000000000000223451474143067200212410ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_tags_count.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include void CommandTagsCount::add_matcher(const std::string& expression) { bool has_value_matcher = false; auto matcher = get_tag_matcher(expression, &has_value_matcher); if (has_value_matcher) { m_tags_filter.add_rule(true, std::move(matcher)); } else { m_keys_filter.add_rule(true, std::move(matcher)); } } void CommandTagsCount::read_expressions_file(const std::string& file_name) { m_vout << "Reading expressions file...\n"; std::ifstream file{file_name}; if (!file.is_open()) { throw argument_error{"Could not open file '" + file_name + "'"}; } for (std::string line; std::getline(file, line);) { const auto pos = line.find_first_of('#'); if (pos != std::string::npos) { line.erase(pos); } if (!line.empty()) { if (line.back() == '\r') { line.resize(line.size() - 1); } add_matcher(line); } } } namespace { sort_func_type get_sort_function(const std::string& sort_order) { static const std::pair sort_options[] = { { "count-desc", [](const element_type& a, const element_type& b){ if (a.count == b.count) { return *a.name < *b.name; } return a.count > b.count; } }, { "count-asc", [](const element_type& a, const element_type& b){ if (a.count == b.count) { return *a.name < *b.name; } return a.count < b.count; } }, { "name-desc", [](const element_type& a, const element_type& b){ return *a.name > *b.name; } }, { "name-asc", [](const element_type& a, const element_type& b){ return *a.name < *b.name; } } }; for (const auto& nf : sort_options) { if (nf.first == sort_order) { return nf.second; } } throw argument_error{"Unknown sort order '" + sort_order + "'"}; } } // anonymous namespace bool CommandTagsCount::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("expressions,e", po::value(), "Read tag expressions from file") ("min-count,m", po::value(), "Min count shown (default: 0)") ("max-count,M", po::value(), "Max count shown (default: none)") ("output,o", po::value(), "Output file (default: stdout)") ("overwrite,O", "Allow existing output file to be overwritten") ("sort,s", po::value(), "Sort order of results ('count-asc', 'count-desc' (default), 'name-asc', or 'name-desc')") ("object-type,t", po::value>(), "Read only objects of given type (node, way, relation)") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "OSM input file") ("expression-list", po::value>(), "Count expressions") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); positional.add("expression-list", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_object_type_nwr(vm); setup_input_file(vm); if (vm.count("output")) { m_output_filename = vm["output"].as(); } if (vm.count("overwrite")) { m_output_overwrite = osmium::io::overwrite::allow; } if (vm.count("expression-list")) { for (const auto& e : vm["expression-list"].as>()) { add_matcher(e); } } else { m_keys_filter = osmium::TagsFilter{true}; } if (vm.count("expressions")) { read_expressions_file(vm["expressions"].as()); } if (vm.count("min-count")) { m_min_count = vm["min-count"].as(); } if (vm.count("max-count")) { m_max_count = vm["max-count"].as(); } if (vm.count("sort")) { m_sort_order = vm["sort"].as(); if (m_sort_order == "name") { m_sort_order = "name-asc"; } else if (m_sort_order == "count") { m_sort_order = "count-desc"; } } m_sort_func = get_sort_function(m_sort_order); return true; } void CommandTagsCount::show_arguments() { show_single_input_arguments(m_vout); m_vout << " output options:\n"; m_vout << " file name: " << m_output_filename << '\n'; m_vout << " overwrite: " << yes_no(m_output_overwrite == osmium::io::overwrite::allow); m_vout << " other options:\n"; m_vout << " sort order: " << m_sort_order << '\n'; m_vout << " min count: " << m_min_count << '\n'; if (m_max_count == std::numeric_limits::max()) { m_vout << " max count: (none)\n"; } else { m_vout << " max count: " << m_max_count << '\n'; } } std::vector CommandTagsCount::sort_results() const { std::vector results; results.reserve(m_counts.size()); for (const auto& c : m_counts) { if (c.second >= m_min_count && c.second <= m_max_count) { results.emplace_back(c.first, c.second); } } std::sort(results.begin(), results.end(), m_sort_func); return results; } namespace { void append_escaped(std::string* out, const char* str) { *out += '"'; for (; *str != '\0'; ++str) { if (*str == '"') { *out += '"'; } *out += *str; } *out += '"'; } void write_results(const std::vector& results, int fd) { std::string out; const std::size_t buffer_size = 1024UL * 1024UL; out.reserve(buffer_size); for (const auto& c : results) { out += std::to_string(c.count); out += '\t'; append_escaped(&out, c.name->key()); const char* value = c.name->value(); if (value) { out += '\t'; append_escaped(&out, value); } out += '\n'; if (out.size() > (buffer_size - 1000)) { osmium::io::detail::reliable_write(fd, out.data(), out.size()); out.clear(); } } osmium::io::detail::reliable_write(fd, out.data(), out.size()); close(fd); } } // anonymous namespace bool CommandTagsCount::run() { m_vout << "Opening input file...\n"; osmium::io::Reader reader{m_input_file, osm_entity_bits(), osmium::io::read_meta::no}; m_vout << "Opening output file...\n"; int fd = 1; if (!m_output_filename.empty()) { fd = osmium::io::detail::open_for_writing(m_output_filename, m_output_overwrite); } m_vout << "Count matching keys/tags...\n"; osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); for (const auto& object : buffer.select()) { for (const auto& tag : object.tags()) { if (m_keys_filter(tag)) { ++m_counts[tag.key()]; } if (m_tags_filter(tag)) { ++m_counts[tag]; } } } } progress_bar.done(); m_vout << "Closing input file...\n"; reader.close(); show_memory_used(); m_vout << "Sorting results...\n"; const auto results = sort_results(); show_memory_used(); m_vout << "Writing results...\n"; write_results(results, fd); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_tags_count.hpp000066400000000000000000000106241474143067200212430ustar00rootroot00000000000000#ifndef COMMAND_TAGS_COUNT_HPP #define COMMAND_TAGS_COUNT_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include #include #include #include #include #include /** * This class stores a key or key-value combination in a single std::string. * Key-value combinations are stored as key + \0 + value internally. */ class key_or_tag { std::string m_value; public: key_or_tag(const osmium::Tag& tag) : m_value(tag.key()) { m_value += '\0'; m_value += tag.value(); } key_or_tag(const char* key) : m_value(key) { } /// Return the key. const char* key() const noexcept { return m_value.c_str(); } /// Return value or nullptr if there is no value stored. const char* value() const noexcept { const auto pos = std::strlen(m_value.c_str()); if (pos == m_value.size()) { return nullptr; } return m_value.c_str() + pos + 1; } const std::string& get() const noexcept { return m_value; } friend bool operator==(const key_or_tag& a, const key_or_tag& b) noexcept { return a.get() == b.get(); } friend bool operator!=(const key_or_tag& a, const key_or_tag& b) noexcept { return a.get() != b.get(); } friend bool operator<(const key_or_tag& a, const key_or_tag& b) noexcept { return a.get() < b.get(); } friend bool operator<=(const key_or_tag& a, const key_or_tag& b) noexcept { return a.get() <= b.get(); } friend bool operator>(const key_or_tag& a, const key_or_tag& b) noexcept { return a.get() > b.get(); } friend bool operator>=(const key_or_tag& a, const key_or_tag& b) noexcept { return a.get() >= b.get(); } }; // class key_or_tag using counter_type = uint32_t; struct element_type { const key_or_tag* name; counter_type count; element_type(const key_or_tag& n, counter_type c) : name(&n), count(c) { } }; namespace std { template <> struct hash { std::size_t operator()(const key_or_tag& s) const noexcept { return std::hash{}(s.get()); } }; } // namespace std using sort_func_type = std::function; class CommandTagsCount : public CommandWithSingleOSMInput, public with_osm_output { osmium::TagsFilter m_keys_filter; osmium::TagsFilter m_tags_filter; std::string m_sort_order{"count-desc"}; sort_func_type m_sort_func; std::unordered_map m_counts; counter_type m_min_count = 0; counter_type m_max_count = std::numeric_limits::max(); void add_matcher(const std::string& expression); void read_expressions_file(const std::string& file_name); std::vector sort_results() const; public: explicit CommandTagsCount(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "tags-count"; } const char* synopsis() const noexcept override final { return "osmium tags-count [OPTIONS] OSM-FILE [TAG-EXPRESSION...]\n" " osmium tags-count [OPTIONS] --expressions=FILE OSM-FILE"; } }; // class CommandTagsCount #endif // COMMAND_TAGS_COUNT_HPP osmium-tool-1.17.0/src/command_tags_filter.cpp000066400000000000000000000336461474143067200214040ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_tags_filter.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void CommandTagsFilter::add_filter(osmium::osm_entity_bits::type entities, const osmium::TagMatcher& matcher) { if (entities & osmium::osm_entity_bits::node) { m_filters(osmium::item_type::node).add_rule(true, matcher); } if (entities & osmium::osm_entity_bits::way) { m_filters(osmium::item_type::way).add_rule(true, matcher); } if (entities & osmium::osm_entity_bits::relation) { m_filters(osmium::item_type::relation).add_rule(true, matcher); } if (entities & osmium::osm_entity_bits::area) { m_area_filters.add_rule(true, matcher); } } void CommandTagsFilter::parse_and_add_expression(const std::string& expression) { const auto p = get_filter_expression(expression); add_filter(p.first, get_tag_matcher(p.second)); } void CommandTagsFilter::read_expressions_file(const std::string& file_name) { m_vout << "Reading expressions file...\n"; std::ifstream file{file_name}; if (!file.is_open()) { throw argument_error{"Could not open file '" + file_name + "'"}; } for (std::string line; std::getline(file, line);) { const auto pos = line.find_first_of('#'); if (pos != std::string::npos) { line.erase(pos); } if (!line.empty()) { if (line.back() == '\r') { line.resize(line.size() - 1); } parse_and_add_expression(line); } } } bool CommandTagsFilter::setup(const std::vector& arguments) { po::options_description opts_cmd{"COMMAND OPTIONS"}; opts_cmd.add_options() ("expressions,e", po::value(), "Read filter expressions from file") ("invert-match,i", "Invert the sense of matching, exclude objects with matching tags") ("omit-referenced,R", "Omit referenced objects") ("remove-tags,t", "Remove tags from non-matching objects") ; const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "OSM input file") ("expression-list", po::value>(), "Filter expressions") ; po::options_description desc; desc.add(opts_cmd).add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); positional.add("expression-list", -1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); setup_output_file(vm); if (vm.count("omit-referenced")) { m_add_referenced_objects = false; } else if (m_input_filename == "-") { throw argument_error{"Can not read OSM input from STDIN (unless --omit-referenced/-R option is used)."}; } if (vm.count("invert-match")) { m_invert_match = true; } if (vm.count("remove-tags")) { m_remove_tags = true; } if (vm.count("expression-list")) { for (const auto& e : vm["expression-list"].as>()) { parse_and_add_expression(e); } } if (vm.count("expressions")) { read_expressions_file(vm["expressions"].as()); } return true; } void CommandTagsFilter::show_arguments() { show_single_input_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " add referenced objects: " << yes_no(m_add_referenced_objects); m_vout << " invert match: " << yes_no(m_invert_match); if (m_add_referenced_objects) { m_vout << " remove tags on non-matching objects: " << yes_no(m_remove_tags); } m_vout << " looking for tags...\n"; m_vout << " on nodes: " << yes_no(!m_filters(osmium::item_type::node).empty()); m_vout << " on ways: " << yes_no(!m_filters(osmium::item_type::way).empty() || !m_area_filters.empty()); m_vout << " on relations: " << yes_no(!m_filters(osmium::item_type::relation).empty() || !m_area_filters.empty()); } osmium::osm_entity_bits::type CommandTagsFilter::get_needed_types() const { if (m_invert_match) { return osmium::osm_entity_bits::nwr; } osmium::osm_entity_bits::type types = osmium::osm_entity_bits::nothing; if (!m_referenced_ids(osmium::item_type::node).empty() || !m_filters(osmium::item_type::node).empty()) { types |= osmium::osm_entity_bits::node; } if (!m_referenced_ids(osmium::item_type::way).empty() || !m_filters(osmium::item_type::way).empty() || !m_area_filters.empty()) { types |= osmium::osm_entity_bits::way; } if (!m_referenced_ids(osmium::item_type::relation).empty() || !m_filters(osmium::item_type::relation).empty() || !m_area_filters.empty()) { types |= osmium::osm_entity_bits::relation; } return types; } void CommandTagsFilter::add_nodes(const osmium::Way& way) { for (const auto& nr : way.nodes()) { m_referenced_ids(osmium::item_type::node).set(nr.positive_ref()); } } void CommandTagsFilter::add_members(const osmium::Relation& relation) { for (const auto& member : relation.members()) { m_referenced_ids(member.type()).set(member.positive_ref()); } } bool CommandTagsFilter::matches_node(const osmium::Node& node) const noexcept { return osmium::tags::match_any_of(node.tags(), m_filters(osmium::item_type::node)); } bool CommandTagsFilter::matches_way(const osmium::Way& way) const noexcept { return osmium::tags::match_any_of(way.tags(), m_filters(osmium::item_type::way)) || (way.nodes().size() >= 4 && way.is_closed() && osmium::tags::match_any_of(way.tags(), m_area_filters)); } namespace { bool is_multipolygon(const osmium::Relation& relation) noexcept { const char* type = relation.tags().get_value_by_key("type"); if (type == nullptr) { return false; } return !std::strcmp(type, "multipolygon") || !std::strcmp(type, "boundary"); } } // anonymous namespace bool CommandTagsFilter::matches_relation(const osmium::Relation& relation) const noexcept { return osmium::tags::match_any_of(relation.tags(), m_filters(osmium::item_type::relation)) || (is_multipolygon(relation) && osmium::tags::match_any_of(relation.tags(), m_area_filters)); } bool CommandTagsFilter::matches_object(const osmium::OSMObject& object) const noexcept { switch (object.type()) { case osmium::item_type::node: return matches_node(static_cast(object)); case osmium::item_type::way: return matches_way(static_cast(object)); case osmium::item_type::relation: return matches_relation(static_cast(object)); default: break; } return false; } void CommandTagsFilter::mark_rel_ids(const osmium::index::RelationsMapIndex& rel_in_rel, osmium::unsigned_object_id_type parent_id) { rel_in_rel.for_each(parent_id, [&](osmium::unsigned_object_id_type member_id) { if (m_referenced_ids(osmium::item_type::relation).check_and_set(member_id)) { mark_rel_ids(rel_in_rel, member_id); } }); } bool CommandTagsFilter::find_relations_in_relations() { m_vout << " Reading input file to find relations in relations...\n"; osmium::index::RelationsMapStash stash; ++m_count_passes; osmium::io::Reader reader{m_input_file, osmium::osm_entity_bits::relation}; while (osmium::memory::Buffer buffer = reader.read()) { for (const auto& relation : buffer.select()) { stash.add_members(relation); if (matches_relation(relation) != m_invert_match) { m_matching_ids(osmium::item_type::relation).set(relation.positive_id()); for (const auto& member : relation.members()) { if (member.type() == osmium::item_type::node) { m_referenced_ids(osmium::item_type::node).set(member.positive_ref()); } else if (member.type() == osmium::item_type::way) { m_referenced_ids(osmium::item_type::way).set(member.positive_ref()); } } } } } reader.close(); if (stash.empty()) { return false; } const auto rel_in_rel = stash.build_parent_to_member_index(); for (const auto id : m_matching_ids(osmium::item_type::relation)) { mark_rel_ids(rel_in_rel, id); } return true; } void CommandTagsFilter::find_nodes_and_ways_in_relations() { m_vout << " Reading input file to find nodes/ways in relations...\n"; ++m_count_passes; osmium::io::Reader reader{m_input_file, osmium::osm_entity_bits::relation}; while (osmium::memory::Buffer buffer = reader.read()) { for (const auto& relation : buffer.select()) { if (m_referenced_ids(osmium::item_type::relation).get(relation.positive_id())) { for (const auto& member : relation.members()) { if (member.type() == osmium::item_type::node) { m_referenced_ids(osmium::item_type::node).set(member.positive_ref()); } else if (member.type() == osmium::item_type::way) { m_referenced_ids(osmium::item_type::way).set(member.positive_ref()); } } } } } reader.close(); } void CommandTagsFilter::find_nodes_in_ways() { m_vout << " Reading input file to find nodes in ways...\n"; ++m_count_passes; osmium::io::Reader reader{m_input_file, osmium::osm_entity_bits::way}; while (osmium::memory::Buffer buffer = reader.read()) { for (const auto& way : buffer.select()) { if (matches_way(way) != m_invert_match) { m_matching_ids(osmium::item_type::way).set(way.positive_id()); add_nodes(way); } else if (m_referenced_ids(osmium::item_type::way).get(way.positive_id())) { add_nodes(way); } } } reader.close(); } void CommandTagsFilter::find_referenced_objects() { m_vout << "Following references...\n"; bool todo = !m_filters(osmium::item_type::relation).empty() || !m_area_filters.empty() || m_invert_match; if (todo) { todo = find_relations_in_relations(); } if (todo) { find_nodes_and_ways_in_relations(); } if (!m_referenced_ids(osmium::item_type::way).empty() || !m_filters(osmium::item_type::way).empty() || !m_area_filters.empty()) { find_nodes_in_ways(); } m_vout << "Done following references.\n"; } void CommandTagsFilter::copy_matching_objects(osmium::io::Reader& reader, osmium::io::Writer& writer) { m_vout << "Copying matching objects to output file...\n"; ++m_count_passes; osmium::ProgressBar progress_bar{reader.file_size(), display_progress()}; while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); for (auto& object : buffer.select()) { if (m_matching_ids(object.type()).get(object.positive_id())) { writer(object); } else if ((!m_add_referenced_objects || object.type() == osmium::item_type::node) && matches_object(object) != m_invert_match) { writer(object); } else if (m_referenced_ids(object.type()).get(object.positive_id())) { if (m_remove_tags) { object.remove_tags(); } writer(object); } } } progress_bar.done(); } bool CommandTagsFilter::run() { m_vout << "Opening output file...\n"; osmium::io::Writer writer{m_output_file, m_output_overwrite, m_fsync}; if (m_add_referenced_objects) { find_referenced_objects(); } m_vout << "Opening input file...\n"; osmium::io::Reader reader{m_input_file, get_needed_types()}; osmium::io::Header header{reader.header()}; setup_header(header); writer.set_header(header); copy_matching_objects(reader, writer); m_vout << "Closing output file...\n"; writer.close(); m_vout << "Closing input file...\n"; reader.close(); show_memory_used(); m_vout << "Needed " << m_count_passes << " pass(es) through the input file.\n"; m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_tags_filter.hpp000066400000000000000000000066301474143067200214020ustar00rootroot00000000000000#ifndef COMMAND_TAGS_FILTER_HPP #define COMMAND_TAGS_FILTER_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include #include #include #include #include #include #include #include #include #include class CommandTagsFilter : public CommandWithSingleOSMInput, public with_osm_output { osmium::nwr_array m_filters; osmium::TagsFilter m_area_filters; osmium::nwr_array> m_matching_ids; osmium::nwr_array> m_referenced_ids; int m_count_passes = 0; bool m_add_referenced_objects = true; bool m_invert_match = false; bool m_remove_tags = false; osmium::osm_entity_bits::type get_needed_types() const; void find_referenced_objects(); void add_nodes(const osmium::Way& way); void add_members(const osmium::Relation& relation); bool matches_node(const osmium::Node& node) const noexcept; bool matches_way(const osmium::Way& way) const noexcept; bool matches_relation(const osmium::Relation& relation) const noexcept; bool matches_object(const osmium::OSMObject& object) const noexcept; void mark_rel_ids(const osmium::index::RelationsMapIndex& rel_in_rel, osmium::unsigned_object_id_type parent_id); bool find_relations_in_relations(); void find_nodes_and_ways_in_relations(); void find_nodes_in_ways(); void add_filter(osmium::osm_entity_bits::type entities, const osmium::TagMatcher& matcher); void parse_and_add_expression(const std::string& expression); void read_expressions_file(const std::string& file_name); void copy_matching_objects(osmium::io::Reader& reader, osmium::io::Writer& writer); public: explicit CommandTagsFilter(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "tags-filter"; } const char* synopsis() const noexcept override final { return "osmium tags-filter [OPTIONS] OSM-FILE FILTER-EXPRESSION...\n" " osmium tags-filter [OPTIONS] --expressions=FILE OSM-FILE"; } }; // class CommandTagsFilter #endif // COMMAND_TAGS_FILTER_HPP osmium-tool-1.17.0/src/command_time_filter.cpp000066400000000000000000000130711474143067200213720ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "command_time_filter.hpp" #include "exception.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CommandTimeFilter::setup(const std::vector& arguments) { const po::options_description opts_common{add_common_options()}; const po::options_description opts_input{add_single_input_options()}; const po::options_description opts_output{add_output_options()}; po::options_description hidden; hidden.add_options() ("input-filename", po::value(), "OSM input file") ("time-from", po::value(), "Start of time range") ("time-to", po::value(), "End of time range") ; po::options_description desc; desc.add(opts_common).add(opts_input).add(opts_output); po::options_description parsed_options; parsed_options.add(desc).add(hidden); po::positional_options_description positional; positional.add("input-filename", 1); positional.add("time-from", 1); positional.add("time-to", 1); po::variables_map vm; po::store(po::command_line_parser(arguments).options(parsed_options).positional(positional).run(), vm); po::notify(vm); if (!setup_common(vm, desc)) { return false; } setup_progress(vm); setup_input_file(vm); setup_output_file(vm); m_from = osmium::Timestamp{std::time(nullptr)}; m_to = m_from; if (vm.count("time-from")) { const auto ts = vm["time-from"].as(); try { m_from = osmium::Timestamp{ts}; } catch (const std::invalid_argument&) { throw argument_error{"Wrong format for (first) timestamp (use YYYY-MM-DDThh:mm:ssZ)."}; } m_to = m_from; } if (vm.count("time-to")) { const auto ts = vm["time-to"].as(); try { m_to = osmium::Timestamp{ts}; } catch (const std::invalid_argument&) { throw argument_error{"Wrong format for second timestamp (use YYYY-MM-DDThh:mm:ssZ)."}; } } if (m_from > m_to) { throw argument_error{"Second timestamp is before first one."}; } if (m_from == m_to) { // point in time if (m_output_file.has_multiple_object_versions()) { warning("You are writing to a file marked as having multiple object versions,\n" "but there will be only a single version of each object.\n"); } } else { // time range if (!m_output_file.has_multiple_object_versions()) { warning("You are writing to a file marked as having a single object version,\n" "but there might be multiple versions of each object.\n"); } } return true; } void CommandTimeFilter::show_arguments() { show_single_input_arguments(m_vout); show_output_arguments(m_vout); m_vout << " other options:\n"; m_vout << " Filtering from time " << m_from.to_iso() << " to " << m_to.to_iso() << "\n"; } bool CommandTimeFilter::run() { m_vout << "Opening input file...\n"; osmium::io::ReaderWithProgressBar reader{display_progress(), m_input_file, osmium::osm_entity_bits::object}; m_vout << "Opening output file...\n"; osmium::io::Header header{reader.header()}; setup_header(header); osmium::io::Writer writer{m_output_file, header, m_output_overwrite, m_fsync}; m_vout << "Filter data while copying it from input to output...\n"; auto input = osmium::io::make_input_iterator_range(reader); auto diff_begin = osmium::make_diff_iterator(input.begin(), input.end()); auto diff_end = osmium::make_diff_iterator(input.end(), input.end()); auto out = osmium::io::make_output_iterator(writer); if (m_from == m_to) { std::copy_if( diff_begin, diff_end, out, [this](const osmium::DiffObject& d) { return d.is_visible_at(m_from); }); } else { std::copy_if( diff_begin, diff_end, out, [this](const osmium::DiffObject& d) { return d.is_between(m_from, m_to); }); } m_vout << "Closing output file...\n"; writer.close(); m_vout << "Closing input file...\n"; reader.close(); show_memory_used(); m_vout << "Done.\n"; return true; } osmium-tool-1.17.0/src/command_time_filter.hpp000066400000000000000000000033571474143067200214050ustar00rootroot00000000000000#ifndef COMMAND_TIME_FILTER_HPP #define COMMAND_TIME_FILTER_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" // IWYU pragma: export #include #include #include class CommandTimeFilter : public CommandWithSingleOSMInput, public with_osm_output { osmium::Timestamp m_from; osmium::Timestamp m_to; public: explicit CommandTimeFilter(const CommandFactory& command_factory) : CommandWithSingleOSMInput(command_factory) { } bool setup(const std::vector& arguments) override final; void show_arguments() override final; bool run() override final; const char* name() const noexcept override final { return "time-filter"; } const char* synopsis() const noexcept override final { return "osmium time-filter [OPTIONS] OSM-HISTORY-FILE [TIME]\n" " osmium time-filter [OPTIONS] OSM-HISTORY-FILE FROM-TIME TO-TIME"; } }; // class CommandTimeFilter #endif // COMMAND_TIME_FILTER_HPP osmium-tool-1.17.0/src/commands.cpp000066400000000000000000000114141474143067200171710ustar00rootroot00000000000000 #include "cmd.hpp" #include "command_add_locations_to_ways.hpp" #include "command_apply_changes.hpp" #include "command_cat.hpp" #include "command_changeset_filter.hpp" #include "command_check_refs.hpp" #include "command_create_locations_index.hpp" #include "command_derive_changes.hpp" #include "command_diff.hpp" #include "command_export.hpp" #include "command_extract.hpp" #include "command_fileinfo.hpp" #include "command_getid.hpp" #include "command_getparents.hpp" #include "command_help.hpp" #include "command_merge.hpp" #include "command_merge_changes.hpp" #include "command_query_locations_index.hpp" #include "command_removeid.hpp" #include "command_renumber.hpp" #include "command_show.hpp" #include "command_sort.hpp" #include "command_tags_count.hpp" #include "command_tags_filter.hpp" #include "command_time_filter.hpp" void register_commands(CommandFactory& cmd_factory) { cmd_factory.register_command("add-locations-to-ways", "Add node locations to ways", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("apply-changes", "Apply OSM change files to OSM data file", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("cat", "Concatenate OSM files and convert to different formats", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("changeset-filter", "Filter OSM changesets by different criteria", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("check-refs", "Check referential integrity of an OSM file", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("create-locations-index", "Create node locations index on disk", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("derive-changes", "Create OSM change files from two OSM data files", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("diff", "Display differences between OSM files", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("export", "Export OSM data", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("extract", "Create geographic extract", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("fileinfo", "Show information about OSM file", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("getid", "Get objects with given ID from OSM file", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("getparents", "Get parents of objects from OSM file", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("help", "Show osmium help", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("merge-changes", "Merge several OSM change files into one", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("merge", "Merge several sorted OSM files into one", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("query-locations-index", "Query node locations index on disk", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("removeid", "Remove objects from OSM file by ID", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("renumber", "Renumber IDs in OSM file", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("show", "Show OSM file contents", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("sort", "Sort OSM data files", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("tags-count", "Count OSM tags", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("tags-filter", "Filter OSM data based on tags", [&]() { return std::make_unique(cmd_factory); }); cmd_factory.register_command("time-filter", "Filter OSM data from a point in time or a time span out of a history file", [&]() { return std::make_unique(cmd_factory); }); } osmium-tool-1.17.0/src/exception.hpp000066400000000000000000000035601474143067200173760ustar00rootroot00000000000000#ifndef EXCEPTION_HPP #define EXCEPTION_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include #include /** * Thrown when there is a problem with the command line arguments. */ struct argument_error : std::runtime_error { explicit argument_error(const char* message) : std::runtime_error(message) { } explicit argument_error(const std::string& message) : std::runtime_error(message) { } }; /** * Thrown when there is a problem with parsing a JSON config file. */ struct config_error : public std::runtime_error { explicit config_error(const char* message) : std::runtime_error(message) { } explicit config_error(const std::string& message) : std::runtime_error(message) { } }; // struct config_error /** * Thrown when there is a problem with parsing a GeoJSON file. */ struct geojson_error : public std::runtime_error { explicit geojson_error(const char* message) : std::runtime_error(message) { } explicit geojson_error(const std::string& message) : std::runtime_error(message) { } }; // struct geojson_error #endif // EXCEPTION_HPP osmium-tool-1.17.0/src/export/000077500000000000000000000000001474143067200162045ustar00rootroot00000000000000osmium-tool-1.17.0/src/export/export_format.hpp000066400000000000000000000065261474143067200216170ustar00rootroot00000000000000#ifndef EXPORT_EXPORT_FORMAT_HPP #define EXPORT_EXPORT_FORMAT_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "options.hpp" #include #include #include #include #include class ExportFormat { const options_type& m_options; protected: std::uint64_t m_count; explicit ExportFormat(const options_type& options) : m_options(options), m_count(0) { } public: const options_type& options() const noexcept { return m_options; } std::uint64_t count() const noexcept { return m_count; } virtual ~ExportFormat() = default; virtual void node(const osmium::Node&) = 0; virtual void way(const osmium::Way&) = 0; virtual void area(const osmium::Area&) = 0; virtual void close() = 0; virtual void debug_output(osmium::VerboseOutput& /*out*/, const std::string& /*filename*/) { } template bool add_tags(const osmium::OSMObject& object, TFunc&& func) { bool has_tags = false; for (const auto& tag : object.tags()) { if (options().tags_filter(tag)) { // If the tag key looks like any of the attribute keys, drop // the tag on the floor. This should be okay for most cases // when the attribute name chosen is sufficiently special. if (!options().type.empty() && tag.key() == options().type) { continue; } if (!options().id.empty() && tag.key() == options().id) { continue; } if (!options().version.empty() && tag.key() == options().version) { continue; } if (!options().changeset.empty() && tag.key() == options().changeset) { continue; } if (!options().uid.empty() && tag.key() == options().uid) { continue; } if (!options().user.empty() && tag.key() == options().user) { continue; } if (!options().timestamp.empty() && tag.key() == options().timestamp) { continue; } if (!options().way_nodes.empty() && tag.key() == options().way_nodes) { continue; } has_tags = true; std::forward(func)(tag); } } return has_tags; } }; // class ExportFormat #endif // EXPORT_EXPORT_FORMAT_HPP osmium-tool-1.17.0/src/export/export_format_json.cpp000066400000000000000000000206211474143067200226330ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "export_format_json.hpp" #include "../exception.hpp" #include "../util.hpp" #include #include #include #include #include #include static constexpr const std::size_t initial_buffer_size = 1024UL * 1024UL; static constexpr const std::size_t flush_buffer_size = 800UL * 1024UL; ExportFormatJSON::ExportFormatJSON(const std::string& output_format, const std::string& output_filename, osmium::io::overwrite overwrite, osmium::io::fsync fsync, const options_type& options) : ExportFormat(options), m_fd(osmium::io::detail::open_for_writing(output_filename, overwrite)), m_fsync(fsync), m_text_sequence_format(output_format == "geojsonseq"), m_with_record_separator(m_text_sequence_format && options.format_options.is_true("print_record_separator")) { m_buffer.reserve(initial_buffer_size); if (!m_text_sequence_format) { m_buffer += R"({"type":"FeatureCollection","features":[)"; m_buffer += '\n'; } m_committed_size = m_buffer.size(); if (output_format == "geojsonseq") { const auto prs = options.format_options.get("print_record_separator"); if (prs != "true" && prs != "false") { throw config_error{"Unknown value for print_record_separator option: '" + prs + "'."}; } } } void ExportFormatJSON::flush_to_output() { osmium::io::detail::reliable_write(m_fd, m_buffer.data(), m_buffer.size()); m_buffer.clear(); m_committed_size = 0; } void ExportFormatJSON::start_feature(const std::string& prefix, osmium::object_id_type id) { rollback_uncomitted(); if (m_count > 0) { if (!m_text_sequence_format) { m_buffer += ','; } m_buffer += '\n'; } if (m_with_record_separator) { m_buffer += static_cast(0x1e); } m_buffer += R"({"type":"Feature")"; if (options().unique_id == unique_id_type::counter) { m_buffer += R"(,"id":)"; m_buffer += std::to_string(m_count + 1); } else if (options().unique_id == unique_id_type::type_id) { m_buffer += R"(,"id":)"; m_buffer += prefix; m_buffer += std::to_string(id); } } void ExportFormatJSON::add_option(const std::string& name) { const nlohmann::json j = name; m_buffer += ','; m_buffer += j.dump(); m_buffer += ':'; } void ExportFormatJSON::add_attributes(const osmium::OSMObject& object) { if (!options().type.empty()) { add_option(options().type); m_buffer += object_type_as_string(object); } if (!options().id.empty()) { add_option(options().id); m_buffer += std::to_string(object.type() == osmium::item_type::area ? osmium::area_id_to_object_id(object.id()) : object.id()); } if (!options().version.empty()) { add_option(options().version); m_buffer += std::to_string(object.version()); } if (!options().changeset.empty()) { add_option(options().changeset); m_buffer += std::to_string(object.changeset()); } if (!options().uid.empty()) { add_option(options().uid); m_buffer += std::to_string(object.uid()); } if (!options().user.empty()) { add_option(options().user); const nlohmann::json j = object.user(); m_buffer += j.template get(); } if (!options().timestamp.empty()) { add_option(options().timestamp); m_buffer += std::to_string(object.timestamp().seconds_since_epoch()); } if (!options().way_nodes.empty() && object.type() == osmium::item_type::way) { add_option(options().way_nodes); m_buffer += '['; for (const auto& nr : static_cast(object).nodes()) { m_buffer += std::to_string(nr.ref()); m_buffer += ','; } if (m_buffer.back() == ',') { m_buffer.back() = ']'; } else { m_buffer += ']'; } } } void ExportFormatJSON::finish_feature(const osmium::OSMObject& object) { m_buffer += R"(,"properties":{)"; add_attributes(object); nlohmann::json j; const bool has_tags = add_tags(object, [&](const osmium::Tag& tag) { j = tag.key(); m_buffer += j.dump(); m_buffer += ':'; j = tag.value(); m_buffer += j.dump(); m_buffer += ','; }); if (has_tags || options().keep_untagged) { if (m_buffer.back() == ',') { m_buffer.back() = '}'; // end properties } else { m_buffer += '}'; // end properties } m_buffer += '}'; // end feature m_committed_size = m_buffer.size(); ++m_count; if (m_buffer.size() > flush_buffer_size) { flush_to_output(); } } } namespace { void append_coordinate(std::string* buffer, double coord) { std::array tmp{}; auto n = std::snprintf(&*tmp.begin(), 20, "%.7f", coord); // remove trailing zeros while (n >= 2 && tmp[n - 1] == '0' && tmp[n - 2] != '.') { --n; } buffer->append(&*tmp.begin(), n); } } // anonymous namespace void ExportFormatJSON::create_coordinate(const osmium::Location& location) { std::string buffer; buffer.resize(20); m_buffer += '['; append_coordinate(&m_buffer, location.lon()); m_buffer += ','; append_coordinate(&m_buffer, location.lat()); m_buffer += ']'; } void ExportFormatJSON::create_coordinate_list(const osmium::NodeRefList& nrl) { m_buffer += '['; for (auto const &nr : nrl) { create_coordinate(nr.location()); m_buffer += ','; } if (m_buffer.back() == ',') { m_buffer.back() = ']'; } else { m_buffer += ']'; } } void ExportFormatJSON::create_point(const osmium::Node& node) { m_buffer += R"(,"geometry":{"type":"Point","coordinates":)"; create_coordinate(node.location()); m_buffer += '}'; } void ExportFormatJSON::create_linestring(const osmium::Way& way) { m_buffer += R"(,"geometry":{"type":"LineString","coordinates":)"; create_coordinate_list(way.nodes()); m_buffer += '}'; } void ExportFormatJSON::create_multipolygon(const osmium::Area& area) { m_buffer += R"(,"geometry":{"type":"MultiPolygon","coordinates":)"; for (const auto &outer_ring : area.outer_rings()) { m_buffer += "[["; create_coordinate_list(outer_ring); m_buffer += ']'; for (const auto &inner_ring : area.inner_rings(outer_ring)) { m_buffer += ",["; create_coordinate_list(inner_ring); m_buffer += ']'; } m_buffer += "],"; } m_buffer.back() = '}'; } void ExportFormatJSON::node(const osmium::Node& node) { start_feature("n", node.id()); create_point(node); finish_feature(node); } void ExportFormatJSON::way(const osmium::Way& way) { start_feature("w", way.id()); create_linestring(way); finish_feature(way); } void ExportFormatJSON::area(const osmium::Area& area) { start_feature("a", area.id()); create_multipolygon(area); finish_feature(area); } void ExportFormatJSON::rollback_uncomitted() { m_buffer.resize(m_committed_size); } void ExportFormatJSON::close() { if (m_fd > 0) { rollback_uncomitted(); m_buffer += '\n'; if (!m_text_sequence_format) { m_buffer += "]}\n"; } flush_to_output(); if (m_fsync == osmium::io::fsync::yes) { osmium::io::detail::reliable_fsync(m_fd); } ::close(m_fd); m_fd = -1; } } osmium-tool-1.17.0/src/export/export_format_json.hpp000066400000000000000000000045261474143067200226460ustar00rootroot00000000000000#ifndef EXPORT_EXPORT_FORMAT_JSON_HPP #define EXPORT_EXPORT_FORMAT_JSON_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "export_format.hpp" #include #include #include #include class ExportFormatJSON : public ExportFormat { int m_fd; osmium::io::fsync m_fsync; bool m_text_sequence_format; bool m_with_record_separator; std::string m_buffer; std::size_t m_committed_size = 0; void flush_to_output(); void rollback_uncomitted(); void add_option(const std::string& name); void start_feature(const std::string& prefix, osmium::object_id_type id); void add_attributes(const osmium::OSMObject& object); void finish_feature(const osmium::OSMObject& object); void create_coordinate(const osmium::Location& location); void create_coordinate_list(const osmium::NodeRefList& nrl); void create_point(const osmium::Node& node); void create_linestring(const osmium::Way& way); void create_multipolygon(const osmium::Area& area); public: ExportFormatJSON(const std::string& output_format, const std::string& output_filename, osmium::io::overwrite overwrite, osmium::io::fsync fsync, const options_type& options); ~ExportFormatJSON() override { close(); } void node(const osmium::Node& node) override; void way(const osmium::Way& way) override; void area(const osmium::Area& area) override; void close() override; }; // class ExportFormatJSON #endif // EXPORT_EXPORT_FORMAT_JSON_HPP osmium-tool-1.17.0/src/export/export_format_pg.cpp000066400000000000000000000223071474143067200222730ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool http://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "export_format_pg.hpp" #include "../exception.hpp" #include "../util.hpp" #include #include #include #include enum { initial_buffer_size = 1024U * 1024U }; enum { flush_buffer_size = 800U * 1024U }; ExportFormatPg::ExportFormatPg(const std::string& /*output_format*/, const std::string& output_filename, osmium::io::overwrite overwrite, osmium::io::fsync fsync, const options_type& options) : ExportFormat(options), m_fd(osmium::io::detail::open_for_writing(output_filename, overwrite)), m_fsync(fsync) { m_buffer.reserve(initial_buffer_size); const auto tt = options.format_options.get("tags_type"); if (tt == "hstore") { m_tags_type = tags_output_format::hstore; } else if (tt == "json" || tt == "jsonb") { m_tags_type = tags_output_format::json; } else { throw config_error{"Unknown value for tags_format option: '" + tt + "'."}; } } void ExportFormatPg::flush_to_output() { osmium::io::detail::reliable_write(m_fd, m_buffer.data(), m_buffer.size()); m_buffer.clear(); m_commit_size = 0; } void ExportFormatPg::start_feature(const char type, const osmium::object_id_type id) { m_buffer.resize(m_commit_size); if (options().unique_id == unique_id_type::counter) { m_buffer.append(std::to_string(m_count + 1)); m_buffer += '\t'; } else if (options().unique_id == unique_id_type::type_id) { m_buffer += type; m_buffer.append(std::to_string(id)); m_buffer += '\t'; } } void ExportFormatPg::append_pg_escaped(const char* str) { while (*str != '\0') { switch (*str) { case '\\': m_buffer += '\\'; m_buffer += '\\'; break; case '\n': m_buffer += '\\'; m_buffer += 'n'; break; case '\r': m_buffer += '\\'; m_buffer += 'r'; break; case '\t': m_buffer += '\\'; m_buffer += 't'; break; default: m_buffer += *str; } ++str; } } void ExportFormatPg::add_attributes(const osmium::OSMObject& object) { if (!options().type.empty()) { m_buffer.append(object_type_as_string(object)); m_buffer += '\t'; } if (!options().id.empty()) { m_buffer.append(std::to_string(object.type() == osmium::item_type::area ? osmium::area_id_to_object_id(object.id()) : object.id())); m_buffer += '\t'; } if (!options().version.empty()) { m_buffer.append(std::to_string(object.version())); m_buffer += '\t'; } if (!options().changeset.empty()) { m_buffer.append(std::to_string(object.changeset())); m_buffer += '\t'; } if (!options().uid.empty()) { m_buffer.append(std::to_string(object.uid())); m_buffer += '\t'; } if (!options().user.empty()) { append_pg_escaped(object.user()); m_buffer += '\t'; } if (!options().timestamp.empty()) { m_buffer.append(object.timestamp().to_iso()); m_buffer += '\t'; } if (!options().way_nodes.empty()) { if (object.type() == osmium::item_type::way) { m_buffer += '{'; for (const auto& nr : static_cast(object).nodes()) { m_buffer.append(std::to_string(nr.ref())); m_buffer += ','; } if (m_buffer.back() == ',') { m_buffer.back() = '}'; } else { m_buffer += '}'; } } else { m_buffer += '\\'; m_buffer += 'N'; } m_buffer += '\t'; } } bool ExportFormatPg::add_tags_json(const osmium::OSMObject& object) { std::string target{"{"}; nlohmann::json j; for (const auto& tag : object.tags()) { if (options().tags_filter(tag)) { j = tag.key(); target += j.dump(); target += ':'; j = tag.value(); target += j.dump(); target += ','; } } bool const has_tags = target.size() > 1; if (has_tags) { target.back() = '}'; } else { target += '}'; } append_pg_escaped(target.c_str()); return has_tags; } namespace { void add_escape_hstore(std::string* out, const char* str) { *out += "\""; while (*str) { if (*str == '"') { *out += "\\\""; } else if (*str == '\\') { *out += "\\\\"; } else { *out += *str; } ++str; } *out += "\""; } } // anonymous namespace bool ExportFormatPg::add_tags_hstore(const osmium::OSMObject& object) { if (object.tags().empty()) { return false; } bool has_tags = false; std::string data; for (const auto& tag : object.tags()) { if (options().tags_filter(tag)) { has_tags = true; add_escape_hstore(&data, tag.key()); data += "=>"; add_escape_hstore(&data, tag.value()); data += ','; } } if (has_tags) { data.resize(data.size() - 1); append_pg_escaped(data.c_str()); } return has_tags; } bool ExportFormatPg::add_tags(const osmium::OSMObject& object) { return m_tags_type == tags_output_format::json ? add_tags_json(object) : add_tags_hstore(object); } void ExportFormatPg::finish_feature(const osmium::OSMObject& object) { m_buffer += '\t'; add_attributes(object); if (add_tags(object) || options().keep_untagged) { m_buffer += '\n'; m_commit_size = m_buffer.size(); ++m_count; if (m_buffer.size() > flush_buffer_size) { flush_to_output(); } } } void ExportFormatPg::node(const osmium::Node& node) { start_feature('n', node.id()); m_buffer.append(m_factory.create_point(node)); finish_feature(node); } void ExportFormatPg::way(const osmium::Way& way) { start_feature('w', way.id()); m_buffer.append(m_factory.create_linestring(way)); finish_feature(way); } void ExportFormatPg::area(const osmium::Area& area) { start_feature('a', area.id()); m_buffer.append(m_factory.create_multipolygon(area)); finish_feature(area); } void ExportFormatPg::close() { if (m_fd > 0) { flush_to_output(); if (m_fsync == osmium::io::fsync::yes) { osmium::io::detail::reliable_fsync(m_fd); } ::close(m_fd); m_fd = -1; } } void ExportFormatPg::debug_output(osmium::VerboseOutput& out, const std::string& filename) { out << '\n'; out << "Create table with something like this:\n"; if (m_tags_type == tags_output_format::hstore) { out << "CREATE EXTENSION IF NOT EXISTS hstore;\n"; } out << "CREATE TABLE osmdata (\n"; if (options().unique_id == unique_id_type::counter) { out << " id BIGINT PRIMARY KEY,\n"; } else if (options().unique_id == unique_id_type::type_id) { out << " id TEXT PRIMARY KEY,\n"; } out << " geom GEOMETRY, -- or GEOGRAPHY\n"; if (!options().type.empty()) { out << " osm_type TEXT,\n"; } if (!options().id.empty()) { out << " osm_id BIGINT,\n"; } if (!options().version.empty()) { out << " version INTEGER,\n"; } if (!options().changeset.empty()) { out << " changeset INTEGER,\n"; } if (!options().uid.empty()) { out << " uid INTEGER,\n"; } if (!options().user.empty()) { out << " \"user\" TEXT,\n"; } if (!options().timestamp.empty()) { out << " timestamp TIMESTAMP (0) WITH TIME ZONE,\n"; } if (!options().way_nodes.empty()) { out << " way_nodes BIGINT[],\n"; } switch (m_tags_type) { case tags_output_format::json: out << " tags JSONB -- or JSON, or TEXT\n"; break; case tags_output_format::hstore: out << " tags hstore\n"; break; } out << ");\n"; out << "Then load data with something like this:\n"; out << "\\copy osmdata FROM '" << filename << "'\n"; out << '\n'; } osmium-tool-1.17.0/src/export/export_format_pg.hpp000066400000000000000000000047071474143067200223040ustar00rootroot00000000000000#ifndef EXPORT_EXPORT_FORMAT_PG_HPP #define EXPORT_EXPORT_FORMAT_PG_HPP /* Osmium -- OpenStreetMap data manipulation command line tool http://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "export_format.hpp" #include #include #include #include class ExportFormatPg : public ExportFormat { enum tags_output_format { json, hstore }; osmium::geom::WKBFactory<> m_factory{osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex}; std::string m_buffer; std::size_t m_commit_size = 0; int m_fd; osmium::io::fsync m_fsync; tags_output_format m_tags_type = tags_output_format::json; void flush_to_output(); void start_feature(char type, osmium::object_id_type id); void add_attributes(const osmium::OSMObject& object); bool add_tags_json(const osmium::OSMObject& object); bool add_tags_hstore(const osmium::OSMObject& object); bool add_tags(const osmium::OSMObject& object); void finish_feature(const osmium::OSMObject& object); void append_pg_escaped(const char* str); public: ExportFormatPg(const std::string& output_format, const std::string& output_filename, osmium::io::overwrite overwrite, osmium::io::fsync fsync, const options_type& options); ~ExportFormatPg() override { try { close(); } catch (...) { } } void node(const osmium::Node& node) override; void way(const osmium::Way& way) override; void area(const osmium::Area& area) override; void close() override; void debug_output(osmium::VerboseOutput& out, const std::string& filename) override; }; // class ExportFormatPg #endif // EXPORT_EXPORT_FORMAT_PG_HPP osmium-tool-1.17.0/src/export/export_format_text.cpp000066400000000000000000000133451474143067200226530ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "export_format_text.hpp" #include "../util.hpp" #include #include #include #include static constexpr const std::size_t initial_buffer_size = 1024UL * 1024UL; static constexpr const std::size_t flush_buffer_size = 800UL * 1024UL; ExportFormatText::ExportFormatText(const std::string& /*output_format*/, const std::string& output_filename, osmium::io::overwrite overwrite, osmium::io::fsync fsync, const options_type& options) : ExportFormat(options), m_fd(osmium::io::detail::open_for_writing(output_filename, overwrite)), m_fsync(fsync) { m_buffer.reserve(initial_buffer_size); } void ExportFormatText::flush_to_output() { osmium::io::detail::reliable_write(m_fd, m_buffer.data(), m_buffer.size()); m_buffer.clear(); m_commit_size = 0; } void ExportFormatText::start_feature(char type, osmium::object_id_type id) { m_buffer.resize(m_commit_size); if (options().unique_id == unique_id_type::counter) { m_buffer.append(std::to_string(m_count + 1)); m_buffer.append(1, ' '); } else if (options().unique_id == unique_id_type::type_id) { m_buffer.append(1, type); m_buffer.append(std::to_string(id)); m_buffer.append(1, ' '); } } void ExportFormatText::add_attributes(const osmium::OSMObject& object) { if (!options().type.empty()) { m_buffer.append(options().type); m_buffer.append(1, '='); m_buffer.append(object_type_as_string(object)); m_buffer.append(1, ','); } if (!options().id.empty()) { m_buffer.append(options().id); m_buffer.append(1, '='); m_buffer.append(std::to_string(object.type() == osmium::item_type::area ? osmium::area_id_to_object_id(object.id()) : object.id())); m_buffer.append(1, ','); } if (!options().version.empty()) { m_buffer.append(options().version); m_buffer.append(1, '='); m_buffer.append(std::to_string(object.version())); m_buffer.append(1, ','); } if (!options().changeset.empty()) { m_buffer.append(options().changeset); m_buffer.append(1, '='); m_buffer.append(std::to_string(object.changeset())); m_buffer.append(1, ','); } if (!options().uid.empty()) { m_buffer.append(options().uid); m_buffer.append(1, '='); m_buffer.append(std::to_string(object.uid())); m_buffer.append(1, ','); } if (!options().user.empty()) { m_buffer.append(options().user); m_buffer.append(1, '='); m_buffer.append(object.user()); m_buffer.append(1, ','); } if (!options().timestamp.empty()) { m_buffer.append(options().timestamp); m_buffer.append(1, '='); m_buffer.append(std::to_string(object.timestamp().seconds_since_epoch())); m_buffer.append(1, ','); } if (!options().way_nodes.empty() && object.type() == osmium::item_type::way) { m_buffer.append(options().way_nodes); m_buffer.append(1, '='); for (const auto& nr : static_cast(object).nodes()) { m_buffer.append(std::to_string(nr.ref())); m_buffer.append(1, '/'); } if (m_buffer.back() == '/') { m_buffer.resize(m_buffer.size() - 1); } } } void ExportFormatText::finish_feature(const osmium::OSMObject& object) { m_buffer.append(1, ' '); add_attributes(object); const bool has_tags = add_tags(object, [&](const osmium::Tag& tag) { osmium::io::detail::append_utf8_encoded_string(m_buffer, tag.key()); m_buffer.append(1, '='); osmium::io::detail::append_utf8_encoded_string(m_buffer, tag.value()); m_buffer.append(1, ','); }); if (has_tags || options().keep_untagged) { if (m_buffer.back() == ',') { m_buffer.back() = '\n'; } else { m_buffer.append(1, '\n'); } m_commit_size = m_buffer.size(); ++m_count; if (m_buffer.size() > flush_buffer_size) { flush_to_output(); } } } void ExportFormatText::node(const osmium::Node& node) { start_feature('n', node.id()); m_buffer.append(m_factory.create_point(node)); finish_feature(node); } void ExportFormatText::way(const osmium::Way& way) { start_feature('w', way.id()); m_buffer.append(m_factory.create_linestring(way)); finish_feature(way); } void ExportFormatText::area(const osmium::Area& area) { start_feature('a', area.id()); m_buffer.append(m_factory.create_multipolygon(area)); finish_feature(area); } void ExportFormatText::close() { if (m_fd > 0) { flush_to_output(); if (m_fsync == osmium::io::fsync::yes) { osmium::io::detail::reliable_fsync(m_fd); } ::close(m_fd); m_fd = -1; } } osmium-tool-1.17.0/src/export/export_format_text.hpp000066400000000000000000000036751474143067200226650ustar00rootroot00000000000000#ifndef EXPORT_EXPORT_FORMAT_TEXT_HPP #define EXPORT_EXPORT_FORMAT_TEXT_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "export_format.hpp" #include #include #include #include class ExportFormatText : public ExportFormat { osmium::geom::WKTFactory<> m_factory; std::string m_buffer; std::size_t m_commit_size = 0; int m_fd; osmium::io::fsync m_fsync; void flush_to_output(); void start_feature(char type, osmium::object_id_type id); void add_attributes(const osmium::OSMObject& object); void finish_feature(const osmium::OSMObject& object); public: ExportFormatText(const std::string& output_format, const std::string& output_filename, osmium::io::overwrite overwrite, osmium::io::fsync fsync, const options_type& options); ~ExportFormatText() override { close(); } void node(const osmium::Node& node) override; void way(const osmium::Way& way) override; void area(const osmium::Area& area) override; void close() override; }; // class ExportFormatText #endif // EXPORT_EXPORT_FORMAT_TEXT_HPP osmium-tool-1.17.0/src/export/export_handler.cpp000066400000000000000000000107251474143067200217330ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "export_handler.hpp" #include "../exception.hpp" #include "../util.hpp" #include #include #include #include #include #include #include #include #include #include namespace { bool check_conditions(const osmium::TagList& tags, const Ruleset& r1, const Ruleset& r2, bool is_no) noexcept { const char* area_tag = tags.get_value_by_key("area"); if (area_tag) { if (std::strcmp(area_tag, "no") == 0) { return is_no; } if (std::strcmp(area_tag, "yes") == 0) { return !is_no; } } if (r1.rule_type() == tags_filter_rule_type::other) { return osmium::tags::match_none_of(tags, r2.filter()); } return osmium::tags::match_any_of(tags, r1.filter()); } } // anonymous namespace bool ExportHandler::is_linear(const osmium::TagList& tags) const noexcept { return check_conditions(tags, m_linear_ruleset, m_area_ruleset, true); } bool ExportHandler::is_area(const osmium::TagList& tags) const noexcept { return check_conditions(tags, m_area_ruleset, m_linear_ruleset, false); } ExportHandler::ExportHandler(std::unique_ptr&& handler, const Ruleset& linear_ruleset, const Ruleset& area_ruleset, geometry_types geometry_types, bool show_errors, bool stop_on_error) : m_handler(std::move(handler)), m_linear_ruleset(linear_ruleset), m_area_ruleset(area_ruleset), m_geometry_types(geometry_types), m_show_errors(show_errors), m_stop_on_error(stop_on_error) { } void ExportHandler::show_error(const std::runtime_error& error) { if (m_stop_on_error) { throw; } ++m_error_count; if (m_show_errors) { std::cerr << "Geometry error: " << error.what() << '\n'; } } void ExportHandler::node(const osmium::Node& node) { if (!m_geometry_types.point) { return; } if (node.tags().empty() && !m_handler->options().keep_untagged) { return; } try { m_handler->node(node); } catch (const osmium::geometry_error& e) { show_error(e); } catch (const osmium::invalid_location& e) { show_error(e); } } void ExportHandler::way(const osmium::Way& way) { if (!m_geometry_types.linestring) { return; } try { if (way.nodes().size() <= 1) { throw osmium::geometry_error{"Way with less than two nodes (id=" + std::to_string(way.id()) + ")"}; } if (!way.nodes().front().location() || !way.nodes().back().location()) { throw osmium::invalid_location{"invalid location"}; } if ((way.tags().empty() && m_handler->options().keep_untagged) || !way.ends_have_same_location() || is_linear(way.tags())) { m_handler->way(way); } } catch (const osmium::geometry_error& e) { show_error(e); } catch (const osmium::invalid_location& e) { show_error(e); } } void ExportHandler::area(const osmium::Area& area) { if (!m_geometry_types.polygon) { return; } if (area.from_way() && !is_area(area.tags())) { return; } try { const auto rings = area.num_rings(); if (rings.first == 0 && rings.second == 0) { throw osmium::geometry_error{"Could not build area geometry"}; } m_handler->area(area); } catch (const osmium::geometry_error& e) { show_error(e); } catch (const osmium::invalid_location& e) { show_error(e); } } osmium-tool-1.17.0/src/export/export_handler.hpp000066400000000000000000000044311474143067200217350ustar00rootroot00000000000000#ifndef EXPORT_EXPORT_HANDLER_HPP #define EXPORT_EXPORT_HANDLER_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "export_format.hpp" #include "ruleset.hpp" #include #include #include #include #include #include #include #include #include class ExportHandler : public osmium::handler::Handler { std::unique_ptr m_handler; const Ruleset& m_linear_ruleset; const Ruleset& m_area_ruleset; uint64_t m_error_count = 0; geometry_types m_geometry_types; bool m_show_errors; bool m_stop_on_error; bool is_linear(const osmium::TagList& tags) const noexcept; bool is_area(const osmium::TagList& tags) const noexcept; void show_error(const std::runtime_error& error); public: ExportHandler(std::unique_ptr&& handler, const Ruleset& linear_ruleset, const Ruleset& area_ruleset, geometry_types geometry_types, bool show_errors, bool stop_on_error); void node(const osmium::Node& node); void way(const osmium::Way& way); void area(const osmium::Area& area); void close() const { m_handler->close(); } std::uint64_t count() const noexcept { return m_handler->count(); } std::uint64_t error_count() const noexcept { return m_error_count; } }; // class ExportHandler #endif // EXPORT_EXPORT_HANDLER_HPP osmium-tool-1.17.0/src/export/options.hpp000066400000000000000000000033241474143067200204120ustar00rootroot00000000000000#ifndef EXPORT_OPTIONS_HPP #define EXPORT_OPTIONS_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include #include #include enum class unique_id_type { none = 0, counter = 1, type_id = 2 }; struct options_type { osmium::TagsFilter tags_filter{true}; std::string type; std::string id; std::string version; std::string changeset; std::string timestamp; std::string uid; std::string user; std::string way_nodes; unique_id_type unique_id = unique_id_type::none; osmium::Options format_options; bool keep_untagged = false; }; struct geometry_types { bool point = true; bool linestring = true; bool polygon = true; void clear() noexcept { point = false; linestring = false; polygon = false; } bool empty() const noexcept { return !point && !linestring && !polygon; } }; // struct geometry_types #endif // EXPORT_OPTIONS_HPP osmium-tool-1.17.0/src/export/ruleset.hpp000066400000000000000000000025711474143067200204050ustar00rootroot00000000000000#ifndef EXPORT_RULESET_HPP #define EXPORT_RULESET_HPP #include "../util.hpp" #include #include #include enum class tags_filter_rule_type { none = 0, any = 1, list = 2, other = 3 }; class Ruleset { tags_filter_rule_type m_type = tags_filter_rule_type::any; std::vector m_tags; osmium::TagsFilter m_filter{false}; public: void set_rule_type(tags_filter_rule_type type) noexcept { m_type = type; } tags_filter_rule_type rule_type() const noexcept { return m_type; } const std::vector& tags() const noexcept { return m_tags; } template void add_rule(T&& rule) { m_tags.emplace_back(std::forward(rule)); } const osmium::TagsFilter& filter() const noexcept { return m_filter; } void init_filter() { switch (m_type) { case tags_filter_rule_type::none: break; case tags_filter_rule_type::any: m_filter.set_default_result(true); break; case tags_filter_rule_type::list: initialize_tags_filter(m_filter, false, m_tags); break; case tags_filter_rule_type::other: break; } } }; // class Ruleset #endif // EXPORT_RULESET_HPP osmium-tool-1.17.0/src/extract/000077500000000000000000000000001474143067200163355ustar00rootroot00000000000000osmium-tool-1.17.0/src/extract/extract.cpp000066400000000000000000000035201474143067200205130ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "extract.hpp" #include #include #include #include #include void Extract::open_file(const osmium::io::Header& header, osmium::io::overwrite output_overwrite, osmium::io::fsync sync, OptionClean const* clean) { m_clean = clean; m_writer = std::make_unique(m_output_file, header, output_overwrite, sync); } void Extract::close_file() { if (m_writer) { if (m_buffer.committed() > 0) { m_clean->apply_to(m_buffer); (*m_writer)(std::move(m_buffer)); } m_writer->close(); } } void Extract::write(const osmium::memory::Item& item) { if (m_buffer.capacity() - m_buffer.committed() < item.padded_size()) { m_clean->apply_to(m_buffer); (*m_writer)(std::move(m_buffer)); m_buffer = osmium::memory::Buffer{buffer_size, osmium::memory::Buffer::auto_grow::no}; } m_buffer.push_back(item); } std::string Extract::envelope_as_text() const { std::stringstream ss; ss << m_envelope; return ss.str(); } osmium-tool-1.17.0/src/extract/extract.hpp000066400000000000000000000062271474143067200205270ustar00rootroot00000000000000#ifndef EXTRACT_EXTRACT_HPP #define EXTRACT_EXTRACT_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "../option_clean.hpp" #include #include #include #include #include #include #include #include #include #include #include class Extract { static constexpr const std::size_t buffer_size = 10UL * 1024UL * 1024UL; osmium::io::File m_output_file; std::string m_description; std::vector m_header_options; osmium::Box m_envelope; osmium::memory::Buffer m_buffer{buffer_size, osmium::memory::Buffer::auto_grow::no}; std::unique_ptr m_writer; const OptionClean* m_clean = nullptr; public: Extract(const osmium::io::File& output_file, const std::string& description, const osmium::Box& envelope) : m_output_file(output_file), m_description(description), m_envelope(envelope), m_writer(nullptr) { } virtual ~Extract() = default; const std::string& output() const noexcept { return m_output_file.filename(); } const char* output_format() const noexcept { return osmium::io::as_string(m_output_file.format()); } const std::string& description() const noexcept { return m_description; } const osmium::Box& envelope() const noexcept { return m_envelope; } void add_header_option(const std::string& option) { m_header_options.emplace_back(option + "!"); } void add_header_option(const std::string& name, const std::string& value) { m_header_options.emplace_back(name + "=" + value); } const std::vector& header_options() const noexcept { return m_header_options; } osmium::io::Writer& writer() { return *m_writer; } void open_file(const osmium::io::Header& header, osmium::io::overwrite output_overwrite, osmium::io::fsync sync, OptionClean const* clean); void close_file(); void write(const osmium::memory::Item& item); std::string envelope_as_text() const; virtual bool contains(const osmium::Location& location) const noexcept = 0; virtual const char* geometry_type() const noexcept = 0; virtual std::string geometry_as_text() const = 0; }; // class Extract #endif // EXTRACT_EXTRACT_HPP osmium-tool-1.17.0/src/extract/extract_bbox.cpp000066400000000000000000000025151474143067200215300ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "extract_bbox.hpp" #include #include #include bool ExtractBBox::contains(const osmium::Location& location) const noexcept { return location.valid() && envelope().contains(location); } const char* ExtractBBox::geometry_type() const noexcept { return "bbox"; } std::string ExtractBBox::geometry_as_text() const { std::string s{"BOX("}; envelope().bottom_left().as_string(std::back_inserter(s), ' '); s += ','; envelope().top_right().as_string(std::back_inserter(s), ' '); s += ')'; return s; } osmium-tool-1.17.0/src/extract/extract_bbox.hpp000066400000000000000000000024771474143067200215440ustar00rootroot00000000000000#ifndef EXTRACT_EXTRACT_BBOX_HPP #define EXTRACT_EXTRACT_BBOX_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "extract.hpp" class ExtractBBox : public Extract { public: ExtractBBox(const osmium::io::File& output_file, const std::string& description, const osmium::Box& box) : Extract(output_file, description, box) { } bool contains(const osmium::Location& location) const noexcept override final; const char* geometry_type() const noexcept override final; std::string geometry_as_text() const override final; }; // class ExtractBBox #endif // EXTRACT_EXTRACT_BBOX_HPP osmium-tool-1.17.0/src/extract/extract_polygon.cpp000066400000000000000000000122441474143067200222650ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "extract_polygon.hpp" #include "../exception.hpp" #include #include #include #include #include #include #include #include #include namespace { void add_ring(std::vector* segments, const osmium::NodeRefList& ring) { const auto* it = ring.begin(); const auto* const end = ring.end(); if (it == end) { throw config_error{"Ring without any points."}; } const auto* prev_it = it++; while (it != end) { segments->emplace_back(prev_it->location(), it->location()); prev_it = it++; } } } // anonymous namespace const osmium::Area& ExtractPolygon::area() const noexcept { return m_buffer.get(m_offset); } ExtractPolygon::ExtractPolygon(const osmium::io::File& output_file, const std::string& description, const osmium::memory::Buffer& buffer, std::size_t offset) : Extract(output_file, description, buffer.get(offset).envelope()), m_buffer(buffer), m_offset(offset) { // get segments from all rings std::vector segments; for (const auto& outer_ring : area().outer_rings()) { add_ring(&segments, outer_ring); for (const auto& inner_ring : area().inner_rings(outer_ring)) { add_ring(&segments, inner_ring); } } // split y range into equal-sized bands constexpr const int32_t segments_per_band = 10; constexpr const int32_t max_bands = 10000; int32_t num_bands = static_cast(segments.size()) / segments_per_band; if (num_bands < 1) { num_bands = 1; } else if (num_bands > max_bands) { num_bands = max_bands; } m_bands.resize(num_bands + 1); m_dy = (y_max() - y_min() + num_bands - 1) / num_bands; // put segments into the bands they overlap for (const auto& segment : segments) { const std::pair mm = std::minmax(segment.first().y(), segment.second().y()); const uint32_t band_min = (mm.first - y_min()) / m_dy; const uint32_t band_max = (mm.second - y_min()) / m_dy; assert(band_min < m_bands.size() && band_max < m_bands.size()); for (auto band = band_min; band <= band_max; ++band) { m_bands[band].push_back(segment); } } } /* Simple point-in-polygon algorithm adapted from https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy) { int i, j, c = 0; for (i = 0, j = nvert-1; i < nvert; j = i++) { if ( ((verty[i]>testy) != (verty[j]>testy)) && (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) ) c = !c; } return c; } In our implementation we split the y-range into equal-sized subranges and only have to test all segments in the subrange that contains the y coordinate of the node. */ bool ExtractPolygon::contains(const osmium::Location& location) const noexcept { if (!location.valid() || !envelope().contains(location)) { return false; } const std::size_t band = (location.y() - y_min()) / m_dy; assert(band < m_bands.size()); bool inside = false; for (const auto& segment : m_bands[band]) { if (segment.first() == location || segment.second() == location) { return true; } if ((segment.second().y() > location.y()) != (segment.first().y() > location.y())) { const auto ax = static_cast(segment.first().x()) - static_cast(segment.second().x()); const auto ay = static_cast(segment.first().y()) - static_cast(segment.second().y()); const auto tx = static_cast(location.x()) - static_cast(segment.second().x()); const auto ty = static_cast(location.y()) - static_cast(segment.second().y()); const bool comp = tx * ay < ax * ty; if ((ay > 0) == comp) { inside = !inside; } } } return inside; } const char* ExtractPolygon::geometry_type() const noexcept { return "polygon"; } std::string ExtractPolygon::geometry_as_text() const { osmium::geom::WKTFactory<> factory; return factory.create_multipolygon(area()); } osmium-tool-1.17.0/src/extract/extract_polygon.hpp000066400000000000000000000034051474143067200222710ustar00rootroot00000000000000#ifndef EXTRACT_EXTRACT_POLYGON_HPP #define EXTRACT_EXTRACT_POLYGON_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "extract.hpp" #include #include #include class ExtractPolygon : public Extract { const osmium::memory::Buffer& m_buffer; std::size_t m_offset; std::vector> m_bands; int32_t m_dy = 0; const osmium::Area& area() const noexcept; int32_t y_max() const noexcept { return envelope().top_right().y(); } int32_t y_min() const noexcept { return envelope().bottom_left().y(); } public: ExtractPolygon(const osmium::io::File& output_file, const std::string& description, const osmium::memory::Buffer& buffer, std::size_t offset); bool contains(const osmium::Location& location) const noexcept override final; const char* geometry_type() const noexcept override final; std::string geometry_as_text() const override final; }; // class ExtractPolygon #endif // EXTRACT_EXTRACT_POLYGON_HPP osmium-tool-1.17.0/src/extract/geojson_file_parser.cpp000066400000000000000000000204211474143067200230570ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "geojson_file_parser.hpp" #include "../exception.hpp" #include "geometry_util.hpp" #include #include #include #include #include #include #include #include #include #include #include std::string get_value_as_string(const nlohmann::json& object, const char* key) { assert(object.is_object()); const auto it = object.find(key); if (it == object.end()) { return {}; } if (it->is_string()) { return it->template get(); } throw config_error{std::string{"Value for name '"} + key + "' must be a string."}; } namespace { // parse coordinate pair from JSON array osmium::geom::Coordinates parse_coordinate(const nlohmann::json& value) { if (!value.is_array()) { throw config_error{"Coordinates must be an array."}; } if (value.size() != 2) { throw config_error{"Coordinates array must have exactly two elements."}; } if (value[0].is_number() && value[1].is_number()) { return osmium::geom::Coordinates{value[0].template get(), value[1].template get()}; } throw config_error{"Coordinates array must contain numbers."}; } std::vector parse_ring(const nlohmann::json& value) { if (!value.is_array()) { throw config_error{"Ring must be an array."}; } if (value.size() < 3) { throw config_error{"Ring must contain at least three coordinate pairs."}; } std::vector coordinates; for (const nlohmann::json& item : value) { coordinates.push_back(parse_coordinate(item)); } return coordinates; } void parse_rings(const nlohmann::json& value, osmium::builder::AreaBuilder* builder) { assert(value.is_array()); if (value.empty()) { throw config_error{"Polygon must contain at least one ring."}; } { auto outer_ring = parse_ring(value[0]); if (!is_ccw(outer_ring)) { std::reverse(outer_ring.begin(), outer_ring.end()); } osmium::builder::OuterRingBuilder ring_builder{*builder}; for (const auto& c : outer_ring) { const osmium::Location loc{c.x, c.y}; if (loc.valid()) { ring_builder.add_node_ref(0, loc); } else { throw config_error{"Invalid location in boundary (multi)polygon: (" + std::to_string(c.x) + ", " + std::to_string(c.y) + ")."}; } } } for (unsigned int i = 1; i < value.size(); ++i) { auto inner_ring = parse_ring(value[i]); if (is_ccw(inner_ring)) { std::reverse(inner_ring.begin(), inner_ring.end()); } osmium::builder::InnerRingBuilder ring_builder{*builder}; for (const auto& c : inner_ring) { const osmium::Location loc{c.x, c.y}; if (loc.valid()) { ring_builder.add_node_ref(0, loc); } else { throw config_error{"Invalid location in boundary (multi)polygon: (" + std::to_string(c.x) + ", " + std::to_string(c.y) + ")."}; } } } } } // anonymous namespace std::size_t parse_polygon_array(const nlohmann::json& value, osmium::memory::Buffer* buffer) { { osmium::builder::AreaBuilder builder{*buffer}; parse_rings(value, &builder); } return buffer->commit(); } std::size_t parse_multipolygon_array(const nlohmann::json& value, osmium::memory::Buffer* buffer) { assert(value.is_array()); if (value.empty()) { throw config_error{"Multipolygon must contain at least one polygon array."}; } { osmium::builder::AreaBuilder builder{*buffer}; for (const auto& polygon : value) { if (!polygon.is_array()) { throw config_error{"Polygon must be an array."}; } parse_rings(polygon, &builder); } } return buffer->commit(); } [[noreturn]] void GeoJSONFileParser::error(const std::string& message) { throw geojson_error{std::string{"In file '"} + m_file_name + "':\n" + message}; } GeoJSONFileParser::GeoJSONFileParser(osmium::memory::Buffer& buffer, std::string file_name) : m_buffer(buffer), m_file_name(std::move(file_name)), m_file(m_file_name) { if (!m_file.is_open()) { throw config_error{std::string{"Could not open file '"} + m_file_name + "'."}; } } std::size_t GeoJSONFileParser::parse_top(const nlohmann::json& top) { const auto json_geometry = top.find("geometry"); if (json_geometry == top.end()) { error("Missing 'geometry' name."); } if (!json_geometry->is_object()) { error("Expected 'geometry' value to be an object."); } const std::string geometry_type{get_value_as_string(*json_geometry, "type")}; if (geometry_type.empty()) { error("Missing 'geometry.type'."); } if (geometry_type != "Polygon" && geometry_type != "MultiPolygon") { error("Expected 'geometry.type' value to be 'Polygon' or 'MultiPolygon'."); } const auto json_coordinates = json_geometry->find("coordinates"); if (json_coordinates == json_geometry->end()) { error("Missing 'coordinates' name in 'geometry' object."); } if (!json_coordinates->is_array()) { error("Expected 'geometry.coordinates' value to be an array."); } if (geometry_type == "Polygon") { return parse_polygon_array(*json_coordinates, &m_buffer); } return parse_multipolygon_array(*json_coordinates, &m_buffer); } std::size_t GeoJSONFileParser::operator()() { try { const nlohmann::json doc = nlohmann::json::parse(m_file); if (!doc.is_object()) { error("Top-level value must be an object."); } const std::string type{get_value_as_string(doc, "type")}; if (type.empty()) { error("Expected 'type' name with the value 'Feature' or 'FeatureCollection'."); } if (type == "Feature") { return parse_top(doc); } if (type == "FeatureCollection") { const auto json_features = doc.find("features"); if (json_features == doc.end()) { error("Missing 'features' name."); } if (!json_features->is_array()) { error("Expected 'features' value to be an array."); } if (json_features->empty()) { throw config_error{"Features array must contain at least one polygon."}; } const auto& json_first_feature = (*json_features)[0]; if (!json_first_feature.is_object()) { error("Expected values of 'features' array to be a objects."); } const std::string feature_type{get_value_as_string(json_first_feature, "type")}; if (feature_type != "Feature") { error("Expected 'type' value to be 'Feature'."); } return parse_top(json_first_feature); } error("Expected 'type' value to be 'Feature'."); } catch (const nlohmann::json::parse_error &e) { error(std::string{"JSON error at offset "} + std::to_string(e.byte) + " : " + e.what()); } } osmium-tool-1.17.0/src/extract/geojson_file_parser.hpp000066400000000000000000000032401474143067200230640ustar00rootroot00000000000000#ifndef EXTRACT_GEOJSON_FILE_PARSER_HPP #define EXTRACT_GEOJSON_FILE_PARSER_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include #include #include #include std::string get_value_as_string(const nlohmann::json& object, const char* key); std::size_t parse_polygon_array(const nlohmann::json& value, osmium::memory::Buffer* buffer); std::size_t parse_multipolygon_array(const nlohmann::json& value, osmium::memory::Buffer* buffer); /** * Gets areas from OSM files. */ class GeoJSONFileParser { osmium::memory::Buffer& m_buffer; std::string m_file_name; std::ifstream m_file; [[noreturn]] void error(const std::string& message); std::size_t parse_top(const nlohmann::json& top); public: GeoJSONFileParser(osmium::memory::Buffer& buffer, std::string file_name); std::size_t operator()(); }; // class GeoJSONFileParser #endif // EXTRACT_GEOJSON_FILE_PARSER_HPP osmium-tool-1.17.0/src/extract/geometry_util.cpp000066400000000000000000000014711474143067200217340ustar00rootroot00000000000000 #include "geometry_util.hpp" #include double calculate_double_area(const std::vector& coordinates) { assert(coordinates.size() > 1); double total = 0.0; auto prev = coordinates.front(); for (unsigned i = 1; i < coordinates.size(); ++i) { auto const cur = coordinates[i]; total += prev.lon() * cur.lat() - cur.lon() * prev.lat(); prev = cur; } return total; } double calculate_double_area(const std::vector& coordinates) { assert(coordinates.size() > 1); double total = 0.0; auto prev = coordinates.front(); for (unsigned i = 1; i < coordinates.size(); ++i) { auto const cur = coordinates[i]; total += prev.x * cur.y - cur.x * prev.y; prev = cur; } return total; } osmium-tool-1.17.0/src/extract/geometry_util.hpp000066400000000000000000000023731474143067200217430ustar00rootroot00000000000000#ifndef EXTRACT_GEOMETRY_UTIL_HPP #define EXTRACT_GEOMETRY_UTIL_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include #include double calculate_double_area(const std::vector& coordinates); double calculate_double_area(const std::vector& coordinates); /// Is the ring defined by the coordinates counter-clockwise? template bool is_ccw(T& coordinates) { return calculate_double_area(coordinates) > 0; } #endif // EXTRACT_GEOMETRY_UTIL_HPP osmium-tool-1.17.0/src/extract/osm_file_parser.cpp000066400000000000000000000062051474143067200222150ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "osm_file_parser.hpp" #include "../exception.hpp" #include #include #include #include #include #include #include #include #include #include #include using index_type = osmium::index::map::SparseMemArray; using location_handler_type = osmium::handler::NodeLocationsForWays; OSMFileParser::OSMFileParser(osmium::memory::Buffer& buffer, std::string file_name) : m_buffer(buffer), m_file_name(std::move(file_name)) { } std::size_t OSMFileParser::operator()() { const osmium::io::File input_file{m_file_name}; const osmium::area::Assembler::config_type assembler_config; osmium::area::MultipolygonCollector collector{assembler_config}; { osmium::io::Reader reader{input_file, osmium::osm_entity_bits::relation}; collector.read_relations(reader); reader.close(); } bool has_ring = false; try { index_type index; location_handler_type location_handler{index}; osmium::builder::AreaBuilder builder{m_buffer}; osmium::io::Reader reader{input_file}; osmium::apply(reader, location_handler, collector.handler([&](const osmium::memory::Buffer& buffer) { for (const auto& area : buffer.select()) { for (const auto& item : area) { if (item.type() == osmium::item_type::outer_ring || item.type() == osmium::item_type::inner_ring) { builder.add_item(item); has_ring = true; } } } })); reader.close(); } catch (const osmium::invalid_location&) { throw config_error{"Invalid location in boundary (multi)polygon in '" + m_file_name + "'."}; } catch (const osmium::not_found&) { throw config_error{"Missing node in boundary (multi)polygon in '" + m_file_name + "'."}; } if (has_ring) { return m_buffer.commit(); } m_buffer.rollback(); throw osmium::io_error{"No areas found in the OSM file."}; } osmium-tool-1.17.0/src/extract/osm_file_parser.hpp000066400000000000000000000022721474143067200222220ustar00rootroot00000000000000#ifndef EXTRACT_OSM_FILE_PARSER_HPP #define EXTRACT_OSM_FILE_PARSER_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include #include /** * Gets areas from OSM files. */ class OSMFileParser { osmium::memory::Buffer& m_buffer; std::string m_file_name; public: OSMFileParser(osmium::memory::Buffer& buffer, std::string file_name); std::size_t operator()(); }; // class OSMFileParser #endif // EXTRACT_OSM_FILE_PARSER_HPP osmium-tool-1.17.0/src/extract/poly_file_parser.cpp000066400000000000000000000105631474143067200224040ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "poly_file_parser.hpp" #include "../exception.hpp" #include "geometry_util.hpp" #include #include #include #include #include #include #include #include #include #include #include [[noreturn]] void PolyFileParser::error(const std::string& message) { throw poly_error{std::string{"In file '"} + m_file_name + "' on line " + std::to_string(m_line + 1) + ":\n" + message}; } PolyFileParser::PolyFileParser(osmium::memory::Buffer& buffer, const std::string& file_name) : m_buffer(buffer), m_builder(nullptr), m_file_name(file_name) { std::ifstream file{file_name}; if (!file.is_open()) { throw config_error{std::string{"Could not open file '"} + file_name + "'"}; } std::stringstream sstr; sstr << file.rdbuf(); m_data = osmium::split_string(sstr.str(), '\n', true); // remove CR at end of lines for (auto& line : m_data) { if (line.back() == '\r') { line.resize(line.size() - 1); } } } void PolyFileParser::parse_ring() { const bool is_inner_ring = line()[0] == '!'; ++m_line; std::vector coordinates; while (m_line < m_data.size()) { if (line() == "END") { if (coordinates.size() < 3) { error("Expected at least three lines with coordinates."); } if (coordinates.front() != coordinates.back()) { coordinates.push_back(coordinates.front()); } if (is_inner_ring) { if (is_ccw(coordinates)) { std::reverse(coordinates.begin(), coordinates.end()); } osmium::builder::InnerRingBuilder ring_builder{*m_builder}; for (const auto& location : coordinates) { ring_builder.add_node_ref(0, location); } } else { if (!is_ccw(coordinates)) { std::reverse(coordinates.begin(), coordinates.end()); } osmium::builder::OuterRingBuilder ring_builder{*m_builder}; for (const auto& location : coordinates) { ring_builder.add_node_ref(0, location); } } ++m_line; return; } std::istringstream sstr{line()}; double lon = NAN; double lat = NAN; if (!(sstr >> lon >> lat)) { error("Expected coordinates or 'END' to end the ring."); } coordinates.emplace_back(lon, lat); if (!coordinates.back().valid()) { throw config_error{"Invalid location in boundary (multi)polygon: (" + std::to_string(lon) + ", " + std::to_string(lat) + ")."}; } ++m_line; } } void PolyFileParser::parse_multipolygon() { ++m_line; // ignore first line while (m_line < m_data.size()) { if (line() == "END") { ++m_line; if (m_line == 2) { error("Need at least one ring in (multi)polygon."); } return; } parse_ring(); } --m_line; error("Expected 'END' for end of (multi)polygon."); } std::size_t PolyFileParser::operator()() { if (m_data.empty()) { throw poly_error{std::string{"File '"} + m_file_name + "' is empty."}; } m_builder = std::make_unique(m_buffer); while (m_line < m_data.size()) { parse_multipolygon(); } m_builder.reset(); return m_buffer.commit(); } osmium-tool-1.17.0/src/extract/poly_file_parser.hpp000066400000000000000000000036701474143067200224120ustar00rootroot00000000000000#ifndef EXTRACT_POLY_FILE_PARSER_HPP #define EXTRACT_POLY_FILE_PARSER_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include #include #include #include #include /** * Thrown when there is a problem with parsing a poly file. */ struct poly_error : public std::runtime_error { explicit poly_error(const std::string& message) : std::runtime_error(message) { } }; // struct poly_error /** * Gets areas from .poly files. * * Format description: * https://wiki.openstreetmap.org/wiki/Osmosis/Polygon_Filter_File_Format */ class PolyFileParser { osmium::memory::Buffer& m_buffer; std::unique_ptr m_builder; std::string m_file_name; std::vector m_data; std::size_t m_line = 0; void parse_ring(); void parse_multipolygon(); const std::string& line() const noexcept { return m_data[m_line]; } [[noreturn]] void error(const std::string& message); public: PolyFileParser(osmium::memory::Buffer& buffer, const std::string& file_name); std::size_t operator()(); }; // class PolyFileParser #endif // EXTRACT_POLY_FILE_PARSER_HPP osmium-tool-1.17.0/src/extract/strategy.hpp000066400000000000000000000111071474143067200207100ustar00rootroot00000000000000#ifndef EXTRACT_STRATEGY_HPP #define EXTRACT_STRATEGY_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "extract.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include template class ExtractData : public T { Extract* m_extract_ptr; public: explicit ExtractData(Extract& extract) : T(), m_extract_ptr(&extract) { } bool contains(const osmium::Location& location) const noexcept { return m_extract_ptr->contains(location); } void write(const osmium::memory::Item& item) { m_extract_ptr->write(item); } void close() { m_extract_ptr->close_file(); } }; // class ExtractData class ExtractStrategy { public: ExtractStrategy() = default; virtual ~ExtractStrategy() = default; virtual const char* name() const noexcept = 0; virtual void show_arguments(osmium::VerboseOutput& /*vout*/) { } virtual void run(osmium::VerboseOutput& vout, bool display_progress, const osmium::io::File& input_file) = 0; }; // class ExtractStrategy template class Pass { TStrategy* m_strategy; void run_impl(osmium::ProgressBar& progress_bar, osmium::io::Reader& reader) { while (osmium::memory::Buffer buffer = reader.read()) { progress_bar.update(reader.offset()); for (const auto& object : buffer) { switch (object.type()) { case osmium::item_type::node: self().node(static_cast(object)); for (auto& e : extracts()) { self().enode(&e, static_cast(object)); } break; case osmium::item_type::way: self().way(static_cast(object)); for (auto& e : extracts()) { self().eway(&e, static_cast(object)); } break; case osmium::item_type::relation: self().relation(static_cast(object)); for (auto& e : extracts()) { self().erelation(&e, static_cast(object)); } break; default: break; } } } } protected: using extract_data = typename TStrategy::extract_data; TStrategy& strategy() { return *m_strategy; } std::vector& extracts() { return m_strategy->m_extracts; } TChild& self() { return *static_cast(this); } void node(const osmium::Node&) { } void way(const osmium::Way&) { } void relation(const osmium::Relation&) { } void enode(extract_data*, const osmium::Node&) { } void eway(extract_data*, const osmium::Way&) { } void erelation(extract_data*, const osmium::Relation&) { } public: explicit Pass(TStrategy* strategy) : m_strategy(strategy) { assert(strategy); } template void run(osmium::ProgressBar& progress_bar, Args... args) { osmium::io::Reader reader{std::forward(args)...}; run_impl(progress_bar, reader); reader.close(); } }; // class Pass #endif // EXTRACT_STRATEGY_HPP osmium-tool-1.17.0/src/extract/strategy_complete_ways.cpp000066400000000000000000000146141474143067200236440ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "strategy_complete_ways.hpp" #include "../util.hpp" #include #include #include #include #include namespace strategy_complete_ways { void Data::add_relation_parents(osmium::unsigned_object_id_type id, const osmium::index::RelationsMapIndex& map) { map.for_each(id, [&](osmium::unsigned_object_id_type parent_id) { if (!relation_ids.get(parent_id)) { relation_ids.set(parent_id); add_relation_parents(parent_id, map); } }); } Strategy::Strategy(const std::vector>& extracts, const osmium::Options& options) { m_extracts.reserve(extracts.size()); for (const auto& extract : extracts) { m_extracts.emplace_back(*extract); } for (const auto& option : options) { if (option.first != "relations") { warning(std::string{"Ignoring unknown option '"} + option.first + "' for 'complete_ways' strategy.\n"); } } if (options.is_false("relations")) { m_read_types = osmium::osm_entity_bits::node | osmium::osm_entity_bits::way; } } const char* Strategy::name() const noexcept { return "complete_ways"; } class Pass1 : public Pass { osmium::handler::CheckOrder m_check_order; osmium::index::RelationsMapStash m_relations_map_stash; public: explicit Pass1(Strategy* strategy) : Pass(strategy) { } void node(const osmium::Node& node) { m_check_order.node(node); } void enode(extract_data* e, const osmium::Node& node) { if (e->contains(node.location())) { e->node_ids.set(node.positive_id()); } } void way(const osmium::Way& way) { m_check_order.way(way); } void eway(extract_data* e, const osmium::Way& way) { for (const auto& nr : way.nodes()) { if (e->node_ids.get(nr.positive_ref())) { e->way_ids.set(way.positive_id()); for (const auto& nr : way.nodes()) { e->extra_node_ids.set(nr.ref()); } return; } } } void relation(const osmium::Relation& relation) { m_check_order.relation(relation); m_relations_map_stash.add_members(relation); } void erelation(extract_data* e, const osmium::Relation& relation) { for (const auto& member : relation.members()) { switch (member.type()) { case osmium::item_type::node: if (e->node_ids.get(member.positive_ref())) { e->relation_ids.set(relation.positive_id()); return; } break; case osmium::item_type::way: if (e->way_ids.get(member.positive_ref())) { e->relation_ids.set(relation.positive_id()); return; } break; default: break; } } } osmium::index::RelationsMapStash& relations_map_stash() noexcept { return m_relations_map_stash; } }; // class Pass1 class Pass2 : public Pass { public: explicit Pass2(Strategy* strategy) : Pass(strategy) { } void enode(extract_data* e, const osmium::Node& node) { if (e->node_ids.get(node.positive_id()) || e->extra_node_ids.get(node.positive_id())) { e->write(node); } } void eway(extract_data* e, const osmium::Way& way) { if (e->way_ids.get(way.positive_id())) { e->write(way); } } void erelation(extract_data* e, const osmium::Relation& relation) { if (e->relation_ids.get(relation.positive_id())) { e->write(relation); } } }; // class Pass2 void Strategy::run(osmium::VerboseOutput& vout, bool display_progress, const osmium::io::File& input_file) { if (input_file.filename().empty()) { throw osmium::io_error{"Can not read from STDIN when using 'complete_ways' strategy."}; } vout << "Running 'complete_ways' strategy in two passes...\n"; const std::size_t file_size = osmium::file_size(input_file.filename()); osmium::ProgressBar progress_bar{file_size * 2, display_progress}; vout << "First pass (of two)...\n"; Pass1 pass1{this}; pass1.run(progress_bar, input_file, osmium::io::read_meta::no, m_read_types); progress_bar.file_done(file_size); if (m_read_types & osmium::osm_entity_bits::relation) { // recursively get parents of all relations that are in an extract const auto relations_map = pass1.relations_map_stash().build_member_to_parent_index(); for (auto& e : m_extracts) { for (const osmium::unsigned_object_id_type id : e.relation_ids) { e.add_relation_parents(id, relations_map); } } } progress_bar.remove(); vout << "Second pass (of two)...\n"; Pass2 pass2{this}; pass2.run(progress_bar, input_file, m_read_types); progress_bar.done(); } } // namespace strategy_complete_ways osmium-tool-1.17.0/src/extract/strategy_complete_ways.hpp000066400000000000000000000042771474143067200236550ustar00rootroot00000000000000#ifndef EXTRACT_STRATEGY_COMPLETE_WAYS_HPP #define EXTRACT_STRATEGY_COMPLETE_WAYS_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "strategy.hpp" #include #include #include #include namespace strategy_complete_ways { struct Data { osmium::index::IdSetDense node_ids; osmium::index::IdSetDense extra_node_ids; osmium::index::IdSetDense way_ids; osmium::index::IdSetDense relation_ids; void add_relation_parents(osmium::unsigned_object_id_type id, const osmium::index::RelationsMapIndex& map); }; class Strategy : public ExtractStrategy { template friend class ::Pass; friend class Pass1; using extract_data = ExtractData; std::vector m_extracts; osmium::osm_entity_bits::type m_read_types = osmium::osm_entity_bits::nwr; public: explicit Strategy(const std::vector>& extracts, const osmium::Options& options); const char* name() const noexcept override final; void run(osmium::VerboseOutput& vout, bool display_progress, const osmium::io::File& input_file) override final; }; // class Strategy } // namespace strategy_complete_ways #endif // EXTRACT_STRATEGY_COMPLETE_WAYS_HPP osmium-tool-1.17.0/src/extract/strategy_complete_ways_with_history.cpp000066400000000000000000000143731474143067200264620ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "strategy_complete_ways_with_history.hpp" #include #include #include namespace strategy_complete_ways_with_history { void Data::add_relation_parents(osmium::unsigned_object_id_type id, const osmium::index::RelationsMapIndex& map) { map.for_each(id, [&](osmium::unsigned_object_id_type parent_id) { if (!relation_ids.get(parent_id)) { relation_ids.set(parent_id); add_relation_parents(parent_id, map); } }); } Strategy::Strategy(const std::vector>& extracts, const osmium::Options& /*options*/) { m_extracts.reserve(extracts.size()); for (const auto& extract : extracts) { m_extracts.emplace_back(*extract); } } const char* Strategy::name() const noexcept { return "complete_ways"; } class Pass1 : public Pass { osmium::index::RelationsMapStash m_relations_map_stash; std::vector m_current_way_nodes; osmium::unsigned_object_id_type m_current_way_id = 0; public: explicit Pass1(Strategy* strategy) : Pass(strategy) { } void add_extra_nodes() { for (auto& e : extracts()) { if (e.way_ids.get(m_current_way_id)) { for (const auto& id : m_current_way_nodes) { e.extra_node_ids.set(id); } } } m_current_way_nodes.clear(); } void enode(extract_data* e, const osmium::Node& node) { if (e->contains(node.location())) { e->node_ids.set(node.positive_id()); } } void way(const osmium::Way& way) { if (m_current_way_id != way.positive_id()) { add_extra_nodes(); m_current_way_id = way.id(); } for (const auto& wn : way.nodes()) { m_current_way_nodes.push_back(wn.positive_ref()); } } void eway(extract_data* e, const osmium::Way& way) { for (const auto& nr : way.nodes()) { if (e->node_ids.get(nr.positive_ref())) { e->way_ids.set(way.positive_id()); return; } } } void relation(const osmium::Relation& relation) { m_relations_map_stash.add_members(relation); } void erelation(extract_data* e, const osmium::Relation& relation) { for (const auto& member : relation.members()) { switch (member.type()) { case osmium::item_type::node: if (e->node_ids.get(member.positive_ref())) { e->relation_ids.set(relation.positive_id()); return; } break; case osmium::item_type::way: if (e->way_ids.get(member.positive_ref())) { e->relation_ids.set(relation.positive_id()); return; } break; default: break; } } } osmium::index::RelationsMapStash& relations_map_stash() noexcept { return m_relations_map_stash; } }; // class Pass1 class Pass2 : public Pass { public: explicit Pass2(Strategy* strategy) : Pass(strategy) { } void enode(extract_data* e, const osmium::Node& node) { if (e->node_ids.get(node.positive_id()) || e->extra_node_ids.get(node.positive_id())) { e->write(node); } } void eway(extract_data* e, const osmium::Way& way) { if (e->way_ids.get(way.positive_id())) { e->write(way); } } void erelation(extract_data* e, const osmium::Relation& relation) { if (e->relation_ids.get(relation.positive_id())) { e->write(relation); } } }; // class Pass2 void Strategy::run(osmium::VerboseOutput& vout, bool display_progress, const osmium::io::File& input_file) { if (input_file.filename().empty()) { throw osmium::io_error{"Can not read from STDIN when using 'complete_ways' strategy."}; } vout << "Running 'complete_ways' strategy on history file in two passes...\n"; const std::size_t file_size = osmium::file_size(input_file.filename()); osmium::ProgressBar progress_bar{file_size * 2, display_progress}; vout << "First pass (of two)...\n"; Pass1 pass1{this}; pass1.run(progress_bar, input_file); progress_bar.file_done(file_size); pass1.add_extra_nodes(); // recursively get parents of all relations that are in an extract const auto relations_map = pass1.relations_map_stash().build_member_to_parent_index(); for (auto& e : m_extracts) { for (const osmium::unsigned_object_id_type id : e.relation_ids) { e.add_relation_parents(id, relations_map); } } progress_bar.remove(); vout << "Second pass (of two)...\n"; Pass2 pass2{this}; pass2.run(progress_bar, input_file); progress_bar.done(); } } // namespace strategy_complete_ways_with_history osmium-tool-1.17.0/src/extract/strategy_complete_ways_with_history.hpp000066400000000000000000000042601474143067200264610ustar00rootroot00000000000000#ifndef EXTRACT_STRATEGY_COMPLETE_WAYS_WITH_HISTORY_HPP #define EXTRACT_STRATEGY_COMPLETE_WAYS_WITH_HISTORY_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "strategy.hpp" #include #include #include #include namespace strategy_complete_ways_with_history { struct Data { osmium::index::IdSetDense node_ids; osmium::index::IdSetDense extra_node_ids; osmium::index::IdSetDense way_ids; osmium::index::IdSetDense relation_ids; void add_relation_parents(osmium::unsigned_object_id_type id, const osmium::index::RelationsMapIndex& map); }; class Strategy : public ExtractStrategy { template friend class ::Pass; friend class Pass1; using extract_data = ExtractData; std::vector m_extracts; public: explicit Strategy(const std::vector>& extracts, const osmium::Options& /*options*/); const char* name() const noexcept override final; void run(osmium::VerboseOutput& vout, bool display_progress, const osmium::io::File& input_file) override final; }; // class Strategy } // namespace strategy_complete_ways_with_history #endif // EXTRACT_STRATEGY_COMPLETE_WAYS_WITH_HISTORY_HPP osmium-tool-1.17.0/src/extract/strategy_simple.cpp000066400000000000000000000072771474143067200222710ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "strategy_simple.hpp" #include "../util.hpp" #include #include #include #include namespace strategy_simple { Strategy::Strategy(const std::vector>& extracts, const osmium::Options& options) { m_extracts.reserve(extracts.size()); for (const auto& extract : extracts) { m_extracts.emplace_back(*extract); } for (const auto& option : options) { warning(std::string{"Ignoring unknown option '"} + option.first + "' for 'simple' strategy.\n"); } } const char* Strategy::name() const noexcept { return "simple"; } class Pass1 : public Pass { osmium::handler::CheckOrder m_check_order; public: explicit Pass1(Strategy* strategy) : Pass(strategy) { } void node(const osmium::Node& node) { m_check_order.node(node); } void enode(extract_data* e, const osmium::Node& node) { if (e->contains(node.location())) { e->write(node); e->node_ids.set(node.positive_id()); } } void way(const osmium::Way& way) { m_check_order.way(way); } void eway(extract_data* e, const osmium::Way& way) { for (const auto& nr : way.nodes()) { if (e->node_ids.get(nr.positive_ref())) { e->write(way); e->way_ids.set(way.positive_id()); } return; } } void relation(const osmium::Relation& relation) { m_check_order.relation(relation); } void erelation(extract_data* e, const osmium::Relation& relation) { for (const auto& member : relation.members()) { switch (member.type()) { case osmium::item_type::node: if (e->node_ids.get(member.positive_ref())) { e->write(relation); } return; case osmium::item_type::way: if (e->way_ids.get(member.positive_ref())) { e->write(relation); } return; default: break; } } } }; // class Pass1 void Strategy::run(osmium::VerboseOutput& vout, bool display_progress, const osmium::io::File& input_file) { vout << "Running 'simple' strategy in one pass...\n"; const std::size_t file_size = input_file.filename().empty() ? 0 : osmium::file_size(input_file.filename()); osmium::ProgressBar progress_bar{file_size, display_progress}; Pass1 pass1{this}; pass1.run(progress_bar, input_file); progress_bar.done(); } } // namespace strategy_simple osmium-tool-1.17.0/src/extract/strategy_simple.hpp000066400000000000000000000034011474143067200222570ustar00rootroot00000000000000#ifndef EXTRACT_STRATEGY_SIMPLE_HPP #define EXTRACT_STRATEGY_SIMPLE_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "strategy.hpp" #include #include #include namespace strategy_simple { struct Data { osmium::index::IdSetDense node_ids; osmium::index::IdSetDense way_ids; }; class Strategy : public ExtractStrategy { template friend class ::Pass; friend class Pass1; using extract_data = ExtractData; std::vector m_extracts; public: explicit Strategy(const std::vector>& extracts, const osmium::Options& /*options*/); const char* name() const noexcept override final; void run(osmium::VerboseOutput& vout, bool display_progress, const osmium::io::File& input_file) override final; }; // class Strategy } // namespace strategy_simple #endif // EXTRACT_STRATEGY_SIMPLE_HPP osmium-tool-1.17.0/src/extract/strategy_smart.cpp000066400000000000000000000275651474143067200221300ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "strategy_smart.hpp" #include "../util.hpp" #include #include #include #include #include #include #include #include #include namespace strategy_smart { void Data::add_relation_members(const osmium::Relation& relation) { for (const auto& member : relation.members()) { const auto ref = member.positive_ref(); switch (member.type()) { case osmium::item_type::node: extra_node_ids.set(ref); break; case osmium::item_type::way: extra_way_ids.set(ref); break; default: break; } } } void Data::add_relation_parents(osmium::unsigned_object_id_type id, const osmium::index::RelationsMapIndex& map) { map.for_each(id, [&](osmium::unsigned_object_id_type parent_id) { if (!relation_ids.get(parent_id) && !extra_relation_ids.get(parent_id)) { relation_ids.set(parent_id); add_relation_parents(parent_id, map); } }); } Strategy::Strategy(const std::vector>& extracts, const osmium::Options& options) { m_extracts.reserve(extracts.size()); for (const auto& extract : extracts) { m_extracts.emplace_back(*extract); } m_types = {"multipolygon"}; for (const auto& option : options) { if (option.first == "types") { if (option.second.empty() || option.second == "any" || option.second == "true") { m_types.clear(); } else { m_types = osmium::split_string(option.second, ',', true); } } else if (option.first == "complete-partial-relations") { if (!option.second.empty()) { m_complete_partial_relations_percentage = osmium::detail::str_to_int(option.second.c_str()); if (m_complete_partial_relations_percentage <= 0 || m_complete_partial_relations_percentage > 100) { m_complete_partial_relations_percentage = 100; } } } else if (option.first == "tags") { m_filter_tags = osmium::split_string(option.second, ',', true); m_filter.set_default_result(false); for (const auto &tag : m_filter_tags) { const auto pos = tag.find('='); if (pos == std::string::npos) { m_filter.add_rule(true, osmium::TagMatcher{tag}); } else { const auto key = tag.substr(0, pos); const auto value = tag.substr(pos + 1); m_filter.add_rule(true, osmium::TagMatcher{key, value}); } } } else { warning(std::string{"Ignoring unknown option '"} + option.first + "' for 'smart' strategy.\n"); } } } const char* Strategy::name() const noexcept { return "smart"; } bool Strategy::check_members_count(const std::size_t size, const std::size_t wanted_members) const noexcept { return wanted_members * 100 >= size * m_complete_partial_relations_percentage; } bool Strategy::check_type(const osmium::Relation& relation) const noexcept { if (m_types.empty()) { return true; } const char* type = relation.tags()["type"]; if (!type) { return false; } const auto it = std::find(m_types.begin(), m_types.end(), type); return it != m_types.end(); } bool Strategy::check_tags(const osmium::Relation& relation) const noexcept { return osmium::tags::match_any_of(relation.tags(), m_filter); } void Strategy::show_arguments(osmium::VerboseOutput& vout) { vout << "Additional strategy options:\n"; if (m_types.empty()) { vout << " - [types] relation types: any\n"; } else { std::string typelist; for (const auto& type : m_types) { if (!typelist.empty()) { typelist += ", "; } typelist += type; } vout << " - [types] relation types: " << typelist << '\n'; } if (m_complete_partial_relations_percentage == 100) { vout << " - [complete-partial-relations] do not complete partial relations\n"; } else { vout << " - [complete-partial-relations] complete partial relations when " << m_complete_partial_relations_percentage << "% or more members are in extract\n"; } if (m_filter_tags.empty()) { vout << " - [tags] no tags defined\n"; } else { std::string filterlist; for (const auto& tag : m_filter_tags) { if (!filterlist.empty()) { filterlist += ","; } filterlist += tag; } vout << " - [tags] " << filterlist << '\n'; } vout << '\n'; } class Pass1 : public Pass { osmium::handler::CheckOrder m_check_order; osmium::index::RelationsMapStash m_relations_map_stash; public: explicit Pass1(Strategy* strategy) : Pass(strategy) { } void node(const osmium::Node& node) { m_check_order.node(node); } void enode(extract_data* e, const osmium::Node& node) { if (e->contains(node.location())) { e->node_ids.set(node.positive_id()); } } void way(const osmium::Way& way) { m_check_order.way(way); } void eway(extract_data* e, const osmium::Way& way) { for (const auto& nr : way.nodes()) { if (e->node_ids.get(nr.positive_ref())) { e->way_ids.set(way.positive_id()); return; } } } void relation(const osmium::Relation& relation) { m_check_order.relation(relation); m_relations_map_stash.add_members(relation); } void erelation(extract_data* e, const osmium::Relation& relation) { std::size_t wanted_members = 0; for (const auto& member : relation.members()) { switch (member.type()) { case osmium::item_type::node: if (e->node_ids.get(member.positive_ref())) { if (wanted_members == 0) { e->relation_ids.set(relation.positive_id()); if (strategy().check_type(relation) && strategy().check_tags(relation)) { e->add_relation_members(relation); return; } } ++wanted_members; } break; case osmium::item_type::way: if (e->way_ids.get(member.positive_ref())) { if (wanted_members == 0) { e->relation_ids.set(relation.positive_id()); if (strategy().check_type(relation) && strategy().check_tags(relation)) { e->add_relation_members(relation); return; } } ++wanted_members; } break; default: break; } } if (strategy().check_members_count(relation.members().size(), wanted_members) && strategy().check_tags(relation)) { e->add_relation_members(relation); } } osmium::index::RelationsMapStash& relations_map_stash() noexcept { return m_relations_map_stash; } }; // class Pass1 class Pass2 : public Pass { public: explicit Pass2(Strategy* strategy) : Pass(strategy) { } void eway(extract_data* e, const osmium::Way& way) { if (e->way_ids.get(way.positive_id()) || e->extra_way_ids.get(way.positive_id())) { for (const auto& nr : way.nodes()) { e->extra_node_ids.set(nr.ref()); } } } }; // class Pass2 class Pass3 : public Pass { public: explicit Pass3(Strategy* strategy) : Pass(strategy) { } void enode(extract_data* e, const osmium::Node& node) { if (e->node_ids.get(node.positive_id()) || e->extra_node_ids.get(node.positive_id())) { e->write(node); } } void eway(extract_data* e, const osmium::Way& way) { if (e->way_ids.get(way.positive_id()) || e->extra_way_ids.get(way.positive_id())) { e->write(way); } } void erelation(extract_data* e, const osmium::Relation& relation) { if (e->relation_ids.get(relation.positive_id()) || e->extra_relation_ids.get(relation.positive_id())) { e->write(relation); } } }; // class Pass3 void Strategy::run(osmium::VerboseOutput& vout, bool display_progress, const osmium::io::File& input_file) { if (input_file.filename().empty()) { throw osmium::io_error{"Can not read from STDIN when using 'smart' strategy."}; } vout << "Running 'smart' strategy in three passes...\n"; const std::size_t file_size = osmium::file_size(input_file.filename()); osmium::ProgressBar progress_bar{file_size * 3, display_progress}; vout << "First pass (of three)...\n"; Pass1 pass1{this}; pass1.run(progress_bar, input_file, osmium::io::read_meta::no); progress_bar.file_done(file_size); // recursively get parents of all relations that are in an extract const auto relations_map = pass1.relations_map_stash().build_member_to_parent_index(); for (auto& e : m_extracts) { for (const osmium::unsigned_object_id_type id : e.relation_ids) { e.add_relation_parents(id, relations_map); } } progress_bar.remove(); vout << "Second pass (of three)...\n"; Pass2 pass2{this}; pass2.run(progress_bar, input_file, osmium::osm_entity_bits::way, osmium::io::read_meta::no); progress_bar.file_done(file_size); progress_bar.remove(); vout << "Third pass (of three)...\n"; Pass3 pass3{this}; pass3.run(progress_bar, input_file); progress_bar.done(); } } // namespace strategy_smart osmium-tool-1.17.0/src/extract/strategy_smart.hpp000066400000000000000000000056001474143067200221170ustar00rootroot00000000000000#ifndef EXTRACT_STRATEGY_SMART_HPP #define EXTRACT_STRATEGY_SMART_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "strategy.hpp" #include #include #include #include #include #include namespace strategy_smart { struct Data { osmium::index::IdSetDense node_ids; osmium::index::IdSetDense extra_node_ids; osmium::index::IdSetDense way_ids; osmium::index::IdSetDense extra_way_ids; osmium::index::IdSetDense relation_ids; osmium::index::IdSetDense extra_relation_ids; void add_relation_members(const osmium::Relation& relation); void add_relation_parents(osmium::unsigned_object_id_type id, const osmium::index::RelationsMapIndex& map); }; class Strategy : public ExtractStrategy { template friend class ::Pass; friend class Pass1; using extract_data = ExtractData; std::vector m_extracts; std::vector m_types; std::size_t m_complete_partial_relations_percentage = 100; std::vector m_filter_tags; osmium::TagsFilter m_filter{true}; bool check_members_count(const std::size_t size, const std::size_t wanted_members) const noexcept; bool check_type(const osmium::Relation& relation) const noexcept; bool check_tags(const osmium::Relation& relation) const noexcept; public: explicit Strategy(const std::vector>& extracts, const osmium::Options& options); const char* name() const noexcept override final; void show_arguments(osmium::VerboseOutput& vout) override final; void run(osmium::VerboseOutput& vout, bool display_progress, const osmium::io::File& input_file) override final; }; // class Strategy } // namespace strategy_smart #endif // EXTRACT_STRATEGY_SMART_HPP osmium-tool-1.17.0/src/id_file.cpp000066400000000000000000000034171474143067200167670ustar00rootroot00000000000000 #include "id_file.hpp" #include "util.hpp" #include #include #include #include #include #include #include void add_nodes(const osmium::Way& way, ids_type& ids) { for (const auto& nr : way.nodes()) { ids(osmium::item_type::node).set(nr.positive_ref()); } } void read_id_osm_file(const std::string& file_name, ids_type& ids) { osmium::io::Reader reader{file_name, osmium::osm_entity_bits::object}; while (osmium::memory::Buffer buffer = reader.read()) { for (const auto& object : buffer.select()) { ids(object.type()).set(object.positive_id()); } } reader.close(); } void parse_and_add_id(const std::string& s, ids_type& ids, osmium::item_type default_item_type) { auto p = osmium::string_to_object_id(s.c_str(), osmium::osm_entity_bits::nwr, default_item_type); if (p.second < 0) { throw std::runtime_error{"This command does not work with negative IDs"}; } ids(p.first).set(static_cast(p.second)); } void read_id_file(std::istream& stream, ids_type& ids, osmium::item_type default_item_type) { for (std::string line; std::getline(stream, line);) { strip_whitespace(line); const auto pos = line.find_first_of(" #"); if (pos != std::string::npos) { line.erase(pos); } if (!line.empty()) { parse_and_add_id(line, ids, default_item_type); } } } bool no_ids(const ids_type& ids) noexcept { return ids(osmium::item_type::node).empty() && ids(osmium::item_type::way).empty() && ids(osmium::item_type::relation).empty(); } osmium-tool-1.17.0/src/id_file.hpp000066400000000000000000000013111474143067200167630ustar00rootroot00000000000000#ifndef ID_FILES_HPP #define ID_FILES_HPP #include #include #include #include #include #include using ids_type = osmium::nwr_array>; void add_nodes(const osmium::Way& way, ids_type& ids); void read_id_osm_file(const std::string& file_name, ids_type& ids); void parse_and_add_id(const std::string& s, ids_type& ids, osmium::item_type default_item_type); void read_id_file(std::istream& stream, ids_type& ids, osmium::item_type default_item_type); bool no_ids(const ids_type& ids) noexcept; #endif // ID_FILES_HPP osmium-tool-1.17.0/src/io.cpp000066400000000000000000000171651474143067200160100ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" #include "exception.hpp" #include "util.hpp" #include // IWYU pragma: keep #include // IWYU pragma: keep #include #include #include #include #include #include #include void with_single_osm_input::setup_input_file(const boost::program_options::variables_map& vm) { if (vm.count("input-filename")) { m_input_filename = vm["input-filename"].as(); } if (vm.count("input-format")) { m_input_format = vm["input-format"].as(); } if (m_input_format.empty()) { if (m_input_filename == "-") { throw argument_error{"When reading from STDIN you need to use the --input-format/-F option\n" "to specify the file format."}; } if (m_input_filename.empty()) { throw argument_error{"Missing input file. Use '-' to read from STDIN and add the --input-format/-F\n" "option to specify the file format or specify the input file name."}; } } m_input_file = osmium::io::File{m_input_filename, m_input_format}; } po::options_description with_single_osm_input::add_single_input_options() { po::options_description options{"INPUT OPTIONS"}; options.add_options() ("input-format,F", po::value(), "Format of input file") ; return options; } void with_single_osm_input::show_single_input_arguments(osmium::VerboseOutput& vout) { vout << " input options:\n"; vout << " file name: " << m_input_filename << "\n"; vout << " file format: " << m_input_format << "\n"; } void with_multiple_osm_inputs::setup_input_files(const boost::program_options::variables_map& vm) { if (vm.count("input-filenames")) { m_input_filenames = vm["input-filenames"].as>(); } else { m_input_filenames.emplace_back("-"); // default is stdin } bool uses_stdin = false; for (auto& filename : m_input_filenames) { if (filename == "-") { if (uses_stdin) { throw argument_error{"Can read at most one file from STDIN."}; } uses_stdin = true; } } if (vm.count("input-format")) { m_input_format = vm["input-format"].as(); } if (uses_stdin && m_input_format.empty()) { throw argument_error{"When reading from STDIN you need to use the --input-format/-F option\n" "to specify the file format. Or are you missing a file name argument?"}; } for (const std::string& input_filename : m_input_filenames) { const osmium::io::File input_file{input_filename, m_input_format}; m_input_files.push_back(input_file); } } po::options_description with_multiple_osm_inputs::add_multiple_inputs_options() { po::options_description options{"INPUT OPTIONS"}; options.add_options() ("input-format,F", po::value(), "Format of input files") ; return options; } void with_multiple_osm_inputs::show_multiple_inputs_arguments(osmium::VerboseOutput& vout) { vout << " input options:\n"; vout << " file names: \n"; for (const auto& fn : m_input_filenames) { vout << " " << fn << "\n"; } vout << " file format: " << m_input_format << "\n"; } void with_osm_output::init_output_file(const po::variables_map& vm) { if (vm.count("generator")) { m_generator = vm["generator"].as(); } if (vm.count("output")) { m_output_filename = vm["output"].as(); } if (vm.count("output-format")) { m_output_format = vm["output-format"].as(); } if (vm.count("output-header")) { m_output_headers = vm["output-header"].as>(); } if (vm.count("overwrite")) { m_output_overwrite = osmium::io::overwrite::allow; } if (vm.count("fsync")) { m_fsync = osmium::io::fsync::yes; } } void with_osm_output::check_output_file() { if (m_output_format.empty()) { if (m_output_filename == "-") { throw argument_error{"When writing to STDOUT you need to use the --output-format/-f\n" "option to specify the file format."}; } if (m_output_filename.empty()) { throw argument_error{"Missing output file. Set the output file with --output/-o and/or\n" "add the --output-format/-f option to specify the file format."}; } } m_output_file = osmium::io::File{m_output_filename, m_output_format}; m_output_file.check(); } void with_osm_output::setup_output_file(const po::variables_map& vm) { init_output_file(vm); check_output_file(); } po::options_description with_osm_output::add_output_options() { po::options_description options{"OUTPUT OPTIONS"}; options.add_options() ("output-format,f", po::value(), "Format of output file") ("fsync", "Call fsync after writing file") ("generator", po::value(), "Generator setting for file header") ("output,o", po::value(), "Output file") ("overwrite,O", "Allow existing output file to be overwritten") ("output-header", po::value>(), "Add output header") ; return options; } void with_osm_output::show_output_arguments(osmium::VerboseOutput& vout) { vout << " output options:\n"; vout << " file name: " << m_output_filename << "\n"; vout << " file format: " << m_output_format << "\n"; vout << " generator: " << m_generator << "\n"; vout << " overwrite: " << yes_no(m_output_overwrite == osmium::io::overwrite::allow); vout << " fsync: " << yes_no(m_fsync == osmium::io::fsync::yes); if (!m_output_headers.empty()) { vout << " output header:\n"; for (const auto& h : m_output_headers) { vout << " " << h << "\n"; } } } void with_osm_output::setup_header(osmium::io::Header& header) const { header.set("generator", m_generator); for (const auto& h : m_output_headers) { header.set(h); } } void init_header(osmium::io::Header& header, const osmium::io::Header& input_header, const std::vector& options) { for (const auto& h : options) { if (!h.empty() && h.back() == '!') { std::string hc{h}; hc.resize(h.size() - 1); header.set(hc, input_header.get(hc)); } else { header.set(h); } } } void with_osm_output::setup_header(osmium::io::Header& header, const osmium::io::Header& input_header) const { header.set("generator", m_generator); init_header(header, input_header, m_output_headers); } osmium-tool-1.17.0/src/main.cpp000066400000000000000000000115051474143067200163150ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "cmd.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 # include # include #endif enum return_code : int { okay = 0, error = 1, fatal = 2 }; int main(int argc, char* argv[]) { #ifdef _WIN32 _setmode(1, _O_BINARY); #endif std::string command{argv[0]}; // remove path from command // (backslash for windows, slash for everybody else) if (command.find_last_of("/\\") != std::string::npos) { command = command.substr(command.find_last_of("/\\") + 1); } std::vector arguments; for (int i = 1; i < argc; ++i) { arguments.push_back(argv[i]); } if (command == "osmium" || command == "osmium.exe") { if (arguments.empty()) { command = "help"; } else { if (arguments.front() == "--help" || arguments.front() == "-h") { command = "help"; } else if (arguments.front() == "--version") { command = "version"; } else { command = arguments.front(); } arguments.erase(arguments.begin()); } } else { if (command.substr(0, 7) == "osmium-") { command = command.substr(7); } } if (command == "version") { std::cout << get_osmium_long_version() << '\n' << get_libosmium_version() << '\n' << "Supported PBF compression types:"; for (const auto& type : osmium::io::supported_pbf_compression_types()) { std::cout << " " << type; } std::cout << "\n\nCopyright (C) 2013-2025 Jochen Topf \n" << "License: GNU GENERAL PUBLIC LICENSE Version 3 .\n" << "This is free software: you are free to change and redistribute it.\n" << "There is NO WARRANTY, to the extent permitted by law.\n"; return return_code::okay; } CommandFactory command_factory; register_commands(command_factory); std::unique_ptr cmd = command_factory.create_command(command); if (!cmd) { std::cerr << "Unknown command or option '" << command << "'. Try 'osmium help'.\n"; return return_code::fatal; } try { if (!cmd->setup(arguments)) { return return_code::okay; } } catch (const boost::program_options::error& e) { std::cerr << "Error parsing command line: " << e.what() << '\n'; return return_code::fatal; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; return return_code::fatal; } cmd->print_arguments(command); try { if (cmd->run()) { return return_code::okay; } } catch (const std::bad_alloc&) { std::cerr << "Out of memory. Read the MEMORY USAGE section of the osmium(1) manpage.\n"; } catch (const osmium::out_of_order_error& e) { std::cerr << e.what() << '\n'; std::cerr << "This command expects the input file to be ordered: First nodes in order of ID,\n" << "then ways in order of ID, then relations in order of ID.\n"; } catch (const std::system_error& e) { std::cerr << e.what(); if (e.code().value() == EEXIST) { std::cerr << ". Try using --overwrite if you are sure you want to overwrite the file."; } std::cerr << '\n'; } catch (const osmium::geometry_error& e) { std::cerr << "Geometry error: " << e.what() << '\n'; } catch (const osmium::invalid_location&) { std::cerr << "Geometry error: Invalid location. Usually this means a node was missing from the input data.\n"; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; } return return_code::error; } osmium-tool-1.17.0/src/option_clean.cpp000066400000000000000000000062541474143067200200500ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "option_clean.hpp" #include "exception.hpp" #include #include #include #include void OptionClean::setup(const boost::program_options::variables_map& vm) { if (vm.count("clean")) { for (const auto& c : vm["clean"].as>()) { if (c == "version") { m_clean_attrs |= clean_options::clean_version; } else if (c == "changeset") { m_clean_attrs |= clean_options::clean_changeset; } else if (c == "timestamp") { m_clean_attrs |= clean_options::clean_timestamp; } else if (c == "uid") { m_clean_attrs |= clean_options::clean_uid; } else if (c == "user") { m_clean_attrs |= clean_options::clean_user; } else { throw argument_error{"Unknown attribute on --clean option: '" + c + "'"}; } } } } void OptionClean::clean_buffer(osmium::memory::Buffer& buffer) const { for (auto& object : buffer.select()) { if (m_clean_attrs & clean_options::clean_version) { object.set_version(static_cast(0)); } if (m_clean_attrs & clean_options::clean_changeset) { object.set_changeset(static_cast(0)); } if (m_clean_attrs & clean_options::clean_timestamp) { object.set_timestamp(osmium::Timestamp{}); } if (m_clean_attrs & clean_options::clean_uid) { object.set_uid(static_cast(0)); } if (m_clean_attrs & clean_options::clean_user) { object.clear_user(); } } } std::string OptionClean::to_string() const { if (!m_clean_attrs) { return "(none)"; } std::string clean_names; if (m_clean_attrs & clean_options::clean_version) { clean_names += "version,"; } if (m_clean_attrs & clean_options::clean_changeset) { clean_names += "changeset,"; } if (m_clean_attrs & clean_options::clean_timestamp) { clean_names += "timestamp,"; } if (m_clean_attrs & clean_options::clean_uid) { clean_names += "uid,"; } if (m_clean_attrs & clean_options::clean_user) { clean_names += "user,"; } clean_names.resize(clean_names.size() - 1); return clean_names; } osmium-tool-1.17.0/src/option_clean.hpp000066400000000000000000000030321474143067200200440ustar00rootroot00000000000000#ifndef OPTION_CLEAN_HPP #define OPTION_CLEAN_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include #include #include class OptionClean { enum clean_options : uint8_t { clean_version = 0x01, clean_changeset = 0x02, clean_timestamp = 0x04, clean_uid = 0x08, clean_user = 0x10 }; uint8_t m_clean_attrs = 0; void clean_buffer(osmium::memory::Buffer& buffer) const; public: OptionClean() = default; void setup(const boost::program_options::variables_map& vm); void apply_to(osmium::memory::Buffer& buffer) const { if (m_clean_attrs) { clean_buffer(buffer); } } std::string to_string() const; }; // class OptionClean #endif // OPTION_CLEAN_HPP osmium-tool-1.17.0/src/util.cpp000066400000000000000000000171711474143067200163530ustar00rootroot00000000000000/* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include "util.hpp" #include "exception.hpp" #include #include #include #include #include #include #include #include #include #include #include #include /** * Get the suffix of the given file name. The suffix is everything after * the *first* dot (.). So multiple suffixes will all be returned. * * france.poly -> poly * planet.osm.bz2 -> osm.bz2 * some/path/planet.osm.bz2 -> osm.bz2 */ std::string get_filename_suffix(const std::string& file_name) { auto slash = file_name.find_last_of('/'); if (slash == std::string::npos) { slash = 0; } const auto dot = file_name.find_first_of('.', slash); if (dot == std::string::npos) { return ""; } return file_name.substr(dot + 1); } const char* yes_no(bool choice) noexcept { return choice ? "yes\n" : "no\n"; } void warning(const char* text) { std::cerr << "WARNING: " << text; } void warning(const std::string& text) { std::cerr << "WARNING: " << text; } std::size_t file_size(const osmium::io::File& file) { if (file.filename().empty()) { return 0; } return osmium::file_size(file.filename()); } std::size_t file_size_sum(const std::vector& files) { std::size_t sum = 0; for (const auto& file : files) { sum += file_size(file); } return sum; } osmium::osm_entity_bits::type get_types(const std::string& str) { osmium::osm_entity_bits::type entities{osmium::osm_entity_bits::nothing}; for (const auto c : str) { switch (c) { case 'n': entities |= osmium::osm_entity_bits::node; break; case 'w': entities |= osmium::osm_entity_bits::way; break; case 'r': entities |= osmium::osm_entity_bits::relation; break; case 'a': entities |= osmium::osm_entity_bits::area; break; default: throw argument_error{std::string{"Unknown object type '"} + c + "' (allowed are 'n', 'w', 'r', and 'a')."}; } } return entities; } std::pair get_filter_expression(const std::string& str) { auto pos = str.find('/'); osmium::osm_entity_bits::type entities{osmium::osm_entity_bits::nwr}; if (pos == std::string::npos) { pos = 0; } else if (pos == 0) { pos = 1; } else { entities = get_types(str.substr(0, pos)); ++pos; } return std::make_pair(entities, &str[pos]); } void strip_whitespace(std::string& string) { while (!string.empty() && string.back() == ' ') { string.pop_back(); } const auto pos = string.find_first_not_of(' '); if (pos != std::string::npos) { string.erase(0, pos); } } osmium::StringMatcher get_string_matcher(std::string string) { strip_whitespace(string); if (string.size() == 1 && string.front() == '*') { return osmium::StringMatcher::always_true{}; } if (string.empty() || (string.back() != '*' && string.front() != '*')) { if (string.find(',') == std::string::npos) { return osmium::StringMatcher::equal{string}; } auto sstrings = osmium::split_string(string, ','); for (auto& s : sstrings) { strip_whitespace(s); } return osmium::StringMatcher::list{sstrings}; } auto s = string; if (s.back() == '*' && s.front() != '*') { s.pop_back(); return osmium::StringMatcher::prefix{s}; } if (s.front() == '*') { s.erase(0, 1); } if (!s.empty() && s.back() == '*') { s.pop_back(); } return osmium::StringMatcher::substring{s}; } osmium::TagMatcher get_tag_matcher(const std::string& expression, bool* has_value_matcher) { const auto op_pos = expression.find('='); if (op_pos == std::string::npos) { if (has_value_matcher) { *has_value_matcher = false; } return osmium::TagMatcher{get_string_matcher(expression)}; } auto key = expression.substr(0, op_pos); const auto value = expression.substr(op_pos + 1); bool invert = false; if (!key.empty() && key.back() == '!') { key.pop_back(); invert = true; } if (has_value_matcher) { *has_value_matcher = true; } return osmium::TagMatcher{get_string_matcher(key), get_string_matcher(value), invert}; } void initialize_tags_filter(osmium::TagsFilter& tags_filter, const bool default_result, const std::vector& strings) { tags_filter.set_default_result(default_result); for (const auto& str : strings) { assert(!str.empty()); tags_filter.add_rule(!default_result, get_tag_matcher(str)); } } osmium::Box parse_bbox(const std::string& str, const std::string& option_name) { const auto coordinates = osmium::split_string(str, ','); if (coordinates.size() != 4) { throw argument_error{"Need exactly four coordinates in " + option_name + " option."}; } osmium::Location location1; location1.set_lon(coordinates[0].c_str()); location1.set_lat(coordinates[1].c_str()); osmium::Location location2; location2.set_lon(coordinates[2].c_str()); location2.set_lat(coordinates[3].c_str()); osmium::Box box; box.extend(location1); box.extend(location2); if (!box.valid()) { throw argument_error{"Invalid bounding box in " + option_name + " option. Format is LONG1,LAT1,LONG2,LAT2."}; } return box; } osmium::item_type parse_item_type(const std::string& t) { if (t == "n" || t == "node") { return osmium::item_type::node; } if (t == "w" || t == "way") { return osmium::item_type::way; } if (t == "r" || t == "relation") { return osmium::item_type::relation; } throw argument_error{std::string{"Unknown default type '"} + t + "' (Allowed are 'node', 'way', and 'relation')."}; } const char* object_type_as_string(const osmium::OSMObject& object) noexcept { if (object.type() == osmium::item_type::area) { if (static_cast(object).from_way()) { return "way"; } return "relation"; } return osmium::item_type_to_name(object.type()); } bool ends_with(const std::string& str, const std::string& suffix) { if (suffix.size() > str.size()) { return false; } return std::strcmp(str.c_str() + (str.size() - suffix.size()), suffix.c_str()) == 0; } std::size_t show_mbytes(std::size_t value) noexcept { return value / (1024UL * 1024UL); } double show_gbytes(std::size_t value) noexcept { return static_cast(show_mbytes(value)) / 1000; // NOLINT(bugprone-integer-division) } osmium-tool-1.17.0/src/util.hpp000066400000000000000000000044001474143067200163470ustar00rootroot00000000000000#ifndef UTIL_HPP #define UTIL_HPP /* Osmium -- OpenStreetMap data manipulation command line tool https://osmcode.org/osmium-tool/ Copyright (C) 2013-2025 Jochen Topf 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 . */ #include #include #include #include #include #include #include #include #include #include std::string get_filename_suffix(const std::string& file_name); const char* yes_no(bool choice) noexcept; void warning(const char* text); void warning(const std::string& text); std::size_t file_size(const osmium::io::File& file); std::size_t file_size_sum(const std::vector& files); osmium::osm_entity_bits::type get_types(const std::string& str); std::pair get_filter_expression(const std::string& str); void strip_whitespace(std::string& string); osmium::StringMatcher get_string_matcher(std::string string); osmium::TagMatcher get_tag_matcher(const std::string& expression, bool* has_value_matcher = nullptr); void initialize_tags_filter(osmium::TagsFilter& tags_filter, bool default_result, const std::vector& strings); osmium::Box parse_bbox(const std::string& str, const std::string& option_name); osmium::item_type parse_item_type(const std::string& t); const char* object_type_as_string(const osmium::OSMObject& object) noexcept; bool ends_with(const std::string& str, const std::string& suffix); std::size_t show_mbytes(std::size_t value) noexcept; double show_gbytes(std::size_t value) noexcept; #endif // UTIL_HPP osmium-tool-1.17.0/src/version.cpp.in000066400000000000000000000005201474143067200174560ustar00rootroot00000000000000 #include const char* get_osmium_version() noexcept { return "@PROJECT_VERSION@"; } const char* get_osmium_long_version() noexcept { return "osmium version @PROJECT_VERSION@@VERSION_FROM_GIT@"; } const char* get_libosmium_version() noexcept { return "libosmium version " LIBOSMIUM_VERSION_STRING; } osmium-tool-1.17.0/test/000077500000000000000000000000001474143067200150535ustar00rootroot00000000000000osmium-tool-1.17.0/test/CMakeLists.txt000066400000000000000000000071151474143067200176170ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests # #----------------------------------------------------------------------------- include_directories(include) include_directories(../src) include_directories(../src/extract) include_directories(../include) set(ALL_UNIT_TESTS cat/test_setup.cpp diff/test_setup.cpp extract/test_unit.cpp time-filter/test_setup.cpp util/test_unit.cpp ) foreach(_source_file ${OSMIUM_SOURCE_FILES}) list(APPEND ALL_COMMANDS "../src/${_source_file}") endforeach() add_executable(unit_tests unit_tests.cpp ${ALL_COMMANDS} ${ALL_UNIT_TESTS} ${PROJECT_BINARY_DIR}/src/version.cpp) target_link_libraries(unit_tests ${Boost_LIBRARIES} ${OSMIUM_LIBRARIES}) set_pthread_on_target(unit_tests) add_test(NAME unit_tests COMMAND unit_tests WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}") #----------------------------------------------------------------------------- configure_file(io/Makefile.in ${CMAKE_CURRENT_BINARY_DIR}/io/Makefile @ONLY) #----------------------------------------------------------------------------- function(do_test _name _command _regex) separate_arguments(_command) add_test(NAME ${_name} COMMAND ${_command}) set_tests_properties(${_name} PROPERTIES ENVIRONMENT "MANPATH=${PROJECT_BINARY_DIR}/man" PASS_REGULAR_EXPRESSION ${_regex} ) endfunction() #----------------------------------------------------------------------------- function(check_output _dir _name _command _reference) set(_cmd "$ ${_command}") if(ARGC GREATER 4) set(_return_code "${ARGV4}") else() set(_return_code 0) endif() add_test( NAME "${_dir}-${_name}" COMMAND ${CMAKE_COMMAND} -D cmd:FILEPATH=${_cmd} -D dir:PATH=${PROJECT_SOURCE_DIR}/test -D reference:FILEPATH=${PROJECT_SOURCE_DIR}/test/${_reference} -D output:FILEPATH=${PROJECT_BINARY_DIR}/test/${_dir}/cmd-output-${_name} -D return_code=${_return_code} -P ${CMAKE_SOURCE_DIR}/cmake/run_test_compare_output.cmake ) endfunction() function(check_output2 _dir _name _tmpdir _command1 _command2 _reference) set(_cmd1 "$ ${_command1}") set(_cmd2 "$ ${_command2}") add_test( NAME "${_dir}-${_name}" COMMAND ${CMAKE_COMMAND} -D cmd:FILEPATH=${_cmd1} -D cmd2:FILEPATH=${_cmd2} -D dir:PATH=${PROJECT_SOURCE_DIR}/test -D tmpdir:PATH=${_tmpdir} -D reference:FILEPATH=${PROJECT_SOURCE_DIR}/test/${_reference} -D output:FILEPATH=${PROJECT_BINARY_DIR}/test/${_dir}/cmd-output-${_name} -D return_code=0 -P ${CMAKE_SOURCE_DIR}/cmake/run_test_compare_output.cmake ) endfunction() #----------------------------------------------------------------------------- # # Configure tests for all commands # #----------------------------------------------------------------------------- foreach(_cmd IN LISTS OSMIUM_COMMANDS) do_test(help_cmd_${_cmd} "osmium ${_cmd} -h" "Usage: osmium ${_cmd}.*OPTIONS:") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_cmd}/CMakeLists.txt") message(STATUS "Adding tests in ${_cmd}") add_subdirectory(${_cmd}) else() message(STATUS "No tests for ${_cmd} command found") endif() endforeach() foreach(_extra_tests formats help misc) message(STATUS "Adding tests in ${_extra_tests}") add_subdirectory(${_extra_tests}) endforeach() #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/add-locations-to-ways/000077500000000000000000000000001474143067200211755ustar00rootroot00000000000000osmium-tool-1.17.0/test/add-locations-to-ways/CMakeLists.txt000066400000000000000000000015101474143067200237320ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - add-locations-to-ways # #----------------------------------------------------------------------------- function(check_add_locations_to_ways _name _options _input _output) check_output(add-locations-to-ways ${_name} "add-locations-to-ways ${_options} --generator=test --output-header=xml_josm_upload=false --output-format=xml add-locations-to-ways/${_input}" "add-locations-to-ways/${_output}") endfunction() check_add_locations_to_ways(taggednodes "" input.osm output.osm) check_add_locations_to_ways(allnodes "-n" input.osm output-n.osm) check_add_locations_to_ways(membernodes "--keep-member-nodes" input-rel.osm output-rel.osm) #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/add-locations-to-ways/input-rel.osm000066400000000000000000000016771474143067200236470ustar00rootroot00000000000000 osmium-tool-1.17.0/test/add-locations-to-ways/input.osm000066400000000000000000000020701474143067200230530ustar00rootroot00000000000000 osmium-tool-1.17.0/test/add-locations-to-ways/output-n.osm000066400000000000000000000022241474143067200235100ustar00rootroot00000000000000 osmium-tool-1.17.0/test/add-locations-to-ways/output-rel.osm000066400000000000000000000013711474143067200240370ustar00rootroot00000000000000 osmium-tool-1.17.0/test/add-locations-to-ways/output.osm000066400000000000000000000013201474143067200232510ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/000077500000000000000000000000001474143067200176065ustar00rootroot00000000000000osmium-tool-1.17.0/test/apply-changes/CMakeLists.txt000066400000000000000000000072511474143067200223530ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - apply-changes # #----------------------------------------------------------------------------- function(check_apply_changes _name _options _input _change _type _output) check_output(apply-changes ${_name} "apply-changes ${_options} --generator=test -f ${_type} apply-changes/${_input} apply-changes/${_change}" "apply-changes/${_output}") endfunction() check_apply_changes(data "" input-data.osm input-change.osc "osm" output-data.osm) add_test(NAME check-apply-changes-mixed1 COMMAND osmium apply-changes ${CMAKE_SOURCE_DIR}/test/apply-changes/input-data.osm ${CMAKE_SOURCE_DIR}/test/apply-changes/input-changes.osc -f osh) set_tests_properties(check-apply-changes-mixed1 PROPERTIES WILL_FAIL true) add_test(NAME check-apply-changes-mixed2 COMMAND osmium apply-changes ${CMAKE_SOURCE_DIR}/test/apply-changes/input-data.osh ${CMAKE_SOURCE_DIR}/test/apply-changes/input-changes.osc -f osm) set_tests_properties(check-apply-changes-mixed2 PROPERTIES WILL_FAIL true) check_apply_changes(history-osh-osh "" input-history.osh input-change.osc "osh" output-history.osh) check_apply_changes(history-osh-osh-wh "--with-history" input-history.osh input-change.osc "osh" output-history.osh) check_apply_changes(history-osm-osh-wh "--with-history" input-history.osm input-change.osc "osh" output-history.osh) check_apply_changes(history-osh-osm-wh "--with-history" input-history.osh input-change.osc "osm" output-history.osh) check_apply_changes(data-low "--locations-on-ways" input-data-low.osm input-change.osc "osm" output-data-low.osm) #----------------------------------------------------------------------------- # Test some patching features useful to redact existing OSM files #----------------------------------------------------------------------------- # Version 1 contains a copyright violation. The diff file contains a v2 object (with visible=false) and a modified v1 object. check_apply_changes(redact-and-update "--redact" input-redact-and-update.osh input-redact-and-update.osc "osh" output-redact-and-update.osh) # The input history file contains version 1 and 2, the diff wants to replace v1 by a deleted object (to redact the sensitive data in v1). # The output history file should contain the redacted version 1 and an unmodified copy of v2. check_apply_changes(patch-old-version "--redact" input-patch-old-version.osh input-patch-old-version.osc "osh" output-patch-old-version.osh) # The input history file contains version 1 and 2 of an object. The diff wants to remove the metadata of v1. Version 2 should stay untouched. check_apply_changes(redact-metadata "--redact" input-redact-metadata.osh input-redact-metadata.osc "osh" output-redact-metadata.osh) #----------------------------------------------------------------------------- # Test the application of diffs which have only some metadata fields on files which have only some metadata fields #----------------------------------------------------------------------------- # The input file has version and timestamp fields, the diff has only version fields. check_apply_changes(version-on-version-timestamp "" input-version+timestamp.osm input-version.osc "osm" output-version-applied-on-version+timestamp.osm) check_apply_changes(version-on-version-timestamp-low "--locations-on-ways" input-version+timestamp.osm input-version.osc "osm" output-version-applied-on-version+timestamp-low.osm) # The input file has all metadata fields, the diff has only version fields. check_apply_changes(version-on-all "" input-data.osm input-change-only-version.osc "osm" output-version-applied-on-all.osm) osmium-tool-1.17.0/test/apply-changes/input-change-only-version.osc000066400000000000000000000006771474143067200253520ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-change.osc000066400000000000000000000013131474143067200226740ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-data-low.osm000066400000000000000000000022521474143067200231740ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-data.osm000066400000000000000000000021321474143067200223720ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-history.osh000066400000000000000000000023131474143067200231560ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-history.osm000066400000000000000000000023131474143067200231630ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-patch-old-version.osc000066400000000000000000000003551474143067200250120ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-patch-old-version.osh000066400000000000000000000020541474143067200250150ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-redact-and-update.osc000066400000000000000000000005501474143067200247330ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-redact-and-update.osh000066400000000000000000000006341474143067200247430ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-redact-metadata.osc000066400000000000000000000004611474143067200244720ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-redact-metadata.osh000066400000000000000000000011031474143067200244710ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-version+timestamp.osm000066400000000000000000000017741474143067200251600ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/input-version.osc000066400000000000000000000011561474143067200231410ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/output-data-low.osm000066400000000000000000000022271474143067200233770ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/output-data.osm000066400000000000000000000021071474143067200225750ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/output-history.osh000066400000000000000000000035511474143067200233640ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/output-patch-old-version.osh000066400000000000000000000017011474143067200252140ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/output-redact-and-update.osh000066400000000000000000000006731474143067200251470ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/output-redact-metadata.osh000066400000000000000000000010271474143067200246770ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/output-version-applied-on-all.osm000066400000000000000000000015761474143067200261560ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/output-version-applied-on-version+timestamp-low.osm000066400000000000000000000016551474143067200316670ustar00rootroot00000000000000 osmium-tool-1.17.0/test/apply-changes/output-version-applied-on-version+timestamp.osm000066400000000000000000000016251474143067200310650ustar00rootroot00000000000000 osmium-tool-1.17.0/test/cat/000077500000000000000000000000001474143067200156225ustar00rootroot00000000000000osmium-tool-1.17.0/test/cat/CMakeLists.txt000066400000000000000000000021241474143067200203610ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - cat # #----------------------------------------------------------------------------- function(check_cat _name _in1 _in2 _output) check_output(cat ${_name} "cat --no-progress --generator=test -f osm cat/${_in1} cat/${_in2}" "cat/${_output}") endfunction() function(check_convert _name _input _output _format) check_output(cat ${_name} "cat --no-progress --generator=test cat/${_input} -f ${_format}" "cat/${_output}") endfunction() #----------------------------------------------------------------------------- check_cat(cat12 input1.osm input2.osm output-cat12.osm) check_cat(cat21 input2.osm input1.osm output-cat21.osm) check_convert(osm input1.osm output1.osm.opl opl) check_convert(gzip input1.osm.gz output1.osm.opl opl) check_convert(bzip2 input1.osm.bz2 output1.osm.opl opl) check_convert(pbf input1.osm.pbf output1.osm.opl opl) check_convert(opl output1.osm.opl output1.osm.opl opl) #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/cat/input1.osm000066400000000000000000000006661474143067200175720ustar00rootroot00000000000000 osmium-tool-1.17.0/test/cat/input1.osm.bz2000066400000000000000000000003531474143067200202570ustar00rootroot00000000000000BZh91AY&SYôÐ*û\_€PƒûW/çß@0ÙAšš@hhÐ 42d ŒA‰“CL ¨…<©é=¢e?SIú¦Fƒ&ŽaÈkŒ’]XëÜáT²Í˞ΔbæÈö­f±#Õ¥S—äŒKŽM@ŘIÃȤœ$,–ÛÈD€gÐ3'%³0k²­­CtÔ(w&?£M,kÙ4Á)çÅÊx –FÛ¦Çéà¸Âb¤K±ŒUOè$»(À¹®FRJV\êg½‘Hz )£¤éh–d#Ÿø»’)„‡¦WØosmium-tool-1.17.0/test/cat/input1.osm.gz000066400000000000000000000003151474143067200202000ustar00rootroot00000000000000‹›‹úVinput1.osmµ‘»Â0 E÷~Eä%SKÒ „PÒn|AYآƔJyTMŠø|"¨x Œ•®dËö½g°hîÖNaðNR^0JÐu^®—ôÔó=mêLø`ßWÀŠN*úIBĵРÈ<¯´„‹2¡ÎÎk$Cšqø$¤>6Ù”%”ŒosÆ“ZÆŒ%SÖbš. ÝU¹Æçƨ¥¾"7¿¼r^ùW­Ã«¾yb“QgÈJ¾¶osmium-tool-1.17.0/test/cat/input1.osm.pbf000066400000000000000000000002431474143067200203270ustar00rootroot00000000000000 OSMHeader7+3xœSâó/Î NÎHÍMÔ 3Ð3SârIÍ+NõËOI-nbäÉ/ÎÍ,ÍÕ7Ô³Ô3#P + OSMDataLMHxœãâàbàb)I-.r²çbfbbÒ’åbfddb_ðaÉ).)f&%¡"œxná„a/6ÉÀÄÌÀÀosmium-tool-1.17.0/test/cat/input2.osm000066400000000000000000000006661474143067200175730ustar00rootroot00000000000000 osmium-tool-1.17.0/test/cat/output-cat12.osm000066400000000000000000000013631474143067200206150ustar00rootroot00000000000000 osmium-tool-1.17.0/test/cat/output-cat21.osm000066400000000000000000000013631474143067200206150ustar00rootroot00000000000000 osmium-tool-1.17.0/test/cat/output1.osm.opl000066400000000000000000000002311474143067200205500ustar00rootroot00000000000000n1 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T x1 y1 n2 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T x1 y2 n3 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T x1 y3 osmium-tool-1.17.0/test/cat/test_setup.cpp000066400000000000000000000054011474143067200205250ustar00rootroot00000000000000 #include "test.hpp" // IWYU pragma: keep #include "command_cat.hpp" #include TEST_CASE("cat") { const CommandFactory factory; CommandCat cmd{factory}; SECTION("no parameters") { REQUIRE_THROWS_AS(cmd.setup({}), argument_error); } SECTION("stdin osm to stdout pbf") { cmd.setup({"-F", "osm", "-f", "pbf"}); auto ifs = cmd.input_files(); REQUIRE(ifs.size() == 1); REQUIRE(ifs.front().format() == osmium::io::file_format::xml); REQUIRE(ifs.front().compression() == osmium::io::file_compression::none); REQUIRE(ifs.front().filename().empty()); auto of = cmd.output_file(); REQUIRE(of.format() == osmium::io::file_format::pbf); REQUIRE(of.filename().empty()); REQUIRE(cmd.output_overwrite() == osmium::io::overwrite::no); REQUIRE(cmd.osm_entity_bits() == osmium::osm_entity_bits::all); } SECTION("unknown object-type 1") { REQUIRE_THROWS_AS(cmd.setup({"in.osm", "-o", "out.osm", "-t", "foo"}), argument_error); } SECTION("unknown object-type 2") { REQUIRE_THROWS_AS(cmd.setup({"in.osm", "-o", "out.osm", "--object-type", "foo"}), argument_error); } SECTION("reading to files") { cmd.setup({"-o", "output", "-O", "-f", "opl", "-t", "way", "a.osm.bz2", "b.pbf"}); auto ifs = cmd.input_files(); REQUIRE(ifs.size() == 2); REQUIRE(ifs[0].format() == osmium::io::file_format::xml); REQUIRE(ifs[0].compression() == osmium::io::file_compression::bzip2); REQUIRE(ifs[0].filename() == "a.osm.bz2"); REQUIRE(ifs[1].format() == osmium::io::file_format::pbf); REQUIRE(ifs[1].compression() == osmium::io::file_compression::none); REQUIRE(ifs[1].filename() == "b.pbf"); auto of = cmd.output_file(); REQUIRE(of.format() == osmium::io::file_format::opl); REQUIRE(of.filename() == "output"); REQUIRE(cmd.output_overwrite() == osmium::io::overwrite::allow); REQUIRE(cmd.osm_entity_bits() == osmium::osm_entity_bits::way); } SECTION("unknown input format suffix") { REQUIRE_THROWS_AS(cmd.setup({"in.foo"}), argument_error); } SECTION("unknown input format option") { REQUIRE_THROWS_AS(cmd.setup({"in.osm", "-F", "foo"}), argument_error); } SECTION("unknown output format suffix") { REQUIRE_THROWS_AS(cmd.setup({"in.osm", "-o", "foo.bar"}), std::runtime_error); } SECTION("unknown output suffix and unknown format option") { REQUIRE_THROWS_AS(cmd.setup({"in.osm", "-o", "foo.foo", "-f", "bar"}), std::runtime_error); } SECTION("unknown output format option") { REQUIRE_THROWS_AS(cmd.setup({"in.osm", "-o", "foo.pbf", "-f", "bar"}), std::runtime_error); } } osmium-tool-1.17.0/test/changeset-filter/000077500000000000000000000000001474143067200202775ustar00rootroot00000000000000osmium-tool-1.17.0/test/changeset-filter/CMakeLists.txt000066400000000000000000000123131474143067200230370ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - changeset-filter # #----------------------------------------------------------------------------- function(check_changeset_filter _name _options _input _output) check_output(changeset-filter ${_name} "changeset-filter --generator=test -f osm ${_options} changeset-filter/${_input}" "changeset-filter/${_output}") endfunction() #----------------------------------------------------------------------------- check_changeset_filter(cf1-no-option "" input1.osm output1-all.osm) check_changeset_filter(cf1-with-discussion "--with-discussion" input1.osm output-empty.osm) check_changeset_filter(cf1-without-discussion "--without-discussion" input1.osm output1-all.osm) check_changeset_filter(cf1-with-changes "--with-changes" input1.osm output1-first.osm) check_changeset_filter(cf1-without-changes "--without-changes" input1.osm output1-second.osm) check_changeset_filter(cf1-open "--open" input1.osm output-empty.osm) check_changeset_filter(cf1-closed "--closed" input1.osm output1-all.osm) check_changeset_filter(cf1-user "--user=Elbert" input1.osm output1-first.osm) check_changeset_filter(cf1-uid "--uid=1233268" input1.osm output1-second.osm) check_changeset_filter(cfe-open "--open" input-open.osm output-open.osm) check_changeset_filter(cfe-closed "--closed" input-open.osm output-empty.osm) check_changeset_filter(cf1-after01 "--after=2013-03-22T02:08:50Z" input1.osm output1-all.osm) check_changeset_filter(cf1-after02 "--after=2013-03-22T02:08:54Z" input1.osm output1-all.osm) check_changeset_filter(cf1-after03 "--after=2013-03-22T02:08:55Z" input1.osm output1-all.osm) check_changeset_filter(cf1-after04 "--after=2013-03-22T02:08:56Z" input1.osm output1-all.osm) check_changeset_filter(cf1-after05 "--after=2013-03-22T02:08:57Z" input1.osm output1-all.osm) check_changeset_filter(cf1-after06 "--after=2013-03-22T02:08:58Z" input1.osm output1-all.osm) check_changeset_filter(cf1-after07 "--after=2013-03-22T02:08:59Z" input1.osm output1-second.osm) check_changeset_filter(cf1-after08 "--after=2013-03-22T02:09:00Z" input1.osm output1-second.osm) check_changeset_filter(cf1-after09 "--after=2013-03-22T02:09:10Z" input1.osm output1-second.osm) check_changeset_filter(cf1-after10 "--after=2013-03-22T02:09:11Z" input1.osm output1-second.osm) check_changeset_filter(cf1-after11 "--after=2013-03-22T02:09:12Z" input1.osm output1-second.osm) check_changeset_filter(cf1-after12 "--after=2013-03-22T03:09:10Z" input1.osm output1-second.osm) check_changeset_filter(cf1-after13 "--after=2013-03-22T03:09:11Z" input1.osm output1-second.osm) check_changeset_filter(cf1-after14 "--after=2013-03-22T03:09:12Z" input1.osm output-empty.osm) check_changeset_filter(cf1-after15 "--after=2013-03-22T03:09:20Z" input1.osm output-empty.osm) check_changeset_filter(cfe-after01 "--after=2013-03-22T04:20:24Z" input-open.osm output-open.osm) check_changeset_filter(cfe-after02 "--after=2013-03-22T04:20:25Z" input-open.osm output-open.osm) check_changeset_filter(cfe-after03 "--after=2013-03-22T04:20:26Z" input-open.osm output-open.osm) check_changeset_filter(cf1-before01 "--before=2013-03-22T02:08:50Z" input1.osm output-empty.osm) check_changeset_filter(cf1-before02 "--before=2013-03-22T02:08:54Z" input1.osm output-empty.osm) check_changeset_filter(cf1-before03 "--before=2013-03-22T02:08:55Z" input1.osm output1-first.osm) check_changeset_filter(cf1-before04 "--before=2013-03-22T02:08:56Z" input1.osm output1-first.osm) check_changeset_filter(cf1-before05 "--before=2013-03-22T02:08:57Z" input1.osm output1-first.osm) check_changeset_filter(cf1-before06 "--before=2013-03-22T02:08:58Z" input1.osm output1-first.osm) check_changeset_filter(cf1-before07 "--before=2013-03-22T02:08:59Z" input1.osm output1-first.osm) check_changeset_filter(cf1-before08 "--before=2013-03-22T02:09:00Z" input1.osm output1-first.osm) check_changeset_filter(cf1-before09 "--before=2013-03-22T02:09:10Z" input1.osm output1-first.osm) check_changeset_filter(cf1-before10 "--before=2013-03-22T02:09:11Z" input1.osm output1-all.osm) check_changeset_filter(cf1-before11 "--before=2013-03-22T02:09:12Z" input1.osm output1-all.osm) check_changeset_filter(cf1-before12 "--before=2013-03-22T03:09:10Z" input1.osm output1-all.osm) check_changeset_filter(cf1-before13 "--before=2013-03-22T03:09:11Z" input1.osm output1-all.osm) check_changeset_filter(cf1-before14 "--before=2013-03-22T03:09:12Z" input1.osm output1-all.osm) check_changeset_filter(cf1-before15 "--before=2013-03-22T03:09:20Z" input1.osm output1-all.osm) check_changeset_filter(cfe-before01 "--before=2013-03-22T04:20:24Z" input-open.osm output-empty.osm) check_changeset_filter(cfe-before02 "--before=2013-03-22T04:20:25Z" input-open.osm output-open.osm) check_changeset_filter(cfe-before03 "--before=2013-03-22T04:20:26Z" input-open.osm output-open.osm) check_changeset_filter(cf1-bbox01 "--bbox 120,-11,121,-10" input1.osm output1-first.osm) check_changeset_filter(cf1-bbox02 "--bbox 130,-31,131,-30" input1.osm output-empty.osm) #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/changeset-filter/input-open.osm000066400000000000000000000005271474143067200231210ustar00rootroot00000000000000 osmium-tool-1.17.0/test/changeset-filter/input1.osm000066400000000000000000000012131474143067200222340ustar00rootroot00000000000000 osmium-tool-1.17.0/test/changeset-filter/output-empty.osm000066400000000000000000000001231474143067200235070ustar00rootroot00000000000000 osmium-tool-1.17.0/test/changeset-filter/output-open.osm000066400000000000000000000005421474143067200233170ustar00rootroot00000000000000 osmium-tool-1.17.0/test/changeset-filter/output1-all.osm000066400000000000000000000012471474143067200232120ustar00rootroot00000000000000 osmium-tool-1.17.0/test/changeset-filter/output1-first.osm000066400000000000000000000006211474143067200235640ustar00rootroot00000000000000 osmium-tool-1.17.0/test/changeset-filter/output1-second.osm000066400000000000000000000005511474143067200237120ustar00rootroot00000000000000 osmium-tool-1.17.0/test/check-refs/000077500000000000000000000000001474143067200170655ustar00rootroot00000000000000osmium-tool-1.17.0/test/check-refs/CMakeLists.txt000066400000000000000000000055501474143067200216320ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - check-refs # #----------------------------------------------------------------------------- add_test(NAME check-ref-w-okay COMMAND osmium check-refs ${CMAKE_SOURCE_DIR}/test/check-refs/okay.osm) add_test(NAME check-ref-r-okay COMMAND osmium check-refs -r ${CMAKE_SOURCE_DIR}/test/check-refs/okay.osm) add_test(NAME check-ref-fail-n-in-w COMMAND osmium check-refs ${CMAKE_SOURCE_DIR}/test/check-refs/fail-n-in-w.osm) set_tests_properties(check-ref-fail-n-in-w PROPERTIES WILL_FAIL true) add_test(NAME check-ref-w-way-okay COMMAND osmium check-refs ${CMAKE_SOURCE_DIR}/test/check-refs/way-okay.osm) add_test(NAME check-ref-r-way-okay COMMAND osmium check-refs -r ${CMAKE_SOURCE_DIR}/test/check-refs/way-okay.osm) set_tests_properties(check-ref-r-way-okay PROPERTIES WILL_FAIL true) add_test(NAME check-ref-okay-r-in-r COMMAND osmium check-refs -r ${CMAKE_SOURCE_DIR}/test/check-refs/okay-r-in-r.osm) add_test(NAME check-ref-fail-n-in-r COMMAND osmium check-refs -r ${CMAKE_SOURCE_DIR}/test/check-refs/fail-n-in-r.osm) set_tests_properties(check-ref-fail-n-in-r PROPERTIES WILL_FAIL true) add_test(NAME check-ref-fail-w-in-r COMMAND osmium check-refs -r ${CMAKE_SOURCE_DIR}/test/check-refs/fail-w-in-r.osm) set_tests_properties(check-ref-fail-w-in-r PROPERTIES WILL_FAIL true) add_test(NAME check-ref-fail-r-in-r-1 COMMAND osmium check-refs -r ${CMAKE_SOURCE_DIR}/test/check-refs/fail-r-in-r-1.osm) set_tests_properties(check-ref-fail-r-in-r-1 PROPERTIES WILL_FAIL true) add_test(NAME check-ref-fail-r-in-r-2 COMMAND osmium check-refs -r ${CMAKE_SOURCE_DIR}/test/check-refs/fail-r-in-r-2.osm) set_tests_properties(check-ref-fail-r-in-r-2 PROPERTIES WILL_FAIL true) #----------------------------------------------------------------------------- # input data not ordered properly add_test(NAME check-ref-fail-order-n COMMAND osmium check-refs ${CMAKE_SOURCE_DIR}/test/order/fail-order-n.osm) set_tests_properties(check-ref-fail-order-n PROPERTIES WILL_FAIL true) add_test(NAME check-ref-fail-order-w COMMAND osmium check-refs ${CMAKE_SOURCE_DIR}/test/order/fail-order-w.osm) set_tests_properties(check-ref-fail-order-w PROPERTIES WILL_FAIL true) add_test(NAME check-ref-fail-order-r COMMAND osmium check-refs -r ${CMAKE_SOURCE_DIR}/test/order/fail-order-r.osm) set_tests_properties(check-ref-fail-order-r PROPERTIES WILL_FAIL true) add_test(NAME check-ref-fail-order-wn COMMAND osmium check-refs ${CMAKE_SOURCE_DIR}/test/order/fail-order-wn.osm) set_tests_properties(check-ref-fail-order-wn PROPERTIES WILL_FAIL true) add_test(NAME check-ref-fail-order-rw COMMAND osmium check-refs ${CMAKE_SOURCE_DIR}/test/order/fail-order-rw.osm) set_tests_properties(check-ref-fail-order-rw PROPERTIES WILL_FAIL true) #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/check-refs/fail-n-in-r.osm000066400000000000000000000004031474143067200216130ustar00rootroot00000000000000 osmium-tool-1.17.0/test/check-refs/fail-n-in-w.osm000066400000000000000000000007261474143067200216300ustar00rootroot00000000000000 osmium-tool-1.17.0/test/check-refs/fail-r-in-r-1.osm000066400000000000000000000004071474143067200217610ustar00rootroot00000000000000 osmium-tool-1.17.0/test/check-refs/fail-r-in-r-2.osm000066400000000000000000000004071474143067200217620ustar00rootroot00000000000000 osmium-tool-1.17.0/test/check-refs/fail-w-in-r.osm000066400000000000000000000004021474143067200216230ustar00rootroot00000000000000 osmium-tool-1.17.0/test/check-refs/okay-r-in-r.osm000066400000000000000000000006501474143067200216530ustar00rootroot00000000000000 osmium-tool-1.17.0/test/check-refs/okay.osm000066400000000000000000000017061474143067200205540ustar00rootroot00000000000000 osmium-tool-1.17.0/test/check-refs/way-okay.osm000066400000000000000000000014411474143067200213460ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/000077500000000000000000000000001474143067200177375ustar00rootroot00000000000000osmium-tool-1.17.0/test/derive-changes/CMakeLists.txt000066400000000000000000000033471474143067200225060ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - derive-changes # #----------------------------------------------------------------------------- function(check_derive_changes _name _options _input1 _input2 _output) check_output(derive-changes ${_name} "derive-changes --generator=test -f osc ${_options} derive-changes/${_input1} derive-changes/${_input2}" "derive-changes/${_output}") endfunction() check_derive_changes(normal "" input1.osm input2.osm output.osc) check_derive_changes(keep_details "--keep-details" input1.osm input2.osm output-keep-details.osc) check_derive_changes(incr_version "--increment-version" input1.osm input2.osm output-incr-version.osc) # Tests with input file which don't have the same amount of metadata fields: # File 1 has all metadata fields, file 2 has only version fields. check_derive_changes(new_file_only_versions "" input1.osm input2-only-versions.osm output-2-only-version.osc) # File 1 has only version and timestamp fields, file 2 has only version fields. check_derive_changes(version_timestamp_with_version "" input1-only-version-timestamp.osm input2-only-versions.osm output-2-only-version-timestamp.osc) # File 1 has only version fields, file 2 has version and timestamp fields. check_derive_changes(version_with_version_timestamp "" input1-only-version.osm input2-only-version-timestamp.osm output-2-version-with-version-timestamp.osc) # File 1 has only version fields, file 2 has all metadata fields. check_derive_changes(version_with_all "" input1-only-version.osm input2-all-with-relation.osm output-2-version-with-all.osc) #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/derive-changes/input1-only-version-timestamp.osm000066400000000000000000000016201474143067200263410ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/input1-only-version.osm000066400000000000000000000013431474143067200243420ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/input1.osm000066400000000000000000000021761474143067200217050ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/input2-all-with-relation.osm000066400000000000000000000021471474143067200252360ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/input2-only-version-timestamp.osm000066400000000000000000000016401474143067200263440ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/input2-only-versions.osm000066400000000000000000000011621474143067200245250ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/input2.osm000066400000000000000000000021071474143067200217000ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/output-2-only-version-timestamp.osc000066400000000000000000000007141474143067200266110ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/output-2-only-version.osc000066400000000000000000000007141474143067200246100ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/output-2-version-with-all.osc000066400000000000000000000013511474143067200253460ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/output-2-version-with-version-timestamp.osc000066400000000000000000000012051474143067200302620ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/output-incr-version.osc000066400000000000000000000012251474143067200244210ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/output-keep-details.osc000066400000000000000000000013571474143067200243600ustar00rootroot00000000000000 osmium-tool-1.17.0/test/derive-changes/output.osc000066400000000000000000000012251474143067200220050ustar00rootroot00000000000000 osmium-tool-1.17.0/test/diff/000077500000000000000000000000001474143067200157635ustar00rootroot00000000000000osmium-tool-1.17.0/test/diff/CMakeLists.txt000066400000000000000000000022511474143067200205230ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - diff # #----------------------------------------------------------------------------- function(check_diff _name _options _input1 _input2 _output _return_code) check_output(diff ${_name} "diff ${_options} diff/${_input1} diff/${_input2}" "diff/${_output}" "${_return_code}") endfunction() check_diff(compact "" input1.osm input2.osm output-compact 1) check_diff(compact-c "-c" input1.osm input2.osm output-compact-c 1) check_diff(opl "-f opl" input1.osm input2.osm output.opl 1) check_diff(opl-c "-f opl -c" input1.osm input2.osm output-c.opl 1) check_diff(same "" input1.osm input1.osm output-same 0) check_diff(ignore-uid "--ignore-uid -c" input1.osm input2.osm output-compact-c-nouid 1) check_diff(ignore-uid-15 "--ignore-uid -c" input1uid.osm input2uid.osm output-empty 0) check_diff(ignore-uid-opl "--ignore-uid -f opl -c" input1.osm input2.osm output-compact-c-nouid-opl 1) check_diff(ignore-uid-15-opl "--ignore-uid -f opl -c" input1uid.osm input2uid.osm output-empty 0) #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/diff/input1.osm000066400000000000000000000024741474143067200177320ustar00rootroot00000000000000 osmium-tool-1.17.0/test/diff/input1uid.osm000066400000000000000000000003271474143067200204270ustar00rootroot00000000000000 osmium-tool-1.17.0/test/diff/input2.osm000066400000000000000000000024741474143067200177330ustar00rootroot00000000000000 osmium-tool-1.17.0/test/diff/input2uid.osm000066400000000000000000000003271474143067200204300ustar00rootroot00000000000000 osmium-tool-1.17.0/test/diff/output-c.opl000066400000000000000000000010461474143067200202600ustar00rootroot00000000000000-n11 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T x1 y2 +n11 v2 dV c2 t2015-01-01T02:00:00Z i1 utest T x2 y2 -n13 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T x1 y4 +n14 v1 dV c2 t2015-01-01T02:00:00Z i1 utest T x1 y5 -n15 v1 dV c1 t2015-01-01T02:00:00Z i2 utest T x1 y5 +n15 v1 dV c1 t2015-01-01T02:00:00Z i1 utest T x1 y5 -n16 v1 dV c1 t2015-01-01T02:00:00Z i1 utest T x2 y5 +n16 v1 dV c1 t2015-01-01T02:00:00Z i1 utest T x1 y5 -w21 v1 dV c1 t2015-01-01T01:00:00Z i1 utest Txyz=abc Nn12,n13 +w21 v2 dV c2 t2015-01-01T02:00:00Z i1 utest Txyz=new Nn12,n14 osmium-tool-1.17.0/test/diff/output-compact000066400000000000000000000001401474143067200206650ustar00rootroot00000000000000 n10 v1 -n11 v1 +n11 v2 n12 v1 -n13 v1 +n14 v1 *n15 v1 *n16 v1 w20 v1 -w21 v1 +w21 v2 r30 v1 osmium-tool-1.17.0/test/diff/output-compact-c000066400000000000000000000001001474143067200211010ustar00rootroot00000000000000-n11 v1 +n11 v2 -n13 v1 +n14 v1 *n15 v1 *n16 v1 -w21 v1 +w21 v2 osmium-tool-1.17.0/test/diff/output-compact-c-nouid000066400000000000000000000000701474143067200222230ustar00rootroot00000000000000-n11 v1 +n11 v2 -n13 v1 +n14 v1 *n16 v1 -w21 v1 +w21 v2 osmium-tool-1.17.0/test/diff/output-compact-c-nouid-opl000066400000000000000000000006441474143067200230220ustar00rootroot00000000000000-n11 v1 dV c1 t2015-01-01T01:00:00Z utest T x1 y2 +n11 v2 dV c2 t2015-01-01T02:00:00Z utest T x2 y2 -n13 v1 dV c1 t2015-01-01T01:00:00Z utest T x1 y4 +n14 v1 dV c2 t2015-01-01T02:00:00Z utest T x1 y5 -n16 v1 dV c1 t2015-01-01T02:00:00Z utest T x2 y5 +n16 v1 dV c1 t2015-01-01T02:00:00Z utest T x1 y5 -w21 v1 dV c1 t2015-01-01T01:00:00Z utest Txyz=abc Nn12,n13 +w21 v2 dV c2 t2015-01-01T02:00:00Z utest Txyz=new Nn12,n14 osmium-tool-1.17.0/test/diff/output-empty000066400000000000000000000000001474143067200203700ustar00rootroot00000000000000osmium-tool-1.17.0/test/diff/output-same000066400000000000000000000001101474143067200201610ustar00rootroot00000000000000 n10 v1 n11 v1 n12 v1 n13 v1 n15 v1 n16 v1 w20 v1 w21 v1 r30 v1 osmium-tool-1.17.0/test/diff/output.opl000066400000000000000000000014211474143067200200350ustar00rootroot00000000000000 n10 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T x1 y1 -n11 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T x1 y2 +n11 v2 dV c2 t2015-01-01T02:00:00Z i1 utest T x2 y2 n12 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T x1 y3 -n13 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T x1 y4 +n14 v1 dV c2 t2015-01-01T02:00:00Z i1 utest T x1 y5 -n15 v1 dV c1 t2015-01-01T02:00:00Z i2 utest T x1 y5 +n15 v1 dV c1 t2015-01-01T02:00:00Z i1 utest T x1 y5 -n16 v1 dV c1 t2015-01-01T02:00:00Z i1 utest T x2 y5 +n16 v1 dV c1 t2015-01-01T02:00:00Z i1 utest T x1 y5 w20 v1 dV c1 t2015-01-01T01:00:00Z i1 utest Tfoo=bar Nn10,n11,n12 -w21 v1 dV c1 t2015-01-01T01:00:00Z i1 utest Txyz=abc Nn12,n13 +w21 v2 dV c2 t2015-01-01T02:00:00Z i1 utest Txyz=new Nn12,n14 r30 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T Mn12@m1,w20@m2 osmium-tool-1.17.0/test/diff/test_setup.cpp000066400000000000000000000020271474143067200206670ustar00rootroot00000000000000 #include "test.hpp" #include "command_diff.hpp" TEST_CASE("diff") { const CommandFactory factory; CommandDiff cmd{factory}; SECTION("no arguments - need exactly two arguments") { REQUIRE_THROWS_AS(cmd.setup({}), argument_error); } SECTION("one argument - need exactly two arguments") { REQUIRE_THROWS_AS(cmd.setup({"x"}), argument_error); } SECTION("three arguments - need exactly two arguments") { REQUIRE_THROWS_AS(cmd.setup({"x", "y", "z"}), argument_error); } SECTION("quiet with output parameter -o") { REQUIRE_THROWS_AS(cmd.setup({"-q", "-o", "file"}), argument_error); } SECTION("quiet with output parameter -f") { REQUIRE_THROWS_AS(cmd.setup({"-q", "-f", "opl"}), argument_error); } SECTION("parameter --fsync") { REQUIRE_THROWS_AS(cmd.setup({"--fsync"}), boost::program_options::unknown_option); } SECTION("quiet with output parameter -O") { REQUIRE_THROWS_AS(cmd.setup({"-q", "-O"}), argument_error); } } osmium-tool-1.17.0/test/export/000077500000000000000000000000001474143067200163745ustar00rootroot00000000000000osmium-tool-1.17.0/test/export/CMakeLists.txt000066400000000000000000000077321474143067200211450ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - export # #----------------------------------------------------------------------------- function(check_export _name _options _input _output) check_output(export ${_name} "export ${_options} export/${_input}" "export/${_output}") endfunction() check_export(geojson "-f geojson" input.osm output.geojson) check_export(geojsonseq "-f geojsonseq -x print_record_separator=false" input.osm output.geojsonseq) check_export(pg "-f pg" input.osm output.pg) check_export(missing-node "-f geojson" input-missing-node.osm output-missing-node.geojson) check_export(single-node-way "-f geojson" input-single-node-way.osm output-empty.geojson) add_test(NAME export-error-node COMMAND osmium export -f geojson -E ${CMAKE_SOURCE_DIR}/test/export/input-missing-node.osm) set_tests_properties(export-error-node PROPERTIES WILL_FAIL true) add_test(NAME export-error-single-node-way COMMAND osmium export -f geojson -E ${CMAKE_SOURCE_DIR}/test/export/input-single-node-way.osm) set_tests_properties(export-error-single-node-way PROPERTIES WILL_FAIL true) check_export(invalid-area "-f geojson" input-incomplete-relation.osm output-incomplete-relation.geojson) add_test(NAME export-error-area COMMAND osmium export -f geojson -E ${CMAKE_SOURCE_DIR}/test/export/input-incomplete-relation.osm) set_tests_properties(export-error-area PROPERTIES WILL_FAIL true) add_test(NAME export-error-incomplete-rel COMMAND osmium export -f geojson -E ${CMAKE_SOURCE_DIR}/test/export/input-incomplete-rel-missing-way.osm) set_tests_properties(export-error-incomplete-rel PROPERTIES WILL_FAIL true) #----------------------------------------------------------------------------- check_export(attributes "-E -f text -a id" way.osm way-all.txt) check_export(c-empty-empty-n "-E -f text --keep-untagged -c export/config-empty-empty.json" way.osm way-all-n.txt) set_tests_properties(export-c-empty-empty-n PROPERTIES ENVIRONMENT osmium_cmake_stderr=ignore) check_export(c-empty-empty "-E -f text -c export/config-empty-empty.json" way.osm way-all.txt) set_tests_properties(export-c-empty-empty PROPERTIES ENVIRONMENT osmium_cmake_stderr=ignore) check_export(c-null-null "-E -f text -c export/config-null-null.json" way.osm way-all.txt) check_export(c-undefined "-E -f text -c export/config-undefined.json" way.osm way-all.txt) check_export(c-tag-empty "-E -f text -c export/config-tag-empty.json" way.osm way-tag-empty.txt) set_tests_properties(export-c-tag-empty PROPERTIES ENVIRONMENT osmium_cmake_stderr=ignore) check_export(c-empty-tag "-E -f text -c export/config-empty-tag.json" way.osm way-empty-tag.txt) set_tests_properties(export-c-empty-tag PROPERTIES ENVIRONMENT osmium_cmake_stderr=ignore) check_export(c-tag-tag "-E -f text -c export/config-tag-tag.json" way.osm way-tag-tag.txt) check_export(c-tagx-empty "-E -f text -c export/config-tagx-empty.json" way.osm way-tagx-empty.txt) set_tests_properties(export-c-tagx-empty PROPERTIES ENVIRONMENT osmium_cmake_stderr=ignore) check_export(c-empty-tagx "-E -f text -c export/config-empty-tagx.json" way.osm way-empty-tagx.txt) set_tests_properties(export-c-empty-tagx PROPERTIES ENVIRONMENT osmium_cmake_stderr=ignore) check_export(c-tagx-tagx "-E -f text -c export/config-tagx-tagx.json" way.osm way-tagx-tagx.txt) check_export(c-true-true "-E -f text -c export/config-true-true.json" way.osm way-all.txt) check_export(c-false-false "-E -f text -c export/config-false-false.json" way.osm way-none.txt) check_export(c-null-tag "-E -f text -c export/config-null-tag.json" way.osm way-null-tag.txt) check_export(c-tag-null "-E -f text -c export/config-tag-null.json" way.osm way-tag-null.txt) #----------------------------------------------------------------------------- check_export(pg-untagged "-f pg --keep-untagged" input.osm output-untagged.pg) #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/export/config-empty-empty.json000066400000000000000000000005341474143067200230260ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": [], "area_tags": [], "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-empty-tag.json000066400000000000000000000005451474143067200224450ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": [], "area_tags": ["landuse"], "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-empty-tagx.json000066400000000000000000000005541474143067200226350ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": [], "area_tags": ["does-not-exist"], "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-false-false.json000066400000000000000000000005421474143067200227150ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": false, "area_tags": false, "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-null-null.json000066400000000000000000000005401474143067200224530ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": null, "area_tags": null, "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-null-tag.json000066400000000000000000000005471474143067200222630ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": null, "area_tags": ["landuse"], "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-tag-empty.json000066400000000000000000000005451474143067200224450ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": ["barrier"], "area_tags": [], "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-tag-null.json000066400000000000000000000005151474143067200222560ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": ["barrier"], "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-tag-tag.json000066400000000000000000000005561474143067200220640ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": ["barrier"], "area_tags": ["landuse"], "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-tagx-empty.json000066400000000000000000000005541474143067200226350ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": ["does-not-exist"], "area_tags": [], "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-tagx-tagx.json000066400000000000000000000005741474143067200224440ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": ["does-not-exist"], "area_tags": ["does-not-exist"], "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-true-true.json000066400000000000000000000005401474143067200224650ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "linear_tags": true, "area_tags": true, "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/config-undefined.json000066400000000000000000000004541474143067200224760ustar00rootroot00000000000000{ "attributes": { "type": false, "id": true, "version": false, "changeset": false, "timestamp": false, "uid": false, "user": false, "way_nodes": false }, "exclude_tags": [], "include_tags": [] } osmium-tool-1.17.0/test/export/empty-tag.txt000066400000000000000000000013551474143067200210500ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=31,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=32,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=33,barrier=fence,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=34,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=35,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=31,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=32,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=33,barrier=fence,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=35,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=36,area=yes osmium-tool-1.17.0/test/export/input-incomplete-rel-missing-way.osm000066400000000000000000000015611474143067200254400ustar00rootroot00000000000000 osmium-tool-1.17.0/test/export/input-incomplete-relation.osm000066400000000000000000000027041474143067200242260ustar00rootroot00000000000000 osmium-tool-1.17.0/test/export/input-missing-node.osm000066400000000000000000000026021474143067200226450ustar00rootroot00000000000000 osmium-tool-1.17.0/test/export/input-single-node-way.osm000066400000000000000000000005631474143067200232570ustar00rootroot00000000000000 osmium-tool-1.17.0/test/export/input.osm000066400000000000000000000027631474143067200202630ustar00rootroot00000000000000 osmium-tool-1.17.0/test/export/output-empty.geojson000066400000000000000000000000551474143067200224560ustar00rootroot00000000000000{"type":"FeatureCollection","features":[ ]} osmium-tool-1.17.0/test/export/output-incomplete-relation.geojson000066400000000000000000000006371474143067200253000ustar00rootroot00000000000000{"type":"FeatureCollection","features":[ {"type":"Feature","geometry":{"type":"Point","coordinates":[2.0,1.5]},"properties":{"amenity":"post_box"}}, {"type":"Feature","geometry":{"type":"LineString","coordinates":[[1.0,1.0],[1.0,2.0],[1.0,3.0]]},"properties":{"highway":"track"}}, {"type":"Feature","geometry":{"type":"LineString","coordinates":[[1.0,1.0],[1.0,2.0],[2.0,1.5]]},"properties":{"barrier":"fence"}} ]} osmium-tool-1.17.0/test/export/output-missing-node.geojson000066400000000000000000000006601474143067200237160ustar00rootroot00000000000000{"type":"FeatureCollection","features":[ {"type":"Feature","geometry":{"type":"Point","coordinates":[2.0,1.5]},"properties":{"amenity":"post_box"}}, {"type":"Feature","geometry":{"type":"LineString","coordinates":[[1.0,1.0],[1.0,2.0],[2.0,1.5]]},"properties":{"barrier":"fence"}}, {"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[1.0,1.0],[2.0,1.5],[1.0,2.0],[1.0,1.0]]]]},"properties":{"landuse":"forest"}} ]} osmium-tool-1.17.0/test/export/output-untagged.pg000066400000000000000000000015601474143067200220620ustar00rootroot000000000000000101000020E6100000000000000000F03F000000000000F03F {} 0101000020E6100000000000000000F03F0000000000000040 {} 0101000020E6100000000000000000F03F0000000000000840 {} 0101000020E6100000000000000000F03F0000000000001040 {} 0101000020E61000000000000000000040000000000000F83F {"amenity":"post_box"} 0102000020E610000003000000000000000000F03F000000000000F03F000000000000F03F0000000000000040000000000000F03F0000000000000840 {"highway":"track"} 0102000020E610000003000000000000000000F03F000000000000F03F000000000000F03F00000000000000400000000000000040000000000000F83F {"barrier":"fence"} 0102000020E6100000020000000000000000000040000000000000F83F000000000000F03F000000000000F03F {} 0106000020E6100000010000000103000020E61000000100000004000000000000000000F03F000000000000F03F0000000000000040000000000000F83F000000000000F03F0000000000000040000000000000F03F000000000000F03F {"landuse":"forest"} osmium-tool-1.17.0/test/export/output.geojson000066400000000000000000000010641474143067200213230ustar00rootroot00000000000000{"type":"FeatureCollection","features":[ {"type":"Feature","geometry":{"type":"Point","coordinates":[2.0,1.5]},"properties":{"amenity":"post_box"}}, {"type":"Feature","geometry":{"type":"LineString","coordinates":[[1.0,1.0],[1.0,2.0],[1.0,3.0]]},"properties":{"highway":"track"}}, {"type":"Feature","geometry":{"type":"LineString","coordinates":[[1.0,1.0],[1.0,2.0],[2.0,1.5]]},"properties":{"barrier":"fence"}}, {"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[1.0,1.0],[2.0,1.5],[1.0,2.0],[1.0,1.0]]]]},"properties":{"landuse":"forest"}} ]} osmium-tool-1.17.0/test/export/output.geojsonseq000066400000000000000000000010051474143067200220270ustar00rootroot00000000000000{"type":"Feature","geometry":{"type":"Point","coordinates":[2.0,1.5]},"properties":{"amenity":"post_box"}} {"type":"Feature","geometry":{"type":"LineString","coordinates":[[1.0,1.0],[1.0,2.0],[1.0,3.0]]},"properties":{"highway":"track"}} {"type":"Feature","geometry":{"type":"LineString","coordinates":[[1.0,1.0],[1.0,2.0],[2.0,1.5]]},"properties":{"barrier":"fence"}} {"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[1.0,1.0],[2.0,1.5],[1.0,2.0],[1.0,1.0]]]]},"properties":{"landuse":"forest"}} osmium-tool-1.17.0/test/export/output.pg000066400000000000000000000010721474143067200202640ustar00rootroot000000000000000101000020E61000000000000000000040000000000000F83F {"amenity":"post_box"} 0102000020E610000003000000000000000000F03F000000000000F03F000000000000F03F0000000000000040000000000000F03F0000000000000840 {"highway":"track"} 0102000020E610000003000000000000000000F03F000000000000F03F000000000000F03F00000000000000400000000000000040000000000000F83F {"barrier":"fence"} 0106000020E6100000010000000103000020E61000000100000004000000000000000000F03F000000000000F03F0000000000000040000000000000F83F000000000000F03F0000000000000040000000000000F03F000000000000F03F {"landuse":"forest"} osmium-tool-1.17.0/test/export/tag-empty.txt000066400000000000000000000013551474143067200210500ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=31,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=32,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=33,barrier=fence,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=34,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=35,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=31,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=32,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=33,barrier=fence,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=35,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=36,area=yes osmium-tool-1.17.0/test/export/tag-tag.txt000066400000000000000000000013551474143067200204650ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=31,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=32,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=33,barrier=fence,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=34,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=35,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=31,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=32,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=33,barrier=fence,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=35,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=36,area=yes osmium-tool-1.17.0/test/export/way-all-n.txt000066400000000000000000000033471474143067200207450ustar00rootroot00000000000000POINT(1 1) @id=10 POINT(1 2) @id=11 POINT(2 2) @id=12 POINT(2 1) @id=13 LINESTRING(1 1,1 2,2 2) @id=20 LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=40 LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=41,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=42,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=43,barrier=fence,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=45,area=something LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=48,area=something,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=41,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=42,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=43,barrier=fence,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=45,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=48,area=something,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way-all.txt000066400000000000000000000031311474143067200205010ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=41,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=42,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=43,barrier=fence,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=45,area=something LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=48,area=something,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=41,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=42,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=43,barrier=fence,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=45,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=48,area=something,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way-empty-tag.txt000066400000000000000000000026301474143067200216430ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=41,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=42,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=43,barrier=fence,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=45,area=something LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=48,area=something,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=42,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=43,barrier=fence,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way-empty-tagx.txt000066400000000000000000000023121474143067200220300ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=41,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=42,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=43,barrier=fence,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=45,area=something LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=48,area=something,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way-none.txt000066400000000000000000000015371474143067200207000ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way-null-tag.txt000066400000000000000000000023341474143067200214600ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=41,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=45,area=something LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=48,area=something,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=42,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=43,barrier=fence,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way-tag-empty.txt000066400000000000000000000026521474143067200216470ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=41,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=43,barrier=fence,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=48,area=something,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=41,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=42,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=43,barrier=fence,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=45,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=48,area=something,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way-tag-null.txt000066400000000000000000000023341474143067200214600ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=41,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=43,barrier=fence,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=48,area=something,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=42,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=45,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way-tag-tag.txt000066400000000000000000000023511474143067200212600ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=41,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=43,barrier=fence,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=48,area=something,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=42,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=43,barrier=fence,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way-tagx-empty.txt000066400000000000000000000023561474143067200220400ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=41,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=42,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=43,barrier=fence,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=45,area=something MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=48,area=something,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=51,area=something,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way-tagx-tagx.txt000066400000000000000000000015371474143067200216450ustar00rootroot00000000000000LINESTRING(1 1,1 2,2 2) @id=21,barrier=fence LINESTRING(1 1,1 2,2 2) @id=22,area=no LINESTRING(1 1,1 2,2 2) @id=23,area=something LINESTRING(1 1,1 2,2 2) @id=24,area=yes LINESTRING(1 1,1 2,2 2) @id=25,area=no,barrier=fence LINESTRING(1 1,1 2,2 2) @id=26,area=something,barrier=fence LINESTRING(1 1,1 2,2 2) @id=27,area=yes,barrier=fence LINESTRING(1 1,1 2,2 2) @id=28,area=no,landuse=grass LINESTRING(1 1,1 2,2 2) @id=29,area=something,landuse=grass LINESTRING(1 1,1 2,2 2) @id=30,area=yes,landuse=grass LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=44,area=no LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=47,area=no,barrier=fence LINESTRING(1 1,1 2,2 2,2 1,1 1) @id=50,area=no,landuse=grass MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=46,area=yes MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=49,area=yes,barrier=fence MULTIPOLYGON(((1 1,2 1,2 2,1 2,1 1))) @id=52,area=yes,landuse=grass osmium-tool-1.17.0/test/export/way.osm000066400000000000000000000165701474143067200177250ustar00rootroot00000000000000 osmium-tool-1.17.0/test/extract/000077500000000000000000000000001474143067200165255ustar00rootroot00000000000000osmium-tool-1.17.0/test/extract/CMakeLists.txt000066400000000000000000000062061474143067200212710ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - extract # #----------------------------------------------------------------------------- function(check_extract _name _input _output _opts) check_output(extract ${_name} "extract --generator=test -f osm extract/${_input} ${_opts} -b 0,0,1.5,10" "extract/${_output}") endfunction() function(check_extract_cfg _name _input _output _opts) check_output(extract cfg_${_name} "extract --generator=test extract/${_input} ${_opts} -c ${CMAKE_CURRENT_SOURCE_DIR}/config.json" "extract/${_output}") endfunction() function(check_extract_opl _name _input _output _opts) check_output(extract ${_name} "extract --generator=test -f opl extract/${_input} ${_opts}" "extract/${_output}") endfunction() #----------------------------------------------------------------------------- check_extract(clean input1.osm output-clean.osm "--clean version --clean uid") check_extract(simple input1.osm output-simple.osm "-s simple --output-header=xml_josm_upload!") check_extract(complete_ways input1.osm output-complete-ways.osm "-s complete_ways") check_extract(complete_ways_norels input1.osm output-complete-ways-norels.osm "-s complete_ways -S relations=false") check_extract(smart_default input1.osm output-smart.osm "-s smart") check_extract(smart_mp input1.osm output-smart.osm "-s smart -S types=multipolygon") check_extract(smart_any input1.osm output-smart.osm "-s smart -S types=any") check_extract(smart_nonmp input1.osm output-smart-nonmp.osm "-s smart -S types=x") check_extract_cfg(simple input1.osm output-simple.osm "-s simple --output-header=xml_josm_upload=false") #----------------------------------------------------------------------------- check_extract_opl(antimeridian-east-bbox antimeridian.opl output-antimeridian-east.opl "--bbox=160,60,180,80") check_extract_opl(antimeridian-west-bbox antimeridian.opl output-antimeridian-west.opl "--bbox=-180,60,-160,80") check_extract_opl(antimeridian-east-poly antimeridian.opl output-antimeridian-east.opl "--polygon=extract/polygon-russia-east.geojson") check_extract_opl(antimeridian-west-poly antimeridian.opl output-antimeridian-west.opl "--polygon=extract/polygon-russia-west.geojson") check_extract_opl(antimeridian-both-poly antimeridian.opl output-antimeridian-both.opl "--polygon=extract/polygon-russia-all.geojson") check_extract_opl(antimeridian-reverse-poly antimeridian.opl output-antimeridian-both.opl "--polygon=extract/polygon-russia-reverse.geojson") check_extract_opl(antimeridian-alaska-east-json w42394837.osm w42394837.opl "--polygon=extract/polygon-us-alaska.geojson") check_extract_opl(antimeridian-alaska-west-json w46113981.osm w46113981.opl "--polygon=extract/polygon-us-alaska.geojson") check_extract_opl(antimeridian-alaska-east-poly w42394837.osm w42394837.opl "--polygon=extract/polygon-us-alaska.poly") check_extract_opl(antimeridian-alaska-west-poly w46113981.osm w46113981.opl "--polygon=extract/polygon-us-alaska.poly") #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/extract/antimeridian.opl000066400000000000000000000015441474143067200217110ustar00rootroot00000000000000n10 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x170 y66 n11 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x180 y66 n12 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x180 y70 n13 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x170 y70 n20 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-170 y66 n21 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-180 y66 n22 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-180 y70 n23 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-170 y70 w40 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn10,n11,n12,n13,n10 w41 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn20,n21,n22,n23,n20 w42 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn11,n12 w43 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn21,n22 w50 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn10,n13,n12,n11,n10 w51 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn20,n23,n22,n21,n20 w52 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn12,n11 w53 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn22,n21 osmium-tool-1.17.0/test/extract/config.json000066400000000000000000000002171474143067200206650ustar00rootroot00000000000000{ "extracts": [ { "output": "-", "output_format": "osm", "description": "Test", "bbox": [0,0,1.5,10] } ] } osmium-tool-1.17.0/test/extract/empty-root.geojson000066400000000000000000000000031474143067200222230ustar00rootroot00000000000000{} osmium-tool-1.17.0/test/extract/empty.geojson000066400000000000000000000000001474143067200212370ustar00rootroot00000000000000osmium-tool-1.17.0/test/extract/empty.osm.opl000066400000000000000000000000001474143067200211620ustar00rootroot00000000000000osmium-tool-1.17.0/test/extract/empty.poly000066400000000000000000000000001474143067200205560ustar00rootroot00000000000000osmium-tool-1.17.0/test/extract/input1.osm000066400000000000000000000043451474143067200204730ustar00rootroot00000000000000 osmium-tool-1.17.0/test/extract/invalid-root.geojson000066400000000000000000000000051474143067200225150ustar00rootroot00000000000000null osmium-tool-1.17.0/test/extract/invalid.geojson000066400000000000000000000000071474143067200215360ustar00rootroot00000000000000FOOBAR osmium-tool-1.17.0/test/extract/missing-end-polygon.poly000066400000000000000000000000741474143067200233350ustar00rootroot00000000000000foo 1 10.0 10.0 19.0 10.0 19.0 19.0 10.0 19.0 10.0 10.0 END osmium-tool-1.17.0/test/extract/missing-end-ring.poly000066400000000000000000000000701474143067200226010ustar00rootroot00000000000000foo 1 10.0 10.0 19.0 10.0 19.0 19.0 10.0 19.0 10.0 10.0 osmium-tool-1.17.0/test/extract/multipolygon.osm.opl000066400000000000000000000005121474143067200225760ustar00rootroot00000000000000n10 x10.0 y10.0 n11 x19.0 y10.0 n12 x19.0 y19.0 n13 x10.0 y19.0 n14 x11.0 y11.0 n15 x18.0 y11.0 n16 x18.0 y18.0 n17 x11.0 y18.0 n20 x20.0 y20.0 n21 x29.0 y20.0 n22 x29.0 y29.0 n23 x20.0 y29.0 w40 Nn10,n11,n12,n13,n10 w41 Nn14,n15,n16,n17,n14 w42 Nn20,n21,n22,n23,n20 r90 Ttype=multipolygon Mw40@,w41@ r91 Ttype=multipolygon Mw42@ osmium-tool-1.17.0/test/extract/no-polygon.osm.opl000066400000000000000000000001251474143067200221350ustar00rootroot00000000000000n10 x10.0 y10.0 n11 x19.0 y10.0 n12 x19.0 y19.0 n13 x10.0 y19.0 w40 Nn10,n11,n12,n13 osmium-tool-1.17.0/test/extract/one-line.poly000066400000000000000000000000041474143067200211320ustar00rootroot00000000000000foo osmium-tool-1.17.0/test/extract/output-antimeridian-both.opl000066400000000000000000000015441474143067200242010ustar00rootroot00000000000000n10 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x170 y66 n11 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x180 y66 n12 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x180 y70 n13 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x170 y70 n20 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-170 y66 n21 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-180 y66 n22 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-180 y70 n23 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-170 y70 w40 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn10,n11,n12,n13,n10 w41 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn20,n21,n22,n23,n20 w42 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn11,n12 w43 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn21,n22 w50 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn10,n13,n12,n11,n10 w51 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn20,n23,n22,n21,n20 w52 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn12,n11 w53 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn22,n21 osmium-tool-1.17.0/test/extract/output-antimeridian-east.opl000066400000000000000000000006601474143067200241770ustar00rootroot00000000000000n10 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x170 y66 n11 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x180 y66 n12 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x180 y70 n13 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x170 y70 w40 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn10,n11,n12,n13,n10 w42 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn11,n12 w50 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn10,n13,n12,n11,n10 w52 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn12,n11 osmium-tool-1.17.0/test/extract/output-antimeridian-west.opl000066400000000000000000000006641474143067200242310ustar00rootroot00000000000000n20 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-170 y66 n21 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-180 y66 n22 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-180 y70 n23 v1 dV c1 t2020-01-01T00:00:00Z i0 u T x-170 y70 w41 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn20,n21,n22,n23,n20 w43 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn21,n22 w51 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn20,n23,n22,n21,n20 w53 v1 dV c1 t2020-01-01T00:00:00Z i0 u T Nn22,n21 osmium-tool-1.17.0/test/extract/output-clean.osm000066400000000000000000000025611474143067200216710ustar00rootroot00000000000000 osmium-tool-1.17.0/test/extract/output-complete-ways-norels.osm000066400000000000000000000013231474143067200246730ustar00rootroot00000000000000 osmium-tool-1.17.0/test/extract/output-complete-ways.osm000066400000000000000000000030711474143067200233750ustar00rootroot00000000000000 osmium-tool-1.17.0/test/extract/output-simple.osm000066400000000000000000000022251474143067200220750ustar00rootroot00000000000000 osmium-tool-1.17.0/test/extract/output-smart-nonmp.osm000066400000000000000000000030711474143067200230570ustar00rootroot00000000000000 osmium-tool-1.17.0/test/extract/output-smart.osm000066400000000000000000000037041474143067200217350ustar00rootroot00000000000000 osmium-tool-1.17.0/test/extract/polygon-crlf.poly000066400000000000000000000001111474143067200220360ustar00rootroot00000000000000foo 1 10.0 10.0 19.0 10.0 19.0 19.0 10.0 19.0 10.0 10.0 END END osmium-tool-1.17.0/test/extract/polygon-one-outer.poly000066400000000000000000000001001474143067200230230ustar00rootroot00000000000000foo 1 10.0 10.0 19.0 10.0 19.0 19.0 10.0 19.0 10.0 10.0 END END osmium-tool-1.17.0/test/extract/polygon-outer-inner.poly000066400000000000000000000001721474143067200233660ustar00rootroot00000000000000foo 1 10.0 10.0 19.0 10.0 19.0 19.0 10.0 19.0 10.0 10.0 END !1s 11.0 11.0 18.0 11.0 18.0 18.0 11.0 18.0 11.0 11.0 END END osmium-tool-1.17.0/test/extract/polygon-russia-all.geojson000066400000000000000000002350551474143067200236660ustar00rootroot00000000000000{ "type": "Feature", "properties": { "name": "polygon" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 47.45024, 41.21199 ], [ 47.55554, 41.14866 ], [ 47.63965, 41.17394 ], [ 47.77601, 41.1355 ], [ 47.90696, 41.17502 ], [ 48.1129, 41.44532 ], [ 48.41078, 41.55137 ], [ 48.62989, 41.80192 ], [ 48.86453, 41.95753 ], [ 48.60773, 42.16834 ], [ 48.23971, 42.57976 ], [ 47.97945, 42.99383 ], [ 47.84597, 43.11901 ], [ 47.88465, 43.29552 ], [ 47.85146, 43.47209 ], [ 47.89469, 43.61146 ], [ 48.16466, 43.87705 ], [ 48.19536, 43.98996 ], [ 48.1644, 44.09189 ], [ 48.04129, 44.20116 ], [ 47.8084, 44.24603 ], [ 47.89509, 44.44452 ], [ 47.78865, 44.65814 ], [ 47.59802, 44.74029 ], [ 47.37386, 44.72613 ], [ 47.64786, 45.15848 ], [ 48.05696, 45.24572 ], [ 48.27987, 45.40203 ], [ 48.67183, 45.35084 ], [ 48.86567, 45.38544 ], [ 49.01144, 45.47855 ], [ 49.11256, 45.65282 ], [ 49.93666, 46.04634 ], [ 49.71829, 46.23479 ], [ 49.52308, 46.24281 ], [ 49.19315, 46.4275 ], [ 48.62393, 46.65237 ], [ 48.92563, 46.6427 ], [ 49.04755, 46.75114 ], [ 48.56782, 47.43402 ], [ 48.46943, 47.47112 ], [ 48.23329, 47.7388 ], [ 48.04813, 47.81218 ], [ 47.66885, 47.80996 ], [ 47.41085, 47.8885 ], [ 47.35203, 47.76545 ], [ 47.23594, 47.80066 ], [ 47.22767, 47.87353 ], [ 47.14475, 47.95903 ], [ 47.26121, 48.07877 ], [ 47.17553, 48.15345 ], [ 47.15755, 48.3071 ], [ 46.59034, 48.46934 ], [ 46.80537, 48.89006 ], [ 47.0122, 48.9948 ], [ 47.09872, 49.14378 ], [ 47.0187, 49.27955 ], [ 46.85039, 49.38503 ], [ 46.94498, 49.81672 ], [ 47.19074, 49.88336 ], [ 47.38377, 50.05208 ], [ 47.36594, 50.27447 ], [ 47.51007, 50.37976 ], [ 47.59166, 50.40748 ], [ 47.89502, 50.20414 ], [ 48.05998, 50.05301 ], [ 48.20312, 49.82278 ], [ 48.4479, 49.75097 ], [ 48.76092, 49.87291 ], [ 48.95297, 50.02451 ], [ 48.77469, 50.29923 ], [ 48.71294, 50.54935 ], [ 48.83899, 50.54948 ], [ 49.14368, 50.73163 ], [ 49.45624, 50.81043 ], [ 49.49517, 50.88162 ], [ 49.43494, 51.00972 ], [ 49.46337, 51.05153 ], [ 49.77528, 51.05602 ], [ 50.02016, 51.19171 ], [ 50.38884, 51.28291 ], [ 50.43973, 51.36955 ], [ 50.59199, 51.43686 ], [ 50.62893, 51.56545 ], [ 50.76797, 51.52409 ], [ 50.84618, 51.54813 ], [ 50.87969, 51.63323 ], [ 51.23949, 51.62827 ], [ 51.19473, 51.52671 ], [ 51.26264, 51.44307 ], [ 51.58176, 51.45817 ], [ 51.63571, 51.40443 ], [ 51.85604, 51.46959 ], [ 51.84275, 51.56811 ], [ 51.90648, 51.62539 ], [ 52.09789, 51.60852 ], [ 52.31873, 51.68726 ], [ 52.54097, 51.40815 ], [ 52.78196, 51.44728 ], [ 52.94984, 51.40401 ], [ 53.22514, 51.45484 ], [ 53.53716, 51.3739 ], [ 53.55134, 51.28157 ], [ 53.63629, 51.18537 ], [ 53.99397, 51.1117 ], [ 54.08016, 51.06506 ], [ 54.17041, 50.92215 ], [ 54.42749, 50.80938 ], [ 54.36506, 50.61075 ], [ 54.54151, 50.47668 ], [ 54.64616, 50.49797 ], [ 54.78157, 50.61327 ], [ 54.72781, 50.8079 ], [ 54.74457, 50.91284 ], [ 54.65958, 50.97017 ], [ 55.02412, 50.85762 ], [ 55.02561, 50.77932 ], [ 55.36266, 50.60933 ], [ 55.47464, 50.61864 ], [ 55.71887, 50.49804 ], [ 56.08227, 50.65105 ], [ 56.17464, 50.72225 ], [ 56.2094, 50.861 ], [ 56.37383, 50.8525 ], [ 56.49571, 50.9305 ], [ 56.51267, 51.00062 ], [ 56.71622, 50.92326 ], [ 56.79957, 50.96934 ], [ 56.77757, 51.03494 ], [ 57.16343, 51.04051 ], [ 57.2991, 50.89787 ], [ 57.50648, 50.82501 ], [ 57.57432, 50.88038 ], [ 57.79196, 50.87955 ], [ 57.81701, 51.06097 ], [ 58.16644, 51.01243 ], [ 58.29841, 51.09797 ], [ 58.36807, 51.02613 ], [ 58.5548, 51.00639 ], [ 58.55671, 50.83518 ], [ 58.61717, 50.82102 ], [ 58.63651, 50.76234 ], [ 58.75108, 50.75904 ], [ 58.87397, 50.64752 ], [ 59.40752, 50.5865 ], [ 59.41208, 50.5204 ], [ 59.50366, 50.44446 ], [ 59.83658, 50.49067 ], [ 60.03802, 50.64431 ], [ 60.04013, 50.76267 ], [ 60.14419, 50.78129 ], [ 60.30811, 50.62164 ], [ 60.82497, 50.60673 ], [ 61.4775, 50.76372 ], [ 61.6091, 51.18039 ], [ 61.71087, 51.2122 ], [ 61.73371, 51.27975 ], [ 61.505, 51.45935 ], [ 61.02821, 51.52042 ], [ 60.97324, 51.56357 ], [ 60.9563, 51.66168 ], [ 60.48638, 51.69575 ], [ 60.55666, 51.7417 ], [ 60.55461, 51.83352 ], [ 60.19803, 51.9389 ], [ 60.52283, 52.10175 ], [ 60.74276, 52.11238 ], [ 61.10595, 52.3143 ], [ 61.0192, 52.54008 ], [ 60.90531, 52.56987 ], [ 60.88123, 52.67443 ], [ 60.7726, 52.69768 ], [ 61.16093, 52.94651 ], [ 61.47824, 52.97811 ], [ 61.62182, 52.90428 ], [ 61.7987, 52.94538 ], [ 62.0233, 52.89914 ], [ 62.16733, 52.95498 ], [ 62.19602, 53.05015 ], [ 62.13175, 53.16199 ], [ 61.81359, 53.22919 ], [ 61.70444, 53.30797 ], [ 61.54245, 53.26888 ], [ 61.23391, 53.34354 ], [ 61.28709, 53.45849 ], [ 61.47316, 53.4121 ], [ 61.58914, 53.45228 ], [ 61.64179, 53.52702 ], [ 61.56672, 53.64116 ], [ 61.2198, 53.61791 ], [ 61.11265, 53.6706 ], [ 61.27224, 53.77458 ], [ 61.32252, 54.02155 ], [ 61.43208, 54.02931 ], [ 61.55738, 53.92026 ], [ 61.70177, 53.96783 ], [ 61.93821, 53.8984 ], [ 62.07141, 53.90617 ], [ 62.08669, 53.99158 ], [ 62.3479, 53.98152 ], [ 62.40841, 53.89399 ], [ 62.5166, 53.86345 ], [ 62.62218, 53.93064 ], [ 62.63738, 54.02574 ], [ 63.09202, 54.05401 ], [ 63.23851, 54.14052 ], [ 63.79068, 54.21601 ], [ 63.97411, 54.14977 ], [ 64.10045, 54.25829 ], [ 64.61423, 54.32537 ], [ 64.75536, 54.3044 ], [ 64.95391, 54.36365 ], [ 65.10061, 54.28314 ], [ 65.23567, 54.28547 ], [ 65.31312, 54.35856 ], [ 65.27782, 54.4981 ], [ 65.51136, 54.51945 ], [ 65.55275, 54.58507 ], [ 65.76179, 54.55718 ], [ 65.90964, 54.65084 ], [ 66.01484, 54.57539 ], [ 67.07417, 54.73086 ], [ 67.32834, 54.81538 ], [ 67.69672, 54.81308 ], [ 67.80211, 54.84358 ], [ 67.86256, 54.92386 ], [ 68.24901, 54.92079 ], [ 68.36633, 55.06849 ], [ 68.30415, 55.13647 ], [ 68.64694, 55.15331 ], [ 68.77505, 55.31655 ], [ 69.02836, 55.23811 ], [ 69.03674, 55.37045 ], [ 69.20471, 55.28023 ], [ 69.37966, 55.32359 ], [ 69.48628, 55.28513 ], [ 69.7053, 55.29902 ], [ 69.93304, 55.16394 ], [ 70.20063, 55.09731 ], [ 70.41639, 55.16605 ], [ 70.46601, 55.22237 ], [ 70.76852, 55.23043 ], [ 70.9409, 55.05848 ], [ 70.91112, 54.87317 ], [ 70.99774, 54.74058 ], [ 71.07781, 54.65284 ], [ 71.17515, 54.64735 ], [ 71.12151, 54.5804 ], [ 71.15395, 54.37672 ], [ 70.94941, 54.34494 ], [ 70.95604, 54.24729 ], [ 71.09352, 54.08826 ], [ 71.16922, 54.04168 ], [ 71.35058, 54.12825 ], [ 71.47602, 54.04809 ], [ 71.73271, 54.05468 ], [ 71.81381, 54.12726 ], [ 71.79116, 54.19184 ], [ 71.96843, 54.17919 ], [ 72.19242, 54.0773 ], [ 72.26859, 54.18256 ], [ 72.36464, 54.00627 ], [ 72.32821, 53.92899 ], [ 72.51375, 53.85759 ], [ 72.57601, 53.91939 ], [ 72.73967, 53.92125 ], [ 72.76257, 54.02257 ], [ 72.71928, 54.07208 ], [ 72.92642, 54.04317 ], [ 73.04924, 53.93876 ], [ 73.39994, 53.89362 ], [ 73.30287, 53.81917 ], [ 73.28642, 53.72743 ], [ 73.20671, 53.69327 ], [ 73.19241, 53.55241 ], [ 73.44144, 53.385 ], [ 73.70901, 53.55462 ], [ 73.82959, 53.5285 ], [ 73.93355, 53.59363 ], [ 74.05274, 53.5143 ], [ 74.19647, 53.53673 ], [ 74.25824, 53.45297 ], [ 74.40758, 53.40888 ], [ 74.53481, 53.55444 ], [ 74.50614, 53.6269 ], [ 74.65941, 53.62507 ], [ 74.83088, 53.76654 ], [ 75.07475, 53.74859 ], [ 75.47387, 53.93347 ], [ 75.47389, 54.04444 ], [ 76.20979, 54.20822 ], [ 76.2796, 54.29552 ], [ 76.64382, 54.2847 ], [ 76.74415, 54.34325 ], [ 76.7993, 54.3135 ], [ 76.69981, 54.20269 ], [ 76.40203, 54.19956 ], [ 76.3879, 54.10426 ], [ 76.46503, 53.9997 ], [ 77.87975, 53.24298 ], [ 79.04392, 52.00902 ], [ 80.05173, 50.69358 ], [ 80.24767, 50.84853 ], [ 80.51988, 50.93412 ], [ 80.51989, 51.14206 ], [ 80.6576, 51.16136 ], [ 80.70717, 51.25352 ], [ 81.10698, 51.13065 ], [ 81.01967, 50.91674 ], [ 81.35919, 50.92006 ], [ 81.45208, 50.70372 ], [ 81.89253, 50.7463 ], [ 82.16666, 50.67976 ], [ 82.36827, 50.72346 ], [ 82.56112, 50.69488 ], [ 82.73557, 50.77502 ], [ 82.78288, 50.86773 ], [ 82.98475, 50.83348 ], [ 83.16801, 50.95285 ], [ 83.39428, 50.95179 ], [ 83.89711, 50.76756 ], [ 83.93169, 50.69045 ], [ 84.16214, 50.50008 ], [ 84.20435, 50.27332 ], [ 84.31094, 50.17701 ], [ 84.61849, 50.15736 ], [ 84.94911, 50.02382 ], [ 84.94348, 49.87841 ], [ 85.15354, 49.70814 ], [ 85.16417, 49.60616 ], [ 85.23928, 49.54103 ], [ 85.58158, 49.55187 ], [ 85.67419, 49.49991 ], [ 85.88436, 49.50714 ], [ 85.95551, 49.4376 ], [ 86.09463, 49.47158 ], [ 86.21145, 49.41643 ], [ 86.31924, 49.54148 ], [ 86.444, 49.56335 ], [ 86.58109, 49.66593 ], [ 86.54902, 49.61732 ], [ 86.5778, 49.53995 ], [ 86.77356, 49.5029 ], [ 86.79323, 49.42129 ], [ 86.99838, 49.21372 ], [ 87.23516, 49.18828 ], [ 87.24755, 49.0826 ], [ 87.42123, 49.02101 ], [ 87.71537, 49.12298 ], [ 88.00845, 49.13609 ], [ 88.21125, 49.26367 ], [ 88.23826, 49.42432 ], [ 88.59651, 49.44701 ], [ 88.8494, 49.39079 ], [ 88.92032, 49.44588 ], [ 88.9861, 49.41323 ], [ 89.15498, 49.4515 ], [ 89.25965, 49.50635 ], [ 89.27895, 49.56276 ], [ 89.37528, 49.53596 ], [ 89.75596, 49.69343 ], [ 89.7634, 49.80047 ], [ 89.69338, 49.88559 ], [ 90.00121, 49.92667 ], [ 90.07709, 49.97752 ], [ 90.07877, 50.03075 ], [ 90.29256, 50.05998 ], [ 90.52389, 50.18479 ], [ 90.70322, 50.17162 ], [ 90.77261, 50.21512 ], [ 90.78055, 50.27553 ], [ 90.92677, 50.3018 ], [ 90.97181, 50.37544 ], [ 91.4244, 50.40232 ], [ 91.5069, 50.5069 ], [ 91.67377, 50.54436 ], [ 91.70358, 50.61791 ], [ 91.80652, 50.67285 ], [ 92.08418, 50.64518 ], [ 92.27933, 50.68308 ], [ 92.36371, 50.79781 ], [ 92.43545, 50.74418 ], [ 92.54259, 50.74061 ], [ 92.55869, 50.68319 ], [ 92.63326, 50.6551 ], [ 92.77416, 50.68068 ], [ 92.81338, 50.75551 ], [ 92.96927, 50.74261 ], [ 92.92014, 50.63042 ], [ 92.99199, 50.55842 ], [ 93.11647, 50.53637 ], [ 93.44148, 50.57837 ], [ 93.70001, 50.53328 ], [ 94.23916, 50.53319 ], [ 94.29163, 50.48363 ], [ 94.34909, 50.18726 ], [ 94.45798, 50.14274 ], [ 94.60536, 49.98558 ], [ 94.9497, 49.997 ], [ 95.02491, 49.92501 ], [ 95.4031, 49.90624 ], [ 95.52948, 49.85375 ], [ 95.80041, 49.92778 ], [ 95.85203, 49.98876 ], [ 95.96315, 49.9215 ], [ 96.06126, 49.95682 ], [ 96.23183, 49.9262 ], [ 96.40952, 49.82275 ], [ 96.52829, 49.88244 ], [ 96.6104, 49.82108 ], [ 96.72672, 49.86967 ], [ 96.94036, 49.84157 ], [ 97.21371, 49.69574 ], [ 97.33491, 49.70385 ], [ 97.51801, 49.76273 ], [ 97.60912, 49.81855 ], [ 97.63576, 49.89312 ], [ 97.73767, 49.92475 ], [ 97.81343, 49.8756 ], [ 97.91491, 49.88112 ], [ 98.10534, 49.99953 ], [ 98.35058, 50.29995 ], [ 98.37164, 50.52891 ], [ 98.07766, 50.68434 ], [ 98.02749, 50.77358 ], [ 98.07692, 50.89105 ], [ 97.90421, 51.01184 ], [ 98.01436, 51.31991 ], [ 98.08842, 51.40432 ], [ 98.25657, 51.4186 ], [ 98.29632, 51.56664 ], [ 98.4043, 51.68337 ], [ 98.78829, 51.82535 ], [ 98.9223, 52.09636 ], [ 98.99962, 52.02087 ], [ 99.198, 51.97517 ], [ 99.27698, 51.90741 ], [ 99.72202, 51.85495 ], [ 99.85793, 51.71593 ], [ 100.034, 51.67827 ], [ 100.5598, 51.6847 ], [ 101.1288, 51.47283 ], [ 101.2383, 51.48023 ], [ 101.3556, 51.40426 ], [ 101.5145, 51.44502 ], [ 101.6075, 51.3934 ], [ 102.0795, 51.31954 ], [ 102.0841, 51.1035 ], [ 102.173, 50.97255 ], [ 102.1671, 50.80767 ], [ 102.2637, 50.73078 ], [ 102.2659, 50.64856 ], [ 102.4925, 50.54337 ], [ 102.6371, 50.35583 ], [ 102.9291, 50.25778 ], [ 103.2022, 50.27522 ], [ 103.2185, 50.17473 ], [ 103.2692, 50.14192 ], [ 103.4506, 50.15905 ], [ 103.7202, 50.08042 ], [ 103.8655, 50.13703 ], [ 104.1506, 50.09528 ], [ 104.4205, 50.25897 ], [ 104.816, 50.29484 ], [ 104.9176, 50.35659 ], [ 105.1356, 50.34157 ], [ 105.3358, 50.42247 ], [ 105.9772, 50.36646 ], [ 106.0687, 50.28509 ], [ 106.2522, 50.25273 ], [ 106.6131, 50.2864 ], [ 106.9572, 50.16639 ], [ 107.0553, 50.02044 ], [ 107.2216, 49.94051 ], [ 107.8674, 49.88297 ], [ 107.9188, 49.62664 ], [ 108.2573, 49.48815 ], [ 108.3194, 49.3937 ], [ 108.5228, 49.27065 ], [ 109.1851, 49.30017 ], [ 109.5601, 49.16905 ], [ 110.2016, 49.1031 ], [ 110.3939, 49.18066 ], [ 110.675, 49.11985 ], [ 110.8318, 49.13151 ], [ 111.3795, 49.30048 ], [ 111.535, 49.27253 ], [ 111.6978, 49.33232 ], [ 111.9713, 49.33214 ], [ 112.483, 49.47066 ], [ 112.8329, 49.46813 ], [ 113.0753, 49.56811 ], [ 113.2495, 49.79361 ], [ 114.3339, 50.22572 ], [ 114.8412, 50.16705 ], [ 114.9752, 50.12079 ], [ 115.2067, 49.93925 ], [ 115.5053, 49.85507 ], [ 115.7563, 49.83735 ], [ 116.2382, 49.97786 ], [ 116.5947, 49.88062 ], [ 116.6926, 49.79324 ], [ 117.0505, 49.63472 ], [ 117.8774, 49.45985 ], [ 117.9416, 49.54323 ], [ 118.1871, 49.61285 ], [ 118.6009, 49.87309 ], [ 119.0964, 49.93556 ], [ 119.321, 50.07283 ], [ 119.3992, 50.17526 ], [ 119.4274, 50.32667 ], [ 119.3728, 50.40218 ], [ 119.2828, 50.41416 ], [ 119.3404, 50.57032 ], [ 119.5266, 50.70932 ], [ 119.5779, 50.87959 ], [ 119.7974, 51.06188 ], [ 119.8679, 51.23952 ], [ 120.0398, 51.42882 ], [ 120.0956, 51.59387 ], [ 120.6829, 51.88581 ], [ 120.7452, 51.96097 ], [ 120.8298, 52.15832 ], [ 120.79, 52.28908 ], [ 120.6923, 52.34577 ], [ 120.7762, 52.52516 ], [ 120.7613, 52.57697 ], [ 120.4502, 52.69505 ], [ 120.0884, 52.63744 ], [ 120.1049, 52.73635 ], [ 120.3116, 52.82015 ], [ 120.8901, 53.23289 ], [ 121.2326, 53.22818 ], [ 122.3246, 53.44094 ], [ 122.4353, 53.39169 ], [ 122.8514, 53.40464 ], [ 123.1574, 53.45004 ], [ 123.2722, 53.50785 ], [ 123.47, 53.44685 ], [ 123.6187, 53.48627 ], [ 123.8609, 53.43111 ], [ 124.0983, 53.29736 ], [ 124.2257, 53.31909 ], [ 124.4174, 53.16787 ], [ 124.6538, 53.15172 ], [ 124.8532, 53.05015 ], [ 124.9248, 53.06199 ], [ 124.9538, 53.13363 ], [ 125.1487, 53.15071 ], [ 125.4939, 52.99904 ], [ 125.5857, 53.02373 ], [ 125.6394, 52.96569 ], [ 125.6027, 52.90062 ], [ 125.6314, 52.82388 ], [ 125.803, 52.83892 ], [ 125.9434, 52.70869 ], [ 125.9116, 52.65355 ], [ 125.9399, 52.56955 ], [ 126.1223, 52.51982 ], [ 126.1545, 52.42823 ], [ 126.2816, 52.38269 ], [ 126.2711, 52.16747 ], [ 126.4815, 52.10319 ], [ 126.3914, 52.04517 ], [ 126.4073, 51.93178 ], [ 126.6623, 51.67533 ], [ 126.621, 51.59101 ], [ 126.7484, 51.50534 ], [ 126.7256, 51.43632 ], [ 126.7847, 51.37122 ], [ 126.7585, 51.29761 ], [ 126.8431, 51.19485 ], [ 126.8733, 51.03162 ], [ 127.0839, 50.88711 ], [ 127.2297, 50.71578 ], [ 127.2978, 50.57983 ], [ 127.2364, 50.47953 ], [ 127.2909, 50.39955 ], [ 127.2872, 50.30199 ], [ 127.5453, 50.18689 ], [ 127.4377, 50.01178 ], [ 127.5004, 49.77009 ], [ 127.6156, 49.72548 ], [ 127.6583, 49.62535 ], [ 127.8411, 49.52235 ], [ 128.1806, 49.48504 ], [ 128.5465, 49.54902 ], [ 128.6881, 49.51431 ], [ 128.7491, 49.42439 ], [ 128.9727, 49.40282 ], [ 129.0795, 49.30177 ], [ 129.218, 49.34529 ], [ 129.3668, 49.30406 ], [ 129.4291, 49.38526 ], [ 129.4759, 49.37681 ], [ 129.5408, 49.24043 ], [ 129.6882, 49.24001 ], [ 129.8921, 48.99576 ], [ 130.1979, 48.82225 ], [ 130.4284, 48.85132 ], [ 130.5595, 48.8049 ], [ 130.4748, 48.59328 ], [ 130.5535, 48.54617 ], [ 130.5905, 48.4499 ], [ 130.6787, 48.43887 ], [ 130.7561, 48.30394 ], [ 130.6185, 48.14973 ], [ 130.6074, 48.07632 ], [ 130.841, 47.88329 ], [ 130.9676, 47.65113 ], [ 131.0996, 47.63207 ], [ 131.4507, 47.69047 ], [ 131.5963, 47.60511 ], [ 131.7141, 47.65205 ], [ 131.9638, 47.61171 ], [ 132.3304, 47.70502 ], [ 132.568, 47.66682 ], [ 132.644, 47.71194 ], [ 132.7325, 47.88553 ], [ 132.8258, 47.88361 ], [ 133.0785, 48.05274 ], [ 133.5531, 48.07553 ], [ 133.624, 48.14036 ], [ 133.7354, 48.14429 ], [ 133.7865, 48.20655 ], [ 134.2169, 48.33272 ], [ 134.6858, 48.35052 ], [ 134.4936, 47.98576 ], [ 134.7102, 47.72819 ], [ 134.5187, 47.52034 ], [ 134.2986, 47.48392 ], [ 134.1255, 47.3412 ], [ 134.1005, 47.24881 ], [ 134.1693, 47.15426 ], [ 134.0129, 47.00225 ], [ 133.9657, 46.69141 ], [ 133.7971, 46.49669 ], [ 133.8315, 46.29377 ], [ 133.6469, 46.18546 ], [ 133.6674, 46.0558 ], [ 133.4254, 45.87078 ], [ 133.3554, 45.6264 ], [ 133.1504, 45.54089 ], [ 133.0403, 45.29954 ], [ 133.0559, 45.14931 ], [ 132.9346, 45.08232 ], [ 132.0293, 45.29861 ], [ 131.8762, 45.39202 ], [ 131.7397, 45.27829 ], [ 131.6433, 45.25991 ], [ 131.6028, 45.12862 ], [ 131.4421, 45.02841 ], [ 131.0879, 44.98491 ], [ 130.9201, 44.88378 ], [ 130.917, 44.79406 ], [ 131.0654, 44.65677 ], [ 131.2381, 44.08007 ], [ 131.1856, 43.98994 ], [ 131.1361, 43.55799 ], [ 131.2402, 43.41428 ], [ 131.1481, 43.24203 ], [ 131.1502, 43.15951 ], [ 131.0672, 43.08742 ], [ 131.0517, 42.97433 ], [ 130.9582, 42.91953 ], [ 130.8023, 42.93109 ], [ 130.5421, 42.86199 ], [ 130.3442, 42.73033 ], [ 130.3947, 42.66008 ], [ 130.5583, 42.6077 ], [ 130.5039, 42.50742 ], [ 130.6269, 42.28052 ], [ 130.8987, 42.12396 ], [ 133.2675, 39.96882 ], [ 140.789789, 45.836458 ], [ 142.586054, 45.579449 ], [ 145.596308, 44.66475 ], [ 145.431513, 44.13886 ], [ 145.195307, 43.763164 ], [ 145.493316, 43.534612 ], [ 145.828398, 43.384093 ], [ 146.0519, 43.12595 ], [ 180, 35.61404 ], [ 180, 83.83133 ], [ 37.2795, 83.81215 ], [ 31.27848, 70.11174 ], [ 30.77568, 69.82379 ], [ 30.88567, 69.60134 ], [ 30.54062, 69.59318 ], [ 30.24028, 69.70254 ], [ 30.07925, 69.70996 ], [ 30.04604, 69.62395 ], [ 30.11237, 69.57275 ], [ 30.01001, 69.47197 ], [ 29.84288, 69.47344 ], [ 29.56539, 69.37147 ], [ 29.28577, 69.34884 ], [ 29.18916, 69.14856 ], [ 29.04647, 69.07043 ], [ 28.90818, 69.09988 ], [ 28.36758, 68.92939 ], [ 28.45581, 68.83664 ], [ 28.68857, 68.8165 ], [ 28.38412, 68.5494 ], [ 28.61946, 68.15368 ], [ 29.29281, 68.02793 ], [ 29.62745, 67.76365 ], [ 29.92133, 67.63731 ], [ 29.88819, 67.56283 ], [ 29.04771, 67.04106 ], [ 28.98188, 66.93578 ], [ 29.07125, 66.75276 ], [ 29.43544, 66.50602 ], [ 29.66187, 66.23217 ], [ 29.89118, 66.07974 ], [ 30.06695, 65.74475 ], [ 29.67942, 65.66431 ], [ 29.73666, 65.55009 ], [ 29.68779, 65.49607 ], [ 29.67485, 65.36906 ], [ 29.56924, 65.30861 ], [ 29.55285, 65.24834 ], [ 29.61512, 65.18409 ], [ 29.78282, 65.17332 ], [ 29.59119, 65.09738 ], [ 29.54934, 65.00337 ], [ 29.56488, 64.90444 ], [ 29.70682, 64.7489 ], [ 29.99222, 64.74085 ], [ 30.02651, 64.66196 ], [ 29.94633, 64.6067 ], [ 29.93739, 64.52972 ], [ 30.00522, 64.3703 ], [ 30.42164, 64.21392 ], [ 30.49199, 64.10354 ], [ 30.22901, 63.8715 ], [ 29.9702, 63.81066 ], [ 29.93021, 63.72835 ], [ 30.46048, 63.42266 ], [ 30.77099, 63.35498 ], [ 31.18489, 63.18117 ], [ 31.2423, 63.06728 ], [ 31.49568, 62.90009 ], [ 31.11931, 62.48988 ], [ 30.61954, 62.24558 ], [ 29.69859, 61.61222 ], [ 29.4718, 61.53579 ], [ 29.20748, 61.31401 ], [ 28.79581, 61.16649 ], [ 28.63369, 61.00659 ], [ 28.49232, 60.99797 ], [ 27.85071, 60.65141 ], [ 27.64466, 60.46285 ], [ 27.6426, 60.40344 ], [ 27.4862, 60.30133 ], [ 26.86507, 60.16682 ], [ 26.39009, 59.92985 ], [ 26.91914, 59.57938 ], [ 27.82954, 59.53154 ], [ 28.12685, 59.36757 ], [ 27.88014, 59.28753 ], [ 27.68803, 59.01193 ], [ 27.30915, 58.80412 ], [ 27.48362, 58.38673 ], [ 27.44354, 58.20541 ], [ 27.55825, 58.07796 ], [ 27.63487, 57.89748 ], [ 27.51724, 57.87234 ], [ 27.26678, 57.58119 ], [ 27.33297, 57.47116 ], [ 27.48984, 57.48141 ], [ 27.48489, 57.38802 ], [ 27.80667, 57.26726 ], [ 27.77309, 57.18686 ], [ 27.66903, 57.11764 ], [ 27.68045, 56.96759 ], [ 27.60984, 56.82296 ], [ 27.64703, 56.78608 ], [ 27.84829, 56.81343 ], [ 27.86174, 56.71678 ], [ 28.12917, 56.4235 ], [ 28.11273, 56.37153 ], [ 28.16811, 56.28574 ], [ 28.10297, 56.1868 ], [ 28.11991, 56.1093 ], [ 28.30397, 56.00917 ], [ 28.58389, 56.0545 ], [ 28.72857, 55.91646 ], [ 28.86271, 55.905 ], [ 29.06219, 55.97783 ], [ 29.30575, 55.93635 ], [ 29.34851, 55.92022 ], [ 29.31199, 55.74329 ], [ 29.49395, 55.65306 ], [ 29.68037, 55.7369 ], [ 29.81433, 55.73245 ], [ 29.9147, 55.80383 ], [ 30.12313, 55.78048 ], [ 30.23792, 55.81532 ], [ 30.57809, 55.69633 ], [ 30.63959, 55.59844 ], [ 30.75319, 55.54151 ], [ 30.88151, 55.57085 ], [ 30.85992, 55.41069 ], [ 30.78692, 55.36041 ], [ 30.76885, 55.28175 ], [ 30.93431, 55.09108 ], [ 30.78148, 54.97479 ], [ 30.71476, 54.77384 ], [ 30.91914, 54.69588 ], [ 30.97209, 54.6262 ], [ 31.10248, 54.61217 ], [ 31.03625, 54.49514 ], [ 31.18732, 54.41846 ], [ 31.28732, 54.20322 ], [ 31.80737, 54.02874 ], [ 31.79375, 53.94019 ], [ 31.70897, 53.84793 ], [ 31.73503, 53.7526 ], [ 31.89973, 53.72387 ], [ 32.1166, 53.76006 ], [ 32.3069, 53.70644 ], [ 32.44324, 53.5122 ], [ 32.6811, 53.40566 ], [ 32.46274, 53.34737 ], [ 32.41788, 53.2555 ], [ 32.0986, 53.12929 ], [ 31.85271, 53.16265 ], [ 31.81184, 53.22346 ], [ 31.62667, 53.28143 ], [ 31.38296, 53.25917 ], [ 31.28393, 53.09675 ], [ 31.20669, 53.06964 ], [ 31.20841, 52.98805 ], [ 31.53098, 52.75924 ], [ 31.44993, 52.69603 ], [ 31.52909, 52.56008 ], [ 31.48765, 52.46169 ], [ 31.56666, 52.37409 ], [ 31.54027, 52.29675 ], [ 31.75549, 52.06822 ], [ 31.86193, 52.05565 ], [ 31.90689, 51.99334 ], [ 32.09497, 51.98266 ], [ 32.38992, 52.09939 ], [ 32.44809, 52.27175 ], [ 32.6915, 52.19798 ], [ 32.89863, 52.19427 ], [ 33.21088, 52.32006 ], [ 33.54886, 52.25097 ], [ 33.78861, 52.31255 ], [ 34.03332, 52.12261 ], [ 34.01219, 52.07252 ], [ 34.06314, 51.96613 ], [ 34.21642, 51.84007 ], [ 34.35746, 51.79404 ], [ 34.03453, 51.68698 ], [ 34.05617, 51.62284 ], [ 34.21773, 51.50759 ], [ 34.17101, 51.42194 ], [ 34.22899, 51.34658 ], [ 34.19268, 51.23231 ], [ 34.31097, 51.18884 ], [ 34.60857, 51.19203 ], [ 34.70031, 51.12526 ], [ 35.07328, 51.16195 ], [ 35.12019, 51.04252 ], [ 35.27827, 51.00344 ], [ 35.28067, 50.92582 ], [ 35.41448, 50.73853 ], [ 35.35064, 50.67781 ], [ 35.34606, 50.55788 ], [ 35.59275, 50.31192 ], [ 35.7418, 50.3038 ], [ 35.85155, 50.374 ], [ 36.07715, 50.39531 ], [ 36.27515, 50.24484 ], [ 36.46162, 50.25969 ], [ 36.64995, 50.16646 ], [ 36.88982, 50.28679 ], [ 37.16752, 50.30649 ], [ 37.41356, 50.38116 ], [ 37.57234, 50.255 ], [ 37.61331, 50.13249 ], [ 37.73295, 50.03249 ], [ 37.88199, 49.99718 ], [ 38.01555, 49.85233 ], [ 38.19247, 49.896 ], [ 38.28829, 50.02419 ], [ 38.3358, 49.95768 ], [ 38.65124, 49.90573 ], [ 38.92585, 49.74657 ], [ 39.17134, 49.81935 ], [ 39.25245, 49.71591 ], [ 39.54762, 49.68604 ], [ 39.6294, 49.57456 ], [ 39.79514, 49.50784 ], [ 39.99489, 49.54761 ], [ 39.98036, 49.44172 ], [ 40.1341, 49.31827 ], [ 39.89786, 49.11549 ], [ 39.62763, 49.06151 ], [ 39.64642, 48.95187 ], [ 39.75439, 48.87157 ], [ 39.65966, 48.74513 ], [ 39.61548, 48.58986 ], [ 39.66738, 48.53953 ], [ 39.80232, 48.52768 ], [ 39.79789, 48.45847 ], [ 39.85571, 48.39424 ], [ 39.79521, 48.35044 ], [ 39.79541, 48.28809 ], [ 39.8875, 48.22399 ], [ 39.73231, 48.06436 ], [ 39.76046, 47.97173 ], [ 39.71582, 47.88397 ], [ 38.87402, 47.9262 ], [ 38.74584, 47.84248 ], [ 38.72452, 47.75158 ], [ 38.32055, 47.6572 ], [ 38.2375, 47.56339 ], [ 38.24691, 47.42509 ], [ 38.17056, 47.33226 ], [ 38.17948, 47.11301 ], [ 38.23594, 46.98468 ], [ 38.11227, 46.91138 ], [ 37.62322, 46.88217 ], [ 37.41553, 46.76322 ], [ 36.64303, 45.68821 ], [ 36.33254, 45.72272 ], [ 35.99696, 45.67179 ], [ 35.78323, 45.6953 ], [ 35.5479, 45.57771 ], [ 35.25239, 45.8388 ], [ 34.95522, 45.81513 ], [ 34.86024, 45.85082 ], [ 34.834, 45.94033 ], [ 34.64487, 46.03539 ], [ 34.56099, 46.04619 ], [ 34.48616, 45.99791 ], [ 34.35945, 46.10523 ], [ 33.64373, 46.28118 ], [ 33.57107, 46.24987 ], [ 33.57418, 46.17282 ], [ 33.50204, 46.05619 ], [ 32.76382, 45.87799 ], [ 32.29008, 45.63796 ], [ 32.15053, 45.4186 ], [ 32.24215, 45.18556 ], [ 32.58196, 45.06437 ], [ 32.81426, 45.08492 ], [ 33.1961, 44.89718 ], [ 33.18807, 44.79736 ], [ 33.04632, 44.63244 ], [ 33.08447, 44.45073 ], [ 33.28842, 44.28003 ], [ 33.73338, 44.13411 ], [ 34.25741, 44.18416 ], [ 34.56984, 44.35196 ], [ 34.75216, 44.53336 ], [ 35.19419, 44.54824 ], [ 35.63792, 44.77878 ], [ 35.86723, 44.74156 ], [ 36.3213, 44.7814 ], [ 36.62697, 44.88227 ], [ 36.82653, 44.86342 ], [ 36.99347, 44.80367 ], [ 37.13441, 44.60302 ], [ 37.30884, 44.50028 ], [ 37.72977, 44.41796 ], [ 38.06819, 44.20528 ], [ 38.58442, 44.07787 ], [ 39.0957, 43.73459 ], [ 39.77181, 43.19436 ], [ 39.92102, 43.18958 ], [ 40.14963, 43.51766 ], [ 40.53619, 43.46775 ], [ 40.65366, 43.50114 ], [ 40.9289, 43.37216 ], [ 41.36808, 43.30067 ], [ 41.61549, 43.17233 ], [ 42.04859, 43.13725 ], [ 42.39962, 43.19365 ], [ 42.66235, 43.08262 ], [ 42.73485, 43.1274 ], [ 42.84302, 43.12009 ], [ 43.17041, 42.88863 ], [ 43.54686, 42.81264 ], [ 43.73402, 42.71448 ], [ 43.67202, 42.66099 ], [ 43.67724, 42.59853 ], [ 43.93197, 42.50111 ], [ 44.2535, 42.58062 ], [ 44.3303, 42.66346 ], [ 44.53225, 42.64866 ], [ 44.57483, 42.69518 ], [ 44.69127, 42.69116 ], [ 44.81052, 42.56385 ], [ 44.86958, 42.58652 ], [ 44.92369, 42.69655 ], [ 45.03821, 42.64202 ], [ 45.12851, 42.6547 ], [ 45.32356, 42.47483 ], [ 45.54435, 42.4928 ], [ 45.70059, 42.42948 ], [ 45.68852, 42.34632 ], [ 45.56284, 42.25334 ], [ 45.61474, 42.14678 ], [ 45.77294, 42.05502 ], [ 45.86065, 42.05444 ], [ 45.91019, 41.98434 ], [ 46.20599, 41.9492 ], [ 46.49783, 41.83242 ], [ 46.55742, 41.75878 ], [ 46.72213, 41.77576 ], [ 46.94197, 41.60451 ], [ 46.98537, 41.51775 ], [ 47.10308, 41.50738 ], [ 47.24051, 41.28804 ], [ 47.45024, 41.21199 ] ] ], [ [ [ -180, 72.2916 ], [ -180, 72.29053 ], [ -180, 62.26134 ], [ -172.074188, 64.033556 ], [ -168.725284, 65.414875 ], [ -168.684085, 65.990095 ], [ -169.907891, 72.234092 ], [ -180, 72.2916 ] ] ], [ [ [ 22.22727, 54.33593 ], [ 22.7962, 54.35926 ], [ 22.74021, 54.44744 ], [ 22.7093, 54.45891 ], [ 22.70476, 54.50897 ], [ 22.68861, 54.53217 ], [ 22.71956, 54.56434 ], [ 22.69213, 54.58511 ], [ 22.75463, 54.63005 ], [ 22.76275, 54.65463 ], [ 22.74373, 54.66534 ], [ 22.74301, 54.68216 ], [ 22.73321, 54.68658 ], [ 22.75458, 54.7047 ], [ 22.74835, 54.72438 ], [ 22.78026, 54.74346 ], [ 22.80989, 54.7428 ], [ 22.81955, 54.75959 ], [ 22.84556, 54.76117 ], [ 22.86419, 54.77399 ], [ 22.86373, 54.78234 ], [ 22.88351, 54.78865 ], [ 22.88011, 54.80362 ], [ 22.89215, 54.81546 ], [ 22.86936, 54.84295 ], [ 22.87459, 54.8553 ], [ 22.8486, 54.869 ], [ 22.85917, 54.89211 ], [ 22.82176, 54.91769 ], [ 22.79607, 54.90969 ], [ 22.78564, 54.92998 ], [ 22.77229, 54.92998 ], [ 22.76934, 54.94047 ], [ 22.73776, 54.95228 ], [ 22.72969, 54.96771 ], [ 22.69528, 54.97819 ], [ 22.68043, 54.99268 ], [ 22.65624, 54.9868 ], [ 22.65115, 54.9726 ], [ 22.64782, 54.9875 ], [ 22.60258, 55.02726 ], [ 22.59123, 55.07575 ], [ 22.47057, 55.05064 ], [ 22.29012, 55.071 ], [ 22.1606, 55.06165 ], [ 22.13061, 55.05093 ], [ 22.11668, 55.03312 ], [ 22.07676, 55.03107 ], [ 22.0409, 55.04771 ], [ 22.04595, 55.07927 ], [ 22.03355, 55.09001 ], [ 21.99622, 55.09254 ], [ 21.96346, 55.0801 ], [ 21.92037, 55.08658 ], [ 21.85347, 55.1025 ], [ 21.81586, 55.12522 ], [ 21.72595, 55.13858 ], [ 21.71247, 55.15668 ], [ 21.65011, 55.18673 ], [ 21.56952, 55.20409 ], [ 21.50256, 55.19329 ], [ 21.45261, 55.22705 ], [ 21.43505, 55.25676 ], [ 21.38577, 55.29945 ], [ 21.27184, 55.25158 ], [ 21.09934, 55.26235 ], [ 20.95439, 55.28694 ], [ 20.65365, 55.3899 ], [ 20.39793, 55.18633 ], [ 20.20131, 55.16615 ], [ 19.9205, 55.16401 ], [ 19.82198, 55.14569 ], [ 19.72775, 55.10661 ], [ 19.63488, 55.02533 ], [ 19.58918, 54.95461 ], [ 19.57351, 54.86918 ], [ 19.58461, 54.77262 ], [ 19.50858, 54.68355 ], [ 19.40837, 54.61169 ], [ 19.64733, 54.44727 ], [ 20.33136, 54.39511 ], [ 20.58391, 54.37189 ], [ 20.63083, 54.3604 ], [ 20.74068, 54.36326 ], [ 21.26116, 54.32314 ], [ 21.37827, 54.32501 ], [ 21.44629, 54.31282 ], [ 22.22727, 54.33593 ] ] ] ] } }osmium-tool-1.17.0/test/extract/polygon-russia-east.geojson000066400000000000000000002073661474143067200240560ustar00rootroot00000000000000{ "type": "Feature", "properties": { "name": "polygon" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 47.45024, 41.21199 ], [ 47.55554, 41.14866 ], [ 47.63965, 41.17394 ], [ 47.77601, 41.1355 ], [ 47.90696, 41.17502 ], [ 48.1129, 41.44532 ], [ 48.41078, 41.55137 ], [ 48.62989, 41.80192 ], [ 48.86453, 41.95753 ], [ 48.60773, 42.16834 ], [ 48.23971, 42.57976 ], [ 47.97945, 42.99383 ], [ 47.84597, 43.11901 ], [ 47.88465, 43.29552 ], [ 47.85146, 43.47209 ], [ 47.89469, 43.61146 ], [ 48.16466, 43.87705 ], [ 48.19536, 43.98996 ], [ 48.1644, 44.09189 ], [ 48.04129, 44.20116 ], [ 47.8084, 44.24603 ], [ 47.89509, 44.44452 ], [ 47.78865, 44.65814 ], [ 47.59802, 44.74029 ], [ 47.37386, 44.72613 ], [ 47.64786, 45.15848 ], [ 48.05696, 45.24572 ], [ 48.27987, 45.40203 ], [ 48.67183, 45.35084 ], [ 48.86567, 45.38544 ], [ 49.01144, 45.47855 ], [ 49.11256, 45.65282 ], [ 49.93666, 46.04634 ], [ 49.71829, 46.23479 ], [ 49.52308, 46.24281 ], [ 49.19315, 46.4275 ], [ 48.62393, 46.65237 ], [ 48.92563, 46.6427 ], [ 49.04755, 46.75114 ], [ 48.56782, 47.43402 ], [ 48.46943, 47.47112 ], [ 48.23329, 47.7388 ], [ 48.04813, 47.81218 ], [ 47.66885, 47.80996 ], [ 47.41085, 47.8885 ], [ 47.35203, 47.76545 ], [ 47.23594, 47.80066 ], [ 47.22767, 47.87353 ], [ 47.14475, 47.95903 ], [ 47.26121, 48.07877 ], [ 47.17553, 48.15345 ], [ 47.15755, 48.3071 ], [ 46.59034, 48.46934 ], [ 46.80537, 48.89006 ], [ 47.0122, 48.9948 ], [ 47.09872, 49.14378 ], [ 47.0187, 49.27955 ], [ 46.85039, 49.38503 ], [ 46.94498, 49.81672 ], [ 47.19074, 49.88336 ], [ 47.38377, 50.05208 ], [ 47.36594, 50.27447 ], [ 47.51007, 50.37976 ], [ 47.59166, 50.40748 ], [ 47.89502, 50.20414 ], [ 48.05998, 50.05301 ], [ 48.20312, 49.82278 ], [ 48.4479, 49.75097 ], [ 48.76092, 49.87291 ], [ 48.95297, 50.02451 ], [ 48.77469, 50.29923 ], [ 48.71294, 50.54935 ], [ 48.83899, 50.54948 ], [ 49.14368, 50.73163 ], [ 49.45624, 50.81043 ], [ 49.49517, 50.88162 ], [ 49.43494, 51.00972 ], [ 49.46337, 51.05153 ], [ 49.77528, 51.05602 ], [ 50.02016, 51.19171 ], [ 50.38884, 51.28291 ], [ 50.43973, 51.36955 ], [ 50.59199, 51.43686 ], [ 50.62893, 51.56545 ], [ 50.76797, 51.52409 ], [ 50.84618, 51.54813 ], [ 50.87969, 51.63323 ], [ 51.23949, 51.62827 ], [ 51.19473, 51.52671 ], [ 51.26264, 51.44307 ], [ 51.58176, 51.45817 ], [ 51.63571, 51.40443 ], [ 51.85604, 51.46959 ], [ 51.84275, 51.56811 ], [ 51.90648, 51.62539 ], [ 52.09789, 51.60852 ], [ 52.31873, 51.68726 ], [ 52.54097, 51.40815 ], [ 52.78196, 51.44728 ], [ 52.94984, 51.40401 ], [ 53.22514, 51.45484 ], [ 53.53716, 51.3739 ], [ 53.55134, 51.28157 ], [ 53.63629, 51.18537 ], [ 53.99397, 51.1117 ], [ 54.08016, 51.06506 ], [ 54.17041, 50.92215 ], [ 54.42749, 50.80938 ], [ 54.36506, 50.61075 ], [ 54.54151, 50.47668 ], [ 54.64616, 50.49797 ], [ 54.78157, 50.61327 ], [ 54.72781, 50.8079 ], [ 54.74457, 50.91284 ], [ 54.65958, 50.97017 ], [ 55.02412, 50.85762 ], [ 55.02561, 50.77932 ], [ 55.36266, 50.60933 ], [ 55.47464, 50.61864 ], [ 55.71887, 50.49804 ], [ 56.08227, 50.65105 ], [ 56.17464, 50.72225 ], [ 56.2094, 50.861 ], [ 56.37383, 50.8525 ], [ 56.49571, 50.9305 ], [ 56.51267, 51.00062 ], [ 56.71622, 50.92326 ], [ 56.79957, 50.96934 ], [ 56.77757, 51.03494 ], [ 57.16343, 51.04051 ], [ 57.2991, 50.89787 ], [ 57.50648, 50.82501 ], [ 57.57432, 50.88038 ], [ 57.79196, 50.87955 ], [ 57.81701, 51.06097 ], [ 58.16644, 51.01243 ], [ 58.29841, 51.09797 ], [ 58.36807, 51.02613 ], [ 58.5548, 51.00639 ], [ 58.55671, 50.83518 ], [ 58.61717, 50.82102 ], [ 58.63651, 50.76234 ], [ 58.75108, 50.75904 ], [ 58.87397, 50.64752 ], [ 59.40752, 50.5865 ], [ 59.41208, 50.5204 ], [ 59.50366, 50.44446 ], [ 59.83658, 50.49067 ], [ 60.03802, 50.64431 ], [ 60.04013, 50.76267 ], [ 60.14419, 50.78129 ], [ 60.30811, 50.62164 ], [ 60.82497, 50.60673 ], [ 61.4775, 50.76372 ], [ 61.6091, 51.18039 ], [ 61.71087, 51.2122 ], [ 61.73371, 51.27975 ], [ 61.505, 51.45935 ], [ 61.02821, 51.52042 ], [ 60.97324, 51.56357 ], [ 60.9563, 51.66168 ], [ 60.48638, 51.69575 ], [ 60.55666, 51.7417 ], [ 60.55461, 51.83352 ], [ 60.19803, 51.9389 ], [ 60.52283, 52.10175 ], [ 60.74276, 52.11238 ], [ 61.10595, 52.3143 ], [ 61.0192, 52.54008 ], [ 60.90531, 52.56987 ], [ 60.88123, 52.67443 ], [ 60.7726, 52.69768 ], [ 61.16093, 52.94651 ], [ 61.47824, 52.97811 ], [ 61.62182, 52.90428 ], [ 61.7987, 52.94538 ], [ 62.0233, 52.89914 ], [ 62.16733, 52.95498 ], [ 62.19602, 53.05015 ], [ 62.13175, 53.16199 ], [ 61.81359, 53.22919 ], [ 61.70444, 53.30797 ], [ 61.54245, 53.26888 ], [ 61.23391, 53.34354 ], [ 61.28709, 53.45849 ], [ 61.47316, 53.4121 ], [ 61.58914, 53.45228 ], [ 61.64179, 53.52702 ], [ 61.56672, 53.64116 ], [ 61.2198, 53.61791 ], [ 61.11265, 53.6706 ], [ 61.27224, 53.77458 ], [ 61.32252, 54.02155 ], [ 61.43208, 54.02931 ], [ 61.55738, 53.92026 ], [ 61.70177, 53.96783 ], [ 61.93821, 53.8984 ], [ 62.07141, 53.90617 ], [ 62.08669, 53.99158 ], [ 62.3479, 53.98152 ], [ 62.40841, 53.89399 ], [ 62.5166, 53.86345 ], [ 62.62218, 53.93064 ], [ 62.63738, 54.02574 ], [ 63.09202, 54.05401 ], [ 63.23851, 54.14052 ], [ 63.79068, 54.21601 ], [ 63.97411, 54.14977 ], [ 64.10045, 54.25829 ], [ 64.61423, 54.32537 ], [ 64.75536, 54.3044 ], [ 64.95391, 54.36365 ], [ 65.10061, 54.28314 ], [ 65.23567, 54.28547 ], [ 65.31312, 54.35856 ], [ 65.27782, 54.4981 ], [ 65.51136, 54.51945 ], [ 65.55275, 54.58507 ], [ 65.76179, 54.55718 ], [ 65.90964, 54.65084 ], [ 66.01484, 54.57539 ], [ 67.07417, 54.73086 ], [ 67.32834, 54.81538 ], [ 67.69672, 54.81308 ], [ 67.80211, 54.84358 ], [ 67.86256, 54.92386 ], [ 68.24901, 54.92079 ], [ 68.36633, 55.06849 ], [ 68.30415, 55.13647 ], [ 68.64694, 55.15331 ], [ 68.77505, 55.31655 ], [ 69.02836, 55.23811 ], [ 69.03674, 55.37045 ], [ 69.20471, 55.28023 ], [ 69.37966, 55.32359 ], [ 69.48628, 55.28513 ], [ 69.7053, 55.29902 ], [ 69.93304, 55.16394 ], [ 70.20063, 55.09731 ], [ 70.41639, 55.16605 ], [ 70.46601, 55.22237 ], [ 70.76852, 55.23043 ], [ 70.9409, 55.05848 ], [ 70.91112, 54.87317 ], [ 70.99774, 54.74058 ], [ 71.07781, 54.65284 ], [ 71.17515, 54.64735 ], [ 71.12151, 54.5804 ], [ 71.15395, 54.37672 ], [ 70.94941, 54.34494 ], [ 70.95604, 54.24729 ], [ 71.09352, 54.08826 ], [ 71.16922, 54.04168 ], [ 71.35058, 54.12825 ], [ 71.47602, 54.04809 ], [ 71.73271, 54.05468 ], [ 71.81381, 54.12726 ], [ 71.79116, 54.19184 ], [ 71.96843, 54.17919 ], [ 72.19242, 54.0773 ], [ 72.26859, 54.18256 ], [ 72.36464, 54.00627 ], [ 72.32821, 53.92899 ], [ 72.51375, 53.85759 ], [ 72.57601, 53.91939 ], [ 72.73967, 53.92125 ], [ 72.76257, 54.02257 ], [ 72.71928, 54.07208 ], [ 72.92642, 54.04317 ], [ 73.04924, 53.93876 ], [ 73.39994, 53.89362 ], [ 73.30287, 53.81917 ], [ 73.28642, 53.72743 ], [ 73.20671, 53.69327 ], [ 73.19241, 53.55241 ], [ 73.44144, 53.385 ], [ 73.70901, 53.55462 ], [ 73.82959, 53.5285 ], [ 73.93355, 53.59363 ], [ 74.05274, 53.5143 ], [ 74.19647, 53.53673 ], [ 74.25824, 53.45297 ], [ 74.40758, 53.40888 ], [ 74.53481, 53.55444 ], [ 74.50614, 53.6269 ], [ 74.65941, 53.62507 ], [ 74.83088, 53.76654 ], [ 75.07475, 53.74859 ], [ 75.47387, 53.93347 ], [ 75.47389, 54.04444 ], [ 76.20979, 54.20822 ], [ 76.2796, 54.29552 ], [ 76.64382, 54.2847 ], [ 76.74415, 54.34325 ], [ 76.7993, 54.3135 ], [ 76.69981, 54.20269 ], [ 76.40203, 54.19956 ], [ 76.3879, 54.10426 ], [ 76.46503, 53.9997 ], [ 77.87975, 53.24298 ], [ 79.04392, 52.00902 ], [ 80.05173, 50.69358 ], [ 80.24767, 50.84853 ], [ 80.51988, 50.93412 ], [ 80.51989, 51.14206 ], [ 80.6576, 51.16136 ], [ 80.70717, 51.25352 ], [ 81.10698, 51.13065 ], [ 81.01967, 50.91674 ], [ 81.35919, 50.92006 ], [ 81.45208, 50.70372 ], [ 81.89253, 50.7463 ], [ 82.16666, 50.67976 ], [ 82.36827, 50.72346 ], [ 82.56112, 50.69488 ], [ 82.73557, 50.77502 ], [ 82.78288, 50.86773 ], [ 82.98475, 50.83348 ], [ 83.16801, 50.95285 ], [ 83.39428, 50.95179 ], [ 83.89711, 50.76756 ], [ 83.93169, 50.69045 ], [ 84.16214, 50.50008 ], [ 84.20435, 50.27332 ], [ 84.31094, 50.17701 ], [ 84.61849, 50.15736 ], [ 84.94911, 50.02382 ], [ 84.94348, 49.87841 ], [ 85.15354, 49.70814 ], [ 85.16417, 49.60616 ], [ 85.23928, 49.54103 ], [ 85.58158, 49.55187 ], [ 85.67419, 49.49991 ], [ 85.88436, 49.50714 ], [ 85.95551, 49.4376 ], [ 86.09463, 49.47158 ], [ 86.21145, 49.41643 ], [ 86.31924, 49.54148 ], [ 86.444, 49.56335 ], [ 86.58109, 49.66593 ], [ 86.54902, 49.61732 ], [ 86.5778, 49.53995 ], [ 86.77356, 49.5029 ], [ 86.79323, 49.42129 ], [ 86.99838, 49.21372 ], [ 87.23516, 49.18828 ], [ 87.24755, 49.0826 ], [ 87.42123, 49.02101 ], [ 87.71537, 49.12298 ], [ 88.00845, 49.13609 ], [ 88.21125, 49.26367 ], [ 88.23826, 49.42432 ], [ 88.59651, 49.44701 ], [ 88.8494, 49.39079 ], [ 88.92032, 49.44588 ], [ 88.9861, 49.41323 ], [ 89.15498, 49.4515 ], [ 89.25965, 49.50635 ], [ 89.27895, 49.56276 ], [ 89.37528, 49.53596 ], [ 89.75596, 49.69343 ], [ 89.7634, 49.80047 ], [ 89.69338, 49.88559 ], [ 90.00121, 49.92667 ], [ 90.07709, 49.97752 ], [ 90.07877, 50.03075 ], [ 90.29256, 50.05998 ], [ 90.52389, 50.18479 ], [ 90.70322, 50.17162 ], [ 90.77261, 50.21512 ], [ 90.78055, 50.27553 ], [ 90.92677, 50.3018 ], [ 90.97181, 50.37544 ], [ 91.4244, 50.40232 ], [ 91.5069, 50.5069 ], [ 91.67377, 50.54436 ], [ 91.70358, 50.61791 ], [ 91.80652, 50.67285 ], [ 92.08418, 50.64518 ], [ 92.27933, 50.68308 ], [ 92.36371, 50.79781 ], [ 92.43545, 50.74418 ], [ 92.54259, 50.74061 ], [ 92.55869, 50.68319 ], [ 92.63326, 50.6551 ], [ 92.77416, 50.68068 ], [ 92.81338, 50.75551 ], [ 92.96927, 50.74261 ], [ 92.92014, 50.63042 ], [ 92.99199, 50.55842 ], [ 93.11647, 50.53637 ], [ 93.44148, 50.57837 ], [ 93.70001, 50.53328 ], [ 94.23916, 50.53319 ], [ 94.29163, 50.48363 ], [ 94.34909, 50.18726 ], [ 94.45798, 50.14274 ], [ 94.60536, 49.98558 ], [ 94.9497, 49.997 ], [ 95.02491, 49.92501 ], [ 95.4031, 49.90624 ], [ 95.52948, 49.85375 ], [ 95.80041, 49.92778 ], [ 95.85203, 49.98876 ], [ 95.96315, 49.9215 ], [ 96.06126, 49.95682 ], [ 96.23183, 49.9262 ], [ 96.40952, 49.82275 ], [ 96.52829, 49.88244 ], [ 96.6104, 49.82108 ], [ 96.72672, 49.86967 ], [ 96.94036, 49.84157 ], [ 97.21371, 49.69574 ], [ 97.33491, 49.70385 ], [ 97.51801, 49.76273 ], [ 97.60912, 49.81855 ], [ 97.63576, 49.89312 ], [ 97.73767, 49.92475 ], [ 97.81343, 49.8756 ], [ 97.91491, 49.88112 ], [ 98.10534, 49.99953 ], [ 98.35058, 50.29995 ], [ 98.37164, 50.52891 ], [ 98.07766, 50.68434 ], [ 98.02749, 50.77358 ], [ 98.07692, 50.89105 ], [ 97.90421, 51.01184 ], [ 98.01436, 51.31991 ], [ 98.08842, 51.40432 ], [ 98.25657, 51.4186 ], [ 98.29632, 51.56664 ], [ 98.4043, 51.68337 ], [ 98.78829, 51.82535 ], [ 98.9223, 52.09636 ], [ 98.99962, 52.02087 ], [ 99.198, 51.97517 ], [ 99.27698, 51.90741 ], [ 99.72202, 51.85495 ], [ 99.85793, 51.71593 ], [ 100.034, 51.67827 ], [ 100.5598, 51.6847 ], [ 101.1288, 51.47283 ], [ 101.2383, 51.48023 ], [ 101.3556, 51.40426 ], [ 101.5145, 51.44502 ], [ 101.6075, 51.3934 ], [ 102.0795, 51.31954 ], [ 102.0841, 51.1035 ], [ 102.173, 50.97255 ], [ 102.1671, 50.80767 ], [ 102.2637, 50.73078 ], [ 102.2659, 50.64856 ], [ 102.4925, 50.54337 ], [ 102.6371, 50.35583 ], [ 102.9291, 50.25778 ], [ 103.2022, 50.27522 ], [ 103.2185, 50.17473 ], [ 103.2692, 50.14192 ], [ 103.4506, 50.15905 ], [ 103.7202, 50.08042 ], [ 103.8655, 50.13703 ], [ 104.1506, 50.09528 ], [ 104.4205, 50.25897 ], [ 104.816, 50.29484 ], [ 104.9176, 50.35659 ], [ 105.1356, 50.34157 ], [ 105.3358, 50.42247 ], [ 105.9772, 50.36646 ], [ 106.0687, 50.28509 ], [ 106.2522, 50.25273 ], [ 106.6131, 50.2864 ], [ 106.9572, 50.16639 ], [ 107.0553, 50.02044 ], [ 107.2216, 49.94051 ], [ 107.8674, 49.88297 ], [ 107.9188, 49.62664 ], [ 108.2573, 49.48815 ], [ 108.3194, 49.3937 ], [ 108.5228, 49.27065 ], [ 109.1851, 49.30017 ], [ 109.5601, 49.16905 ], [ 110.2016, 49.1031 ], [ 110.3939, 49.18066 ], [ 110.675, 49.11985 ], [ 110.8318, 49.13151 ], [ 111.3795, 49.30048 ], [ 111.535, 49.27253 ], [ 111.6978, 49.33232 ], [ 111.9713, 49.33214 ], [ 112.483, 49.47066 ], [ 112.8329, 49.46813 ], [ 113.0753, 49.56811 ], [ 113.2495, 49.79361 ], [ 114.3339, 50.22572 ], [ 114.8412, 50.16705 ], [ 114.9752, 50.12079 ], [ 115.2067, 49.93925 ], [ 115.5053, 49.85507 ], [ 115.7563, 49.83735 ], [ 116.2382, 49.97786 ], [ 116.5947, 49.88062 ], [ 116.6926, 49.79324 ], [ 117.0505, 49.63472 ], [ 117.8774, 49.45985 ], [ 117.9416, 49.54323 ], [ 118.1871, 49.61285 ], [ 118.6009, 49.87309 ], [ 119.0964, 49.93556 ], [ 119.321, 50.07283 ], [ 119.3992, 50.17526 ], [ 119.4274, 50.32667 ], [ 119.3728, 50.40218 ], [ 119.2828, 50.41416 ], [ 119.3404, 50.57032 ], [ 119.5266, 50.70932 ], [ 119.5779, 50.87959 ], [ 119.7974, 51.06188 ], [ 119.8679, 51.23952 ], [ 120.0398, 51.42882 ], [ 120.0956, 51.59387 ], [ 120.6829, 51.88581 ], [ 120.7452, 51.96097 ], [ 120.8298, 52.15832 ], [ 120.79, 52.28908 ], [ 120.6923, 52.34577 ], [ 120.7762, 52.52516 ], [ 120.7613, 52.57697 ], [ 120.4502, 52.69505 ], [ 120.0884, 52.63744 ], [ 120.1049, 52.73635 ], [ 120.3116, 52.82015 ], [ 120.8901, 53.23289 ], [ 121.2326, 53.22818 ], [ 122.3246, 53.44094 ], [ 122.4353, 53.39169 ], [ 122.8514, 53.40464 ], [ 123.1574, 53.45004 ], [ 123.2722, 53.50785 ], [ 123.47, 53.44685 ], [ 123.6187, 53.48627 ], [ 123.8609, 53.43111 ], [ 124.0983, 53.29736 ], [ 124.2257, 53.31909 ], [ 124.4174, 53.16787 ], [ 124.6538, 53.15172 ], [ 124.8532, 53.05015 ], [ 124.9248, 53.06199 ], [ 124.9538, 53.13363 ], [ 125.1487, 53.15071 ], [ 125.4939, 52.99904 ], [ 125.5857, 53.02373 ], [ 125.6394, 52.96569 ], [ 125.6027, 52.90062 ], [ 125.6314, 52.82388 ], [ 125.803, 52.83892 ], [ 125.9434, 52.70869 ], [ 125.9116, 52.65355 ], [ 125.9399, 52.56955 ], [ 126.1223, 52.51982 ], [ 126.1545, 52.42823 ], [ 126.2816, 52.38269 ], [ 126.2711, 52.16747 ], [ 126.4815, 52.10319 ], [ 126.3914, 52.04517 ], [ 126.4073, 51.93178 ], [ 126.6623, 51.67533 ], [ 126.621, 51.59101 ], [ 126.7484, 51.50534 ], [ 126.7256, 51.43632 ], [ 126.7847, 51.37122 ], [ 126.7585, 51.29761 ], [ 126.8431, 51.19485 ], [ 126.8733, 51.03162 ], [ 127.0839, 50.88711 ], [ 127.2297, 50.71578 ], [ 127.2978, 50.57983 ], [ 127.2364, 50.47953 ], [ 127.2909, 50.39955 ], [ 127.2872, 50.30199 ], [ 127.5453, 50.18689 ], [ 127.4377, 50.01178 ], [ 127.5004, 49.77009 ], [ 127.6156, 49.72548 ], [ 127.6583, 49.62535 ], [ 127.8411, 49.52235 ], [ 128.1806, 49.48504 ], [ 128.5465, 49.54902 ], [ 128.6881, 49.51431 ], [ 128.7491, 49.42439 ], [ 128.9727, 49.40282 ], [ 129.0795, 49.30177 ], [ 129.218, 49.34529 ], [ 129.3668, 49.30406 ], [ 129.4291, 49.38526 ], [ 129.4759, 49.37681 ], [ 129.5408, 49.24043 ], [ 129.6882, 49.24001 ], [ 129.8921, 48.99576 ], [ 130.1979, 48.82225 ], [ 130.4284, 48.85132 ], [ 130.5595, 48.8049 ], [ 130.4748, 48.59328 ], [ 130.5535, 48.54617 ], [ 130.5905, 48.4499 ], [ 130.6787, 48.43887 ], [ 130.7561, 48.30394 ], [ 130.6185, 48.14973 ], [ 130.6074, 48.07632 ], [ 130.841, 47.88329 ], [ 130.9676, 47.65113 ], [ 131.0996, 47.63207 ], [ 131.4507, 47.69047 ], [ 131.5963, 47.60511 ], [ 131.7141, 47.65205 ], [ 131.9638, 47.61171 ], [ 132.3304, 47.70502 ], [ 132.568, 47.66682 ], [ 132.644, 47.71194 ], [ 132.7325, 47.88553 ], [ 132.8258, 47.88361 ], [ 133.0785, 48.05274 ], [ 133.5531, 48.07553 ], [ 133.624, 48.14036 ], [ 133.7354, 48.14429 ], [ 133.7865, 48.20655 ], [ 134.2169, 48.33272 ], [ 134.6858, 48.35052 ], [ 134.4936, 47.98576 ], [ 134.7102, 47.72819 ], [ 134.5187, 47.52034 ], [ 134.2986, 47.48392 ], [ 134.1255, 47.3412 ], [ 134.1005, 47.24881 ], [ 134.1693, 47.15426 ], [ 134.0129, 47.00225 ], [ 133.9657, 46.69141 ], [ 133.7971, 46.49669 ], [ 133.8315, 46.29377 ], [ 133.6469, 46.18546 ], [ 133.6674, 46.0558 ], [ 133.4254, 45.87078 ], [ 133.3554, 45.6264 ], [ 133.1504, 45.54089 ], [ 133.0403, 45.29954 ], [ 133.0559, 45.14931 ], [ 132.9346, 45.08232 ], [ 132.0293, 45.29861 ], [ 131.8762, 45.39202 ], [ 131.7397, 45.27829 ], [ 131.6433, 45.25991 ], [ 131.6028, 45.12862 ], [ 131.4421, 45.02841 ], [ 131.0879, 44.98491 ], [ 130.9201, 44.88378 ], [ 130.917, 44.79406 ], [ 131.0654, 44.65677 ], [ 131.2381, 44.08007 ], [ 131.1856, 43.98994 ], [ 131.1361, 43.55799 ], [ 131.2402, 43.41428 ], [ 131.1481, 43.24203 ], [ 131.1502, 43.15951 ], [ 131.0672, 43.08742 ], [ 131.0517, 42.97433 ], [ 130.9582, 42.91953 ], [ 130.8023, 42.93109 ], [ 130.5421, 42.86199 ], [ 130.3442, 42.73033 ], [ 130.3947, 42.66008 ], [ 130.5583, 42.6077 ], [ 130.5039, 42.50742 ], [ 130.6269, 42.28052 ], [ 130.8987, 42.12396 ], [ 133.2675, 39.96882 ], [ 140.789789, 45.836458 ], [ 142.586054, 45.579449 ], [ 145.596308, 44.66475 ], [ 145.431513, 44.13886 ], [ 145.195307, 43.763164 ], [ 145.493316, 43.534612 ], [ 145.828398, 43.384093 ], [ 146.0519, 43.12595 ], [ 180, 35.61404 ], [ 180, 83.83133 ], [ 37.2795, 83.81215 ], [ 31.27848, 70.11174 ], [ 30.77568, 69.82379 ], [ 30.88567, 69.60134 ], [ 30.54062, 69.59318 ], [ 30.24028, 69.70254 ], [ 30.07925, 69.70996 ], [ 30.04604, 69.62395 ], [ 30.11237, 69.57275 ], [ 30.01001, 69.47197 ], [ 29.84288, 69.47344 ], [ 29.56539, 69.37147 ], [ 29.28577, 69.34884 ], [ 29.18916, 69.14856 ], [ 29.04647, 69.07043 ], [ 28.90818, 69.09988 ], [ 28.36758, 68.92939 ], [ 28.45581, 68.83664 ], [ 28.68857, 68.8165 ], [ 28.38412, 68.5494 ], [ 28.61946, 68.15368 ], [ 29.29281, 68.02793 ], [ 29.62745, 67.76365 ], [ 29.92133, 67.63731 ], [ 29.88819, 67.56283 ], [ 29.04771, 67.04106 ], [ 28.98188, 66.93578 ], [ 29.07125, 66.75276 ], [ 29.43544, 66.50602 ], [ 29.66187, 66.23217 ], [ 29.89118, 66.07974 ], [ 30.06695, 65.74475 ], [ 29.67942, 65.66431 ], [ 29.73666, 65.55009 ], [ 29.68779, 65.49607 ], [ 29.67485, 65.36906 ], [ 29.56924, 65.30861 ], [ 29.55285, 65.24834 ], [ 29.61512, 65.18409 ], [ 29.78282, 65.17332 ], [ 29.59119, 65.09738 ], [ 29.54934, 65.00337 ], [ 29.56488, 64.90444 ], [ 29.70682, 64.7489 ], [ 29.99222, 64.74085 ], [ 30.02651, 64.66196 ], [ 29.94633, 64.6067 ], [ 29.93739, 64.52972 ], [ 30.00522, 64.3703 ], [ 30.42164, 64.21392 ], [ 30.49199, 64.10354 ], [ 30.22901, 63.8715 ], [ 29.9702, 63.81066 ], [ 29.93021, 63.72835 ], [ 30.46048, 63.42266 ], [ 30.77099, 63.35498 ], [ 31.18489, 63.18117 ], [ 31.2423, 63.06728 ], [ 31.49568, 62.90009 ], [ 31.11931, 62.48988 ], [ 30.61954, 62.24558 ], [ 29.69859, 61.61222 ], [ 29.4718, 61.53579 ], [ 29.20748, 61.31401 ], [ 28.79581, 61.16649 ], [ 28.63369, 61.00659 ], [ 28.49232, 60.99797 ], [ 27.85071, 60.65141 ], [ 27.64466, 60.46285 ], [ 27.6426, 60.40344 ], [ 27.4862, 60.30133 ], [ 26.86507, 60.16682 ], [ 26.39009, 59.92985 ], [ 26.91914, 59.57938 ], [ 27.82954, 59.53154 ], [ 28.12685, 59.36757 ], [ 27.88014, 59.28753 ], [ 27.68803, 59.01193 ], [ 27.30915, 58.80412 ], [ 27.48362, 58.38673 ], [ 27.44354, 58.20541 ], [ 27.55825, 58.07796 ], [ 27.63487, 57.89748 ], [ 27.51724, 57.87234 ], [ 27.26678, 57.58119 ], [ 27.33297, 57.47116 ], [ 27.48984, 57.48141 ], [ 27.48489, 57.38802 ], [ 27.80667, 57.26726 ], [ 27.77309, 57.18686 ], [ 27.66903, 57.11764 ], [ 27.68045, 56.96759 ], [ 27.60984, 56.82296 ], [ 27.64703, 56.78608 ], [ 27.84829, 56.81343 ], [ 27.86174, 56.71678 ], [ 28.12917, 56.4235 ], [ 28.11273, 56.37153 ], [ 28.16811, 56.28574 ], [ 28.10297, 56.1868 ], [ 28.11991, 56.1093 ], [ 28.30397, 56.00917 ], [ 28.58389, 56.0545 ], [ 28.72857, 55.91646 ], [ 28.86271, 55.905 ], [ 29.06219, 55.97783 ], [ 29.30575, 55.93635 ], [ 29.34851, 55.92022 ], [ 29.31199, 55.74329 ], [ 29.49395, 55.65306 ], [ 29.68037, 55.7369 ], [ 29.81433, 55.73245 ], [ 29.9147, 55.80383 ], [ 30.12313, 55.78048 ], [ 30.23792, 55.81532 ], [ 30.57809, 55.69633 ], [ 30.63959, 55.59844 ], [ 30.75319, 55.54151 ], [ 30.88151, 55.57085 ], [ 30.85992, 55.41069 ], [ 30.78692, 55.36041 ], [ 30.76885, 55.28175 ], [ 30.93431, 55.09108 ], [ 30.78148, 54.97479 ], [ 30.71476, 54.77384 ], [ 30.91914, 54.69588 ], [ 30.97209, 54.6262 ], [ 31.10248, 54.61217 ], [ 31.03625, 54.49514 ], [ 31.18732, 54.41846 ], [ 31.28732, 54.20322 ], [ 31.80737, 54.02874 ], [ 31.79375, 53.94019 ], [ 31.70897, 53.84793 ], [ 31.73503, 53.7526 ], [ 31.89973, 53.72387 ], [ 32.1166, 53.76006 ], [ 32.3069, 53.70644 ], [ 32.44324, 53.5122 ], [ 32.6811, 53.40566 ], [ 32.46274, 53.34737 ], [ 32.41788, 53.2555 ], [ 32.0986, 53.12929 ], [ 31.85271, 53.16265 ], [ 31.81184, 53.22346 ], [ 31.62667, 53.28143 ], [ 31.38296, 53.25917 ], [ 31.28393, 53.09675 ], [ 31.20669, 53.06964 ], [ 31.20841, 52.98805 ], [ 31.53098, 52.75924 ], [ 31.44993, 52.69603 ], [ 31.52909, 52.56008 ], [ 31.48765, 52.46169 ], [ 31.56666, 52.37409 ], [ 31.54027, 52.29675 ], [ 31.75549, 52.06822 ], [ 31.86193, 52.05565 ], [ 31.90689, 51.99334 ], [ 32.09497, 51.98266 ], [ 32.38992, 52.09939 ], [ 32.44809, 52.27175 ], [ 32.6915, 52.19798 ], [ 32.89863, 52.19427 ], [ 33.21088, 52.32006 ], [ 33.54886, 52.25097 ], [ 33.78861, 52.31255 ], [ 34.03332, 52.12261 ], [ 34.01219, 52.07252 ], [ 34.06314, 51.96613 ], [ 34.21642, 51.84007 ], [ 34.35746, 51.79404 ], [ 34.03453, 51.68698 ], [ 34.05617, 51.62284 ], [ 34.21773, 51.50759 ], [ 34.17101, 51.42194 ], [ 34.22899, 51.34658 ], [ 34.19268, 51.23231 ], [ 34.31097, 51.18884 ], [ 34.60857, 51.19203 ], [ 34.70031, 51.12526 ], [ 35.07328, 51.16195 ], [ 35.12019, 51.04252 ], [ 35.27827, 51.00344 ], [ 35.28067, 50.92582 ], [ 35.41448, 50.73853 ], [ 35.35064, 50.67781 ], [ 35.34606, 50.55788 ], [ 35.59275, 50.31192 ], [ 35.7418, 50.3038 ], [ 35.85155, 50.374 ], [ 36.07715, 50.39531 ], [ 36.27515, 50.24484 ], [ 36.46162, 50.25969 ], [ 36.64995, 50.16646 ], [ 36.88982, 50.28679 ], [ 37.16752, 50.30649 ], [ 37.41356, 50.38116 ], [ 37.57234, 50.255 ], [ 37.61331, 50.13249 ], [ 37.73295, 50.03249 ], [ 37.88199, 49.99718 ], [ 38.01555, 49.85233 ], [ 38.19247, 49.896 ], [ 38.28829, 50.02419 ], [ 38.3358, 49.95768 ], [ 38.65124, 49.90573 ], [ 38.92585, 49.74657 ], [ 39.17134, 49.81935 ], [ 39.25245, 49.71591 ], [ 39.54762, 49.68604 ], [ 39.6294, 49.57456 ], [ 39.79514, 49.50784 ], [ 39.99489, 49.54761 ], [ 39.98036, 49.44172 ], [ 40.1341, 49.31827 ], [ 39.89786, 49.11549 ], [ 39.62763, 49.06151 ], [ 39.64642, 48.95187 ], [ 39.75439, 48.87157 ], [ 39.65966, 48.74513 ], [ 39.61548, 48.58986 ], [ 39.66738, 48.53953 ], [ 39.80232, 48.52768 ], [ 39.79789, 48.45847 ], [ 39.85571, 48.39424 ], [ 39.79521, 48.35044 ], [ 39.79541, 48.28809 ], [ 39.8875, 48.22399 ], [ 39.73231, 48.06436 ], [ 39.76046, 47.97173 ], [ 39.71582, 47.88397 ], [ 38.87402, 47.9262 ], [ 38.74584, 47.84248 ], [ 38.72452, 47.75158 ], [ 38.32055, 47.6572 ], [ 38.2375, 47.56339 ], [ 38.24691, 47.42509 ], [ 38.17056, 47.33226 ], [ 38.17948, 47.11301 ], [ 38.23594, 46.98468 ], [ 38.11227, 46.91138 ], [ 37.62322, 46.88217 ], [ 37.41553, 46.76322 ], [ 36.64303, 45.68821 ], [ 36.33254, 45.72272 ], [ 35.99696, 45.67179 ], [ 35.78323, 45.6953 ], [ 35.5479, 45.57771 ], [ 35.25239, 45.8388 ], [ 34.95522, 45.81513 ], [ 34.86024, 45.85082 ], [ 34.834, 45.94033 ], [ 34.64487, 46.03539 ], [ 34.56099, 46.04619 ], [ 34.48616, 45.99791 ], [ 34.35945, 46.10523 ], [ 33.64373, 46.28118 ], [ 33.57107, 46.24987 ], [ 33.57418, 46.17282 ], [ 33.50204, 46.05619 ], [ 32.76382, 45.87799 ], [ 32.29008, 45.63796 ], [ 32.15053, 45.4186 ], [ 32.24215, 45.18556 ], [ 32.58196, 45.06437 ], [ 32.81426, 45.08492 ], [ 33.1961, 44.89718 ], [ 33.18807, 44.79736 ], [ 33.04632, 44.63244 ], [ 33.08447, 44.45073 ], [ 33.28842, 44.28003 ], [ 33.73338, 44.13411 ], [ 34.25741, 44.18416 ], [ 34.56984, 44.35196 ], [ 34.75216, 44.53336 ], [ 35.19419, 44.54824 ], [ 35.63792, 44.77878 ], [ 35.86723, 44.74156 ], [ 36.3213, 44.7814 ], [ 36.62697, 44.88227 ], [ 36.82653, 44.86342 ], [ 36.99347, 44.80367 ], [ 37.13441, 44.60302 ], [ 37.30884, 44.50028 ], [ 37.72977, 44.41796 ], [ 38.06819, 44.20528 ], [ 38.58442, 44.07787 ], [ 39.0957, 43.73459 ], [ 39.77181, 43.19436 ], [ 39.92102, 43.18958 ], [ 40.14963, 43.51766 ], [ 40.53619, 43.46775 ], [ 40.65366, 43.50114 ], [ 40.9289, 43.37216 ], [ 41.36808, 43.30067 ], [ 41.61549, 43.17233 ], [ 42.04859, 43.13725 ], [ 42.39962, 43.19365 ], [ 42.66235, 43.08262 ], [ 42.73485, 43.1274 ], [ 42.84302, 43.12009 ], [ 43.17041, 42.88863 ], [ 43.54686, 42.81264 ], [ 43.73402, 42.71448 ], [ 43.67202, 42.66099 ], [ 43.67724, 42.59853 ], [ 43.93197, 42.50111 ], [ 44.2535, 42.58062 ], [ 44.3303, 42.66346 ], [ 44.53225, 42.64866 ], [ 44.57483, 42.69518 ], [ 44.69127, 42.69116 ], [ 44.81052, 42.56385 ], [ 44.86958, 42.58652 ], [ 44.92369, 42.69655 ], [ 45.03821, 42.64202 ], [ 45.12851, 42.6547 ], [ 45.32356, 42.47483 ], [ 45.54435, 42.4928 ], [ 45.70059, 42.42948 ], [ 45.68852, 42.34632 ], [ 45.56284, 42.25334 ], [ 45.61474, 42.14678 ], [ 45.77294, 42.05502 ], [ 45.86065, 42.05444 ], [ 45.91019, 41.98434 ], [ 46.20599, 41.9492 ], [ 46.49783, 41.83242 ], [ 46.55742, 41.75878 ], [ 46.72213, 41.77576 ], [ 46.94197, 41.60451 ], [ 46.98537, 41.51775 ], [ 47.10308, 41.50738 ], [ 47.24051, 41.28804 ], [ 47.45024, 41.21199 ] ] ] ] } } osmium-tool-1.17.0/test/extract/polygon-russia-reverse.geojson000066400000000000000000000644171474143067200245730ustar00rootroot00000000000000{ "type": "FeatureCollection", "name": "russia", "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, "features": [ { "type": "Feature", "properties": { "name": "polygon" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 47.45024, 41.21199 ], [ 47.24051, 41.28804 ], [ 47.10308, 41.50738 ], [ 46.98537, 41.51775 ], [ 46.94197, 41.60451 ], [ 46.72213, 41.77576 ], [ 46.55742, 41.75878 ], [ 46.49783, 41.83242 ], [ 46.20599, 41.9492 ], [ 45.91019, 41.98434 ], [ 45.86065, 42.05444 ], [ 45.77294, 42.05502 ], [ 45.61474, 42.14678 ], [ 45.56284, 42.25334 ], [ 45.68852, 42.34632 ], [ 45.70059, 42.42948 ], [ 45.54435, 42.4928 ], [ 45.32356, 42.47483 ], [ 45.12851, 42.6547 ], [ 45.03821, 42.64202 ], [ 44.92369, 42.69655 ], [ 44.86958, 42.58652 ], [ 44.81052, 42.56385 ], [ 44.69127, 42.69116 ], [ 44.57483, 42.69518 ], [ 44.53225, 42.64866 ], [ 44.3303, 42.66346 ], [ 44.2535, 42.58062 ], [ 43.93197, 42.50111 ], [ 43.67724, 42.59853 ], [ 43.67202, 42.66099 ], [ 43.73402, 42.71448 ], [ 43.54686, 42.81264 ], [ 43.17041, 42.88863 ], [ 42.84302, 43.12009 ], [ 42.73485, 43.1274 ], [ 42.66235, 43.08262 ], [ 42.39962, 43.19365 ], [ 42.04859, 43.13725 ], [ 41.61549, 43.17233 ], [ 41.36808, 43.30067 ], [ 40.9289, 43.37216 ], [ 40.65366, 43.50114 ], [ 40.53619, 43.46775 ], [ 40.14963, 43.51766 ], [ 39.92102, 43.18958 ], [ 39.77181, 43.19436 ], [ 39.0957, 43.73459 ], [ 38.58442, 44.07787 ], [ 38.06819, 44.20528 ], [ 37.72977, 44.41796 ], [ 37.30884, 44.50028 ], [ 37.13441, 44.60302 ], [ 36.99347, 44.80367 ], [ 36.82653, 44.86342 ], [ 36.62697, 44.88227 ], [ 36.3213, 44.7814 ], [ 35.86723, 44.74156 ], [ 35.63792, 44.77878 ], [ 35.19419, 44.54824 ], [ 34.75216, 44.53336 ], [ 34.56984, 44.35196 ], [ 34.25741, 44.18416 ], [ 33.73338, 44.13411 ], [ 33.28842, 44.28003 ], [ 33.08447, 44.45073 ], [ 33.04632, 44.63244 ], [ 33.18807, 44.79736 ], [ 33.1961, 44.89718 ], [ 32.81426, 45.08492 ], [ 32.58196, 45.06437 ], [ 32.24215, 45.18556 ], [ 32.15053, 45.4186 ], [ 32.29008, 45.63796 ], [ 32.76382, 45.87799 ], [ 33.50204, 46.05619 ], [ 33.57418, 46.17282 ], [ 33.57107, 46.24987 ], [ 33.64373, 46.28118 ], [ 34.35945, 46.10523 ], [ 34.48616, 45.99791 ], [ 34.56099, 46.04619 ], [ 34.64487, 46.03539 ], [ 34.834, 45.94033 ], [ 34.86024, 45.85082 ], [ 34.95522, 45.81513 ], [ 35.25239, 45.8388 ], [ 35.5479, 45.57771 ], [ 35.78323, 45.6953 ], [ 35.99696, 45.67179 ], [ 36.33254, 45.72272 ], [ 36.64303, 45.68821 ], [ 37.41553, 46.76322 ], [ 37.62322, 46.88217 ], [ 38.11227, 46.91138 ], [ 38.23594, 46.98468 ], [ 38.17948, 47.11301 ], [ 38.17056, 47.33226 ], [ 38.24691, 47.42509 ], [ 38.2375, 47.56339 ], [ 38.32055, 47.6572 ], [ 38.72452, 47.75158 ], [ 38.74584, 47.84248 ], [ 38.87402, 47.9262 ], [ 39.71582, 47.88397 ], [ 39.76046, 47.97173 ], [ 39.73231, 48.06436 ], [ 39.8875, 48.22399 ], [ 39.79541, 48.28809 ], [ 39.79521, 48.35044 ], [ 39.85571, 48.39424 ], [ 39.79789, 48.45847 ], [ 39.80232, 48.52768 ], [ 39.66738, 48.53953 ], [ 39.61548, 48.58986 ], [ 39.65966, 48.74513 ], [ 39.75439, 48.87157 ], [ 39.64642, 48.95187 ], [ 39.62763, 49.06151 ], [ 39.89786, 49.11549 ], [ 40.1341, 49.31827 ], [ 39.98036, 49.44172 ], [ 39.99489, 49.54761 ], [ 39.79514, 49.50784 ], [ 39.6294, 49.57456 ], [ 39.54762, 49.68604 ], [ 39.25245, 49.71591 ], [ 39.17134, 49.81935 ], [ 38.92585, 49.74657 ], [ 38.65124, 49.90573 ], [ 38.3358, 49.95768 ], [ 38.28829, 50.02419 ], [ 38.19247, 49.896 ], [ 38.01555, 49.85233 ], [ 37.88199, 49.99718 ], [ 37.73295, 50.03249 ], [ 37.61331, 50.13249 ], [ 37.57234, 50.255 ], [ 37.41356, 50.38116 ], [ 37.16752, 50.30649 ], [ 36.88982, 50.28679 ], [ 36.64995, 50.16646 ], [ 36.46162, 50.25969 ], [ 36.27515, 50.24484 ], [ 36.07715, 50.39531 ], [ 35.85155, 50.374 ], [ 35.7418, 50.3038 ], [ 35.59275, 50.31192 ], [ 35.34606, 50.55788 ], [ 35.35064, 50.67781 ], [ 35.41448, 50.73853 ], [ 35.28067, 50.92582 ], [ 35.27827, 51.00344 ], [ 35.12019, 51.04252 ], [ 35.07328, 51.16195 ], [ 34.70031, 51.12526 ], [ 34.60857, 51.19203 ], [ 34.31097, 51.18884 ], [ 34.19268, 51.23231 ], [ 34.22899, 51.34658 ], [ 34.17101, 51.42194 ], [ 34.21773, 51.50759 ], [ 34.05617, 51.62284 ], [ 34.03453, 51.68698 ], [ 34.35746, 51.79404 ], [ 34.21642, 51.84007 ], [ 34.06314, 51.96613 ], [ 34.01219, 52.07252 ], [ 34.03332, 52.12261 ], [ 33.78861, 52.31255 ], [ 33.54886, 52.25097 ], [ 33.21088, 52.32006 ], [ 32.89863, 52.19427 ], [ 32.6915, 52.19798 ], [ 32.44809, 52.27175 ], [ 32.38992, 52.09939 ], [ 32.09497, 51.98266 ], [ 31.90689, 51.99334 ], [ 31.86193, 52.05565 ], [ 31.75549, 52.06822 ], [ 31.54027, 52.29675 ], [ 31.56666, 52.37409 ], [ 31.48765, 52.46169 ], [ 31.52909, 52.56008 ], [ 31.44993, 52.69603 ], [ 31.53098, 52.75924 ], [ 31.20841, 52.98805 ], [ 31.20669, 53.06964 ], [ 31.28393, 53.09675 ], [ 31.38296, 53.25917 ], [ 31.62667, 53.28143 ], [ 31.81184, 53.22346 ], [ 31.85271, 53.16265 ], [ 32.0986, 53.12929 ], [ 32.41788, 53.2555 ], [ 32.46274, 53.34737 ], [ 32.6811, 53.40566 ], [ 32.44324, 53.5122 ], [ 32.3069, 53.70644 ], [ 32.1166, 53.76006 ], [ 31.89973, 53.72387 ], [ 31.73503, 53.7526 ], [ 31.70897, 53.84793 ], [ 31.79375, 53.94019 ], [ 31.80737, 54.02874 ], [ 31.28732, 54.20322 ], [ 31.18732, 54.41846 ], [ 31.03625, 54.49514 ], [ 31.10248, 54.61217 ], [ 30.97209, 54.6262 ], [ 30.91914, 54.69588 ], [ 30.71476, 54.77384 ], [ 30.78148, 54.97479 ], [ 30.93431, 55.09108 ], [ 30.76885, 55.28175 ], [ 30.78692, 55.36041 ], [ 30.85992, 55.41069 ], [ 30.88151, 55.57085 ], [ 30.75319, 55.54151 ], [ 30.63959, 55.59844 ], [ 30.57809, 55.69633 ], [ 30.23792, 55.81532 ], [ 30.12313, 55.78048 ], [ 29.9147, 55.80383 ], [ 29.81433, 55.73245 ], [ 29.68037, 55.7369 ], [ 29.49395, 55.65306 ], [ 29.31199, 55.74329 ], [ 29.34851, 55.92022 ], [ 29.30575, 55.93635 ], [ 29.06219, 55.97783 ], [ 28.86271, 55.905 ], [ 28.72857, 55.91646 ], [ 28.58389, 56.0545 ], [ 28.30397, 56.00917 ], [ 28.11991, 56.1093 ], [ 28.10297, 56.1868 ], [ 28.16811, 56.28574 ], [ 28.11273, 56.37153 ], [ 28.12917, 56.4235 ], [ 27.86174, 56.71678 ], [ 27.84829, 56.81343 ], [ 27.64703, 56.78608 ], [ 27.60984, 56.82296 ], [ 27.68045, 56.96759 ], [ 27.66903, 57.11764 ], [ 27.77309, 57.18686 ], [ 27.80667, 57.26726 ], [ 27.48489, 57.38802 ], [ 27.48984, 57.48141 ], [ 27.33297, 57.47116 ], [ 27.26678, 57.58119 ], [ 27.51724, 57.87234 ], [ 27.63487, 57.89748 ], [ 27.55825, 58.07796 ], [ 27.44354, 58.20541 ], [ 27.48362, 58.38673 ], [ 27.30915, 58.80412 ], [ 27.68803, 59.01193 ], [ 27.88014, 59.28753 ], [ 28.12685, 59.36757 ], [ 27.82954, 59.53154 ], [ 26.91914, 59.57938 ], [ 26.39009, 59.92985 ], [ 26.86507, 60.16682 ], [ 27.4862, 60.30133 ], [ 27.6426, 60.40344 ], [ 27.64466, 60.46285 ], [ 27.85071, 60.65141 ], [ 28.49232, 60.99797 ], [ 28.63369, 61.00659 ], [ 28.79581, 61.16649 ], [ 29.20748, 61.31401 ], [ 29.4718, 61.53579 ], [ 29.69859, 61.61222 ], [ 30.61954, 62.24558 ], [ 31.11931, 62.48988 ], [ 31.49568, 62.90009 ], [ 31.2423, 63.06728 ], [ 31.18489, 63.18117 ], [ 30.77099, 63.35498 ], [ 30.46048, 63.42266 ], [ 29.93021, 63.72835 ], [ 29.9702, 63.81066 ], [ 30.22901, 63.8715 ], [ 30.49199, 64.10354 ], [ 30.42164, 64.21392 ], [ 30.00522, 64.3703 ], [ 29.93739, 64.52972 ], [ 29.94633, 64.6067 ], [ 30.02651, 64.66196 ], [ 29.99222, 64.74085 ], [ 29.70682, 64.7489 ], [ 29.56488, 64.90444 ], [ 29.54934, 65.00337 ], [ 29.59119, 65.09738 ], [ 29.78282, 65.17332 ], [ 29.61512, 65.18409 ], [ 29.55285, 65.24834 ], [ 29.56924, 65.30861 ], [ 29.67485, 65.36906 ], [ 29.68779, 65.49607 ], [ 29.73666, 65.55009 ], [ 29.67942, 65.66431 ], [ 30.06695, 65.74475 ], [ 29.89118, 66.07974 ], [ 29.66187, 66.23217 ], [ 29.43544, 66.50602 ], [ 29.07125, 66.75276 ], [ 28.98188, 66.93578 ], [ 29.04771, 67.04106 ], [ 29.88819, 67.56283 ], [ 29.92133, 67.63731 ], [ 29.62745, 67.76365 ], [ 29.29281, 68.02793 ], [ 28.61946, 68.15368 ], [ 28.38412, 68.5494 ], [ 28.68857, 68.8165 ], [ 28.45581, 68.83664 ], [ 28.36758, 68.92939 ], [ 28.90818, 69.09988 ], [ 29.04647, 69.07043 ], [ 29.18916, 69.14856 ], [ 29.28577, 69.34884 ], [ 29.56539, 69.37147 ], [ 29.84288, 69.47344 ], [ 30.01001, 69.47197 ], [ 30.11237, 69.57275 ], [ 30.04604, 69.62395 ], [ 30.07925, 69.70996 ], [ 30.24028, 69.70254 ], [ 30.54062, 69.59318 ], [ 30.88567, 69.60134 ], [ 30.77568, 69.82379 ], [ 31.27848, 70.11174 ], [ 37.2795, 83.81215 ], [ 180.0, 83.83133 ], [ 180.0, 35.61404 ], [ 146.0519, 43.12595 ], [ 145.828398, 43.384093 ], [ 145.493316, 43.534612 ], [ 145.195307, 43.763164 ], [ 145.431513, 44.13886 ], [ 145.596308, 44.66475 ], [ 142.586054, 45.579449 ], [ 140.789789, 45.836458 ], [ 133.2675, 39.96882 ], [ 130.8987, 42.12396 ], [ 130.6269, 42.28052 ], [ 130.5039, 42.50742 ], [ 130.5583, 42.6077 ], [ 130.3947, 42.66008 ], [ 130.3442, 42.73033 ], [ 130.5421, 42.86199 ], [ 130.8023, 42.93109 ], [ 130.9582, 42.91953 ], [ 131.0517, 42.97433 ], [ 131.0672, 43.08742 ], [ 131.1502, 43.15951 ], [ 131.1481, 43.24203 ], [ 131.2402, 43.41428 ], [ 131.1361, 43.55799 ], [ 131.1856, 43.98994 ], [ 131.2381, 44.08007 ], [ 131.0654, 44.65677 ], [ 130.917, 44.79406 ], [ 130.9201, 44.88378 ], [ 131.0879, 44.98491 ], [ 131.4421, 45.02841 ], [ 131.6028, 45.12862 ], [ 131.6433, 45.25991 ], [ 131.7397, 45.27829 ], [ 131.8762, 45.39202 ], [ 132.0293, 45.29861 ], [ 132.9346, 45.08232 ], [ 133.0559, 45.14931 ], [ 133.0403, 45.29954 ], [ 133.1504, 45.54089 ], [ 133.3554, 45.6264 ], [ 133.4254, 45.87078 ], [ 133.6674, 46.0558 ], [ 133.6469, 46.18546 ], [ 133.8315, 46.29377 ], [ 133.7971, 46.49669 ], [ 133.9657, 46.69141 ], [ 134.0129, 47.00225 ], [ 134.1693, 47.15426 ], [ 134.1005, 47.24881 ], [ 134.1255, 47.3412 ], [ 134.2986, 47.48392 ], [ 134.5187, 47.52034 ], [ 134.7102, 47.72819 ], [ 134.4936, 47.98576 ], [ 134.6858, 48.35052 ], [ 134.2169, 48.33272 ], [ 133.7865, 48.20655 ], [ 133.7354, 48.14429 ], [ 133.624, 48.14036 ], [ 133.5531, 48.07553 ], [ 133.0785, 48.05274 ], [ 132.8258, 47.88361 ], [ 132.7325, 47.88553 ], [ 132.644, 47.71194 ], [ 132.568, 47.66682 ], [ 132.3304, 47.70502 ], [ 131.9638, 47.61171 ], [ 131.7141, 47.65205 ], [ 131.5963, 47.60511 ], [ 131.4507, 47.69047 ], [ 131.0996, 47.63207 ], [ 130.9676, 47.65113 ], [ 130.841, 47.88329 ], [ 130.6074, 48.07632 ], [ 130.6185, 48.14973 ], [ 130.7561, 48.30394 ], [ 130.6787, 48.43887 ], [ 130.5905, 48.4499 ], [ 130.5535, 48.54617 ], [ 130.4748, 48.59328 ], [ 130.5595, 48.8049 ], [ 130.4284, 48.85132 ], [ 130.1979, 48.82225 ], [ 129.8921, 48.99576 ], [ 129.6882, 49.24001 ], [ 129.5408, 49.24043 ], [ 129.4759, 49.37681 ], [ 129.4291, 49.38526 ], [ 129.3668, 49.30406 ], [ 129.218, 49.34529 ], [ 129.0795, 49.30177 ], [ 128.9727, 49.40282 ], [ 128.7491, 49.42439 ], [ 128.6881, 49.51431 ], [ 128.5465, 49.54902 ], [ 128.1806, 49.48504 ], [ 127.8411, 49.52235 ], [ 127.6583, 49.62535 ], [ 127.6156, 49.72548 ], [ 127.5004, 49.77009 ], [ 127.4377, 50.01178 ], [ 127.5453, 50.18689 ], [ 127.2872, 50.30199 ], [ 127.2909, 50.39955 ], [ 127.2364, 50.47953 ], [ 127.2978, 50.57983 ], [ 127.2297, 50.71578 ], [ 127.0839, 50.88711 ], [ 126.8733, 51.03162 ], [ 126.8431, 51.19485 ], [ 126.7585, 51.29761 ], [ 126.7847, 51.37122 ], [ 126.7256, 51.43632 ], [ 126.7484, 51.50534 ], [ 126.621, 51.59101 ], [ 126.6623, 51.67533 ], [ 126.4073, 51.93178 ], [ 126.3914, 52.04517 ], [ 126.4815, 52.10319 ], [ 126.2711, 52.16747 ], [ 126.2816, 52.38269 ], [ 126.1545, 52.42823 ], [ 126.1223, 52.51982 ], [ 125.9399, 52.56955 ], [ 125.9116, 52.65355 ], [ 125.9434, 52.70869 ], [ 125.803, 52.83892 ], [ 125.6314, 52.82388 ], [ 125.6027, 52.90062 ], [ 125.6394, 52.96569 ], [ 125.5857, 53.02373 ], [ 125.4939, 52.99904 ], [ 125.1487, 53.15071 ], [ 124.9538, 53.13363 ], [ 124.9248, 53.06199 ], [ 124.8532, 53.05015 ], [ 124.6538, 53.15172 ], [ 124.4174, 53.16787 ], [ 124.2257, 53.31909 ], [ 124.0983, 53.29736 ], [ 123.8609, 53.43111 ], [ 123.6187, 53.48627 ], [ 123.47, 53.44685 ], [ 123.2722, 53.50785 ], [ 123.1574, 53.45004 ], [ 122.8514, 53.40464 ], [ 122.4353, 53.39169 ], [ 122.3246, 53.44094 ], [ 121.2326, 53.22818 ], [ 120.8901, 53.23289 ], [ 120.3116, 52.82015 ], [ 120.1049, 52.73635 ], [ 120.0884, 52.63744 ], [ 120.4502, 52.69505 ], [ 120.7613, 52.57697 ], [ 120.7762, 52.52516 ], [ 120.6923, 52.34577 ], [ 120.79, 52.28908 ], [ 120.8298, 52.15832 ], [ 120.7452, 51.96097 ], [ 120.6829, 51.88581 ], [ 120.0956, 51.59387 ], [ 120.0398, 51.42882 ], [ 119.8679, 51.23952 ], [ 119.7974, 51.06188 ], [ 119.5779, 50.87959 ], [ 119.5266, 50.70932 ], [ 119.3404, 50.57032 ], [ 119.2828, 50.41416 ], [ 119.3728, 50.40218 ], [ 119.4274, 50.32667 ], [ 119.3992, 50.17526 ], [ 119.321, 50.07283 ], [ 119.0964, 49.93556 ], [ 118.6009, 49.87309 ], [ 118.1871, 49.61285 ], [ 117.9416, 49.54323 ], [ 117.8774, 49.45985 ], [ 117.0505, 49.63472 ], [ 116.6926, 49.79324 ], [ 116.5947, 49.88062 ], [ 116.2382, 49.97786 ], [ 115.7563, 49.83735 ], [ 115.5053, 49.85507 ], [ 115.2067, 49.93925 ], [ 114.9752, 50.12079 ], [ 114.8412, 50.16705 ], [ 114.3339, 50.22572 ], [ 113.2495, 49.79361 ], [ 113.0753, 49.56811 ], [ 112.8329, 49.46813 ], [ 112.483, 49.47066 ], [ 111.9713, 49.33214 ], [ 111.6978, 49.33232 ], [ 111.535, 49.27253 ], [ 111.3795, 49.30048 ], [ 110.8318, 49.13151 ], [ 110.675, 49.11985 ], [ 110.3939, 49.18066 ], [ 110.2016, 49.1031 ], [ 109.5601, 49.16905 ], [ 109.1851, 49.30017 ], [ 108.5228, 49.27065 ], [ 108.3194, 49.3937 ], [ 108.2573, 49.48815 ], [ 107.9188, 49.62664 ], [ 107.8674, 49.88297 ], [ 107.2216, 49.94051 ], [ 107.0553, 50.02044 ], [ 106.9572, 50.16639 ], [ 106.6131, 50.2864 ], [ 106.2522, 50.25273 ], [ 106.0687, 50.28509 ], [ 105.9772, 50.36646 ], [ 105.3358, 50.42247 ], [ 105.1356, 50.34157 ], [ 104.9176, 50.35659 ], [ 104.816, 50.29484 ], [ 104.4205, 50.25897 ], [ 104.1506, 50.09528 ], [ 103.8655, 50.13703 ], [ 103.7202, 50.08042 ], [ 103.4506, 50.15905 ], [ 103.2692, 50.14192 ], [ 103.2185, 50.17473 ], [ 103.2022, 50.27522 ], [ 102.9291, 50.25778 ], [ 102.6371, 50.35583 ], [ 102.4925, 50.54337 ], [ 102.2659, 50.64856 ], [ 102.2637, 50.73078 ], [ 102.1671, 50.80767 ], [ 102.173, 50.97255 ], [ 102.0841, 51.1035 ], [ 102.0795, 51.31954 ], [ 101.6075, 51.3934 ], [ 101.5145, 51.44502 ], [ 101.3556, 51.40426 ], [ 101.2383, 51.48023 ], [ 101.1288, 51.47283 ], [ 100.5598, 51.6847 ], [ 100.034, 51.67827 ], [ 99.85793, 51.71593 ], [ 99.72202, 51.85495 ], [ 99.27698, 51.90741 ], [ 99.198, 51.97517 ], [ 98.99962, 52.02087 ], [ 98.9223, 52.09636 ], [ 98.78829, 51.82535 ], [ 98.4043, 51.68337 ], [ 98.29632, 51.56664 ], [ 98.25657, 51.4186 ], [ 98.08842, 51.40432 ], [ 98.01436, 51.31991 ], [ 97.90421, 51.01184 ], [ 98.07692, 50.89105 ], [ 98.02749, 50.77358 ], [ 98.07766, 50.68434 ], [ 98.37164, 50.52891 ], [ 98.35058, 50.29995 ], [ 98.10534, 49.99953 ], [ 97.91491, 49.88112 ], [ 97.81343, 49.8756 ], [ 97.73767, 49.92475 ], [ 97.63576, 49.89312 ], [ 97.60912, 49.81855 ], [ 97.51801, 49.76273 ], [ 97.33491, 49.70385 ], [ 97.21371, 49.69574 ], [ 96.94036, 49.84157 ], [ 96.72672, 49.86967 ], [ 96.6104, 49.82108 ], [ 96.52829, 49.88244 ], [ 96.40952, 49.82275 ], [ 96.23183, 49.9262 ], [ 96.06126, 49.95682 ], [ 95.96315, 49.9215 ], [ 95.85203, 49.98876 ], [ 95.80041, 49.92778 ], [ 95.52948, 49.85375 ], [ 95.4031, 49.90624 ], [ 95.02491, 49.92501 ], [ 94.9497, 49.997 ], [ 94.60536, 49.98558 ], [ 94.45798, 50.14274 ], [ 94.34909, 50.18726 ], [ 94.29163, 50.48363 ], [ 94.23916, 50.53319 ], [ 93.70001, 50.53328 ], [ 93.44148, 50.57837 ], [ 93.11647, 50.53637 ], [ 92.99199, 50.55842 ], [ 92.92014, 50.63042 ], [ 92.96927, 50.74261 ], [ 92.81338, 50.75551 ], [ 92.77416, 50.68068 ], [ 92.63326, 50.6551 ], [ 92.55869, 50.68319 ], [ 92.54259, 50.74061 ], [ 92.43545, 50.74418 ], [ 92.36371, 50.79781 ], [ 92.27933, 50.68308 ], [ 92.08418, 50.64518 ], [ 91.80652, 50.67285 ], [ 91.70358, 50.61791 ], [ 91.67377, 50.54436 ], [ 91.5069, 50.5069 ], [ 91.4244, 50.40232 ], [ 90.97181, 50.37544 ], [ 90.92677, 50.3018 ], [ 90.78055, 50.27553 ], [ 90.77261, 50.21512 ], [ 90.70322, 50.17162 ], [ 90.52389, 50.18479 ], [ 90.29256, 50.05998 ], [ 90.07877, 50.03075 ], [ 90.07709, 49.97752 ], [ 90.00121, 49.92667 ], [ 89.69338, 49.88559 ], [ 89.7634, 49.80047 ], [ 89.75596, 49.69343 ], [ 89.37528, 49.53596 ], [ 89.27895, 49.56276 ], [ 89.25965, 49.50635 ], [ 89.15498, 49.4515 ], [ 88.9861, 49.41323 ], [ 88.92032, 49.44588 ], [ 88.8494, 49.39079 ], [ 88.59651, 49.44701 ], [ 88.23826, 49.42432 ], [ 88.21125, 49.26367 ], [ 88.00845, 49.13609 ], [ 87.71537, 49.12298 ], [ 87.42123, 49.02101 ], [ 87.24755, 49.0826 ], [ 87.23516, 49.18828 ], [ 86.99838, 49.21372 ], [ 86.79323, 49.42129 ], [ 86.77356, 49.5029 ], [ 86.5778, 49.53995 ], [ 86.54902, 49.61732 ], [ 86.58109, 49.66593 ], [ 86.444, 49.56335 ], [ 86.31924, 49.54148 ], [ 86.21145, 49.41643 ], [ 86.09463, 49.47158 ], [ 85.95551, 49.4376 ], [ 85.88436, 49.50714 ], [ 85.67419, 49.49991 ], [ 85.58158, 49.55187 ], [ 85.23928, 49.54103 ], [ 85.16417, 49.60616 ], [ 85.15354, 49.70814 ], [ 84.94348, 49.87841 ], [ 84.94911, 50.02382 ], [ 84.61849, 50.15736 ], [ 84.31094, 50.17701 ], [ 84.20435, 50.27332 ], [ 84.16214, 50.50008 ], [ 83.93169, 50.69045 ], [ 83.89711, 50.76756 ], [ 83.39428, 50.95179 ], [ 83.16801, 50.95285 ], [ 82.98475, 50.83348 ], [ 82.78288, 50.86773 ], [ 82.73557, 50.77502 ], [ 82.56112, 50.69488 ], [ 82.36827, 50.72346 ], [ 82.16666, 50.67976 ], [ 81.89253, 50.7463 ], [ 81.45208, 50.70372 ], [ 81.35919, 50.92006 ], [ 81.01967, 50.91674 ], [ 81.10698, 51.13065 ], [ 80.70717, 51.25352 ], [ 80.6576, 51.16136 ], [ 80.51989, 51.14206 ], [ 80.51988, 50.93412 ], [ 80.24767, 50.84853 ], [ 80.05173, 50.69358 ], [ 79.04392, 52.00902 ], [ 77.87975, 53.24298 ], [ 76.46503, 53.9997 ], [ 76.3879, 54.10426 ], [ 76.40203, 54.19956 ], [ 76.69981, 54.20269 ], [ 76.7993, 54.3135 ], [ 76.74415, 54.34325 ], [ 76.64382, 54.2847 ], [ 76.2796, 54.29552 ], [ 76.20979, 54.20822 ], [ 75.47389, 54.04444 ], [ 75.47387, 53.93347 ], [ 75.07475, 53.74859 ], [ 74.83088, 53.76654 ], [ 74.65941, 53.62507 ], [ 74.50614, 53.6269 ], [ 74.53481, 53.55444 ], [ 74.40758, 53.40888 ], [ 74.25824, 53.45297 ], [ 74.19647, 53.53673 ], [ 74.05274, 53.5143 ], [ 73.93355, 53.59363 ], [ 73.82959, 53.5285 ], [ 73.70901, 53.55462 ], [ 73.44144, 53.385 ], [ 73.19241, 53.55241 ], [ 73.20671, 53.69327 ], [ 73.28642, 53.72743 ], [ 73.30287, 53.81917 ], [ 73.39994, 53.89362 ], [ 73.04924, 53.93876 ], [ 72.92642, 54.04317 ], [ 72.71928, 54.07208 ], [ 72.76257, 54.02257 ], [ 72.73967, 53.92125 ], [ 72.57601, 53.91939 ], [ 72.51375, 53.85759 ], [ 72.32821, 53.92899 ], [ 72.36464, 54.00627 ], [ 72.26859, 54.18256 ], [ 72.19242, 54.0773 ], [ 71.96843, 54.17919 ], [ 71.79116, 54.19184 ], [ 71.81381, 54.12726 ], [ 71.73271, 54.05468 ], [ 71.47602, 54.04809 ], [ 71.35058, 54.12825 ], [ 71.16922, 54.04168 ], [ 71.09352, 54.08826 ], [ 70.95604, 54.24729 ], [ 70.94941, 54.34494 ], [ 71.15395, 54.37672 ], [ 71.12151, 54.5804 ], [ 71.17515, 54.64735 ], [ 71.07781, 54.65284 ], [ 70.99774, 54.74058 ], [ 70.91112, 54.87317 ], [ 70.9409, 55.05848 ], [ 70.76852, 55.23043 ], [ 70.46601, 55.22237 ], [ 70.41639, 55.16605 ], [ 70.20063, 55.09731 ], [ 69.93304, 55.16394 ], [ 69.7053, 55.29902 ], [ 69.48628, 55.28513 ], [ 69.37966, 55.32359 ], [ 69.20471, 55.28023 ], [ 69.03674, 55.37045 ], [ 69.02836, 55.23811 ], [ 68.77505, 55.31655 ], [ 68.64694, 55.15331 ], [ 68.30415, 55.13647 ], [ 68.36633, 55.06849 ], [ 68.24901, 54.92079 ], [ 67.86256, 54.92386 ], [ 67.80211, 54.84358 ], [ 67.69672, 54.81308 ], [ 67.32834, 54.81538 ], [ 67.07417, 54.73086 ], [ 66.01484, 54.57539 ], [ 65.90964, 54.65084 ], [ 65.76179, 54.55718 ], [ 65.55275, 54.58507 ], [ 65.51136, 54.51945 ], [ 65.27782, 54.4981 ], [ 65.31312, 54.35856 ], [ 65.23567, 54.28547 ], [ 65.10061, 54.28314 ], [ 64.95391, 54.36365 ], [ 64.75536, 54.3044 ], [ 64.61423, 54.32537 ], [ 64.10045, 54.25829 ], [ 63.97411, 54.14977 ], [ 63.79068, 54.21601 ], [ 63.23851, 54.14052 ], [ 63.09202, 54.05401 ], [ 62.63738, 54.02574 ], [ 62.62218, 53.93064 ], [ 62.5166, 53.86345 ], [ 62.40841, 53.89399 ], [ 62.3479, 53.98152 ], [ 62.08669, 53.99158 ], [ 62.07141, 53.90617 ], [ 61.93821, 53.8984 ], [ 61.70177, 53.96783 ], [ 61.55738, 53.92026 ], [ 61.43208, 54.02931 ], [ 61.32252, 54.02155 ], [ 61.27224, 53.77458 ], [ 61.11265, 53.6706 ], [ 61.2198, 53.61791 ], [ 61.56672, 53.64116 ], [ 61.64179, 53.52702 ], [ 61.58914, 53.45228 ], [ 61.47316, 53.4121 ], [ 61.28709, 53.45849 ], [ 61.23391, 53.34354 ], [ 61.54245, 53.26888 ], [ 61.70444, 53.30797 ], [ 61.81359, 53.22919 ], [ 62.13175, 53.16199 ], [ 62.19602, 53.05015 ], [ 62.16733, 52.95498 ], [ 62.0233, 52.89914 ], [ 61.7987, 52.94538 ], [ 61.62182, 52.90428 ], [ 61.47824, 52.97811 ], [ 61.16093, 52.94651 ], [ 60.7726, 52.69768 ], [ 60.88123, 52.67443 ], [ 60.90531, 52.56987 ], [ 61.0192, 52.54008 ], [ 61.10595, 52.3143 ], [ 60.74276, 52.11238 ], [ 60.52283, 52.10175 ], [ 60.19803, 51.9389 ], [ 60.55461, 51.83352 ], [ 60.55666, 51.7417 ], [ 60.48638, 51.69575 ], [ 60.9563, 51.66168 ], [ 60.97324, 51.56357 ], [ 61.02821, 51.52042 ], [ 61.505, 51.45935 ], [ 61.73371, 51.27975 ], [ 61.71087, 51.2122 ], [ 61.6091, 51.18039 ], [ 61.4775, 50.76372 ], [ 60.82497, 50.60673 ], [ 60.30811, 50.62164 ], [ 60.14419, 50.78129 ], [ 60.04013, 50.76267 ], [ 60.03802, 50.64431 ], [ 59.83658, 50.49067 ], [ 59.50366, 50.44446 ], [ 59.41208, 50.5204 ], [ 59.40752, 50.5865 ], [ 58.87397, 50.64752 ], [ 58.75108, 50.75904 ], [ 58.63651, 50.76234 ], [ 58.61717, 50.82102 ], [ 58.55671, 50.83518 ], [ 58.5548, 51.00639 ], [ 58.36807, 51.02613 ], [ 58.29841, 51.09797 ], [ 58.16644, 51.01243 ], [ 57.81701, 51.06097 ], [ 57.79196, 50.87955 ], [ 57.57432, 50.88038 ], [ 57.50648, 50.82501 ], [ 57.2991, 50.89787 ], [ 57.16343, 51.04051 ], [ 56.77757, 51.03494 ], [ 56.79957, 50.96934 ], [ 56.71622, 50.92326 ], [ 56.51267, 51.00062 ], [ 56.49571, 50.9305 ], [ 56.37383, 50.8525 ], [ 56.2094, 50.861 ], [ 56.17464, 50.72225 ], [ 56.08227, 50.65105 ], [ 55.71887, 50.49804 ], [ 55.47464, 50.61864 ], [ 55.36266, 50.60933 ], [ 55.02561, 50.77932 ], [ 55.02412, 50.85762 ], [ 54.65958, 50.97017 ], [ 54.74457, 50.91284 ], [ 54.72781, 50.8079 ], [ 54.78157, 50.61327 ], [ 54.64616, 50.49797 ], [ 54.54151, 50.47668 ], [ 54.36506, 50.61075 ], [ 54.42749, 50.80938 ], [ 54.17041, 50.92215 ], [ 54.08016, 51.06506 ], [ 53.99397, 51.1117 ], [ 53.63629, 51.18537 ], [ 53.55134, 51.28157 ], [ 53.53716, 51.3739 ], [ 53.22514, 51.45484 ], [ 52.94984, 51.40401 ], [ 52.78196, 51.44728 ], [ 52.54097, 51.40815 ], [ 52.31873, 51.68726 ], [ 52.09789, 51.60852 ], [ 51.90648, 51.62539 ], [ 51.84275, 51.56811 ], [ 51.85604, 51.46959 ], [ 51.63571, 51.40443 ], [ 51.58176, 51.45817 ], [ 51.26264, 51.44307 ], [ 51.19473, 51.52671 ], [ 51.23949, 51.62827 ], [ 50.87969, 51.63323 ], [ 50.84618, 51.54813 ], [ 50.76797, 51.52409 ], [ 50.62893, 51.56545 ], [ 50.59199, 51.43686 ], [ 50.43973, 51.36955 ], [ 50.38884, 51.28291 ], [ 50.02016, 51.19171 ], [ 49.77528, 51.05602 ], [ 49.46337, 51.05153 ], [ 49.43494, 51.00972 ], [ 49.49517, 50.88162 ], [ 49.45624, 50.81043 ], [ 49.14368, 50.73163 ], [ 48.83899, 50.54948 ], [ 48.71294, 50.54935 ], [ 48.77469, 50.29923 ], [ 48.95297, 50.02451 ], [ 48.76092, 49.87291 ], [ 48.4479, 49.75097 ], [ 48.20312, 49.82278 ], [ 48.05998, 50.05301 ], [ 47.89502, 50.20414 ], [ 47.59166, 50.40748 ], [ 47.51007, 50.37976 ], [ 47.36594, 50.27447 ], [ 47.38377, 50.05208 ], [ 47.19074, 49.88336 ], [ 46.94498, 49.81672 ], [ 46.85039, 49.38503 ], [ 47.0187, 49.27955 ], [ 47.09872, 49.14378 ], [ 47.0122, 48.9948 ], [ 46.80537, 48.89006 ], [ 46.59034, 48.46934 ], [ 47.15755, 48.3071 ], [ 47.17553, 48.15345 ], [ 47.26121, 48.07877 ], [ 47.14475, 47.95903 ], [ 47.22767, 47.87353 ], [ 47.23594, 47.80066 ], [ 47.35203, 47.76545 ], [ 47.41085, 47.8885 ], [ 47.66885, 47.80996 ], [ 48.04813, 47.81218 ], [ 48.23329, 47.7388 ], [ 48.46943, 47.47112 ], [ 48.56782, 47.43402 ], [ 49.04755, 46.75114 ], [ 48.92563, 46.6427 ], [ 48.62393, 46.65237 ], [ 49.19315, 46.4275 ], [ 49.52308, 46.24281 ], [ 49.71829, 46.23479 ], [ 49.93666, 46.04634 ], [ 49.11256, 45.65282 ], [ 49.01144, 45.47855 ], [ 48.86567, 45.38544 ], [ 48.67183, 45.35084 ], [ 48.27987, 45.40203 ], [ 48.05696, 45.24572 ], [ 47.64786, 45.15848 ], [ 47.37386, 44.72613 ], [ 47.59802, 44.74029 ], [ 47.78865, 44.65814 ], [ 47.89509, 44.44452 ], [ 47.8084, 44.24603 ], [ 48.04129, 44.20116 ], [ 48.1644, 44.09189 ], [ 48.19536, 43.98996 ], [ 48.16466, 43.87705 ], [ 47.89469, 43.61146 ], [ 47.85146, 43.47209 ], [ 47.88465, 43.29552 ], [ 47.84597, 43.11901 ], [ 47.97945, 42.99383 ], [ 48.23971, 42.57976 ], [ 48.60773, 42.16834 ], [ 48.86453, 41.95753 ], [ 48.62989, 41.80192 ], [ 48.41078, 41.55137 ], [ 48.1129, 41.44532 ], [ 47.90696, 41.17502 ], [ 47.77601, 41.1355 ], [ 47.63965, 41.17394 ], [ 47.55554, 41.14866 ], [ 47.45024, 41.21199 ] ] ], [ [ [ -180.0, 72.2916 ], [ -169.907891, 72.234092 ], [ -168.684085, 65.990095 ], [ -168.725284, 65.414875 ], [ -172.074188, 64.033556 ], [ -180.0, 62.26134 ], [ -180.0, 72.29053 ], [ -180.0, 72.2916 ] ] ], [ [ [ 22.22727, 54.33593 ], [ 21.44629, 54.31282 ], [ 21.37827, 54.32501 ], [ 21.26116, 54.32314 ], [ 20.74068, 54.36326 ], [ 20.63083, 54.3604 ], [ 20.58391, 54.37189 ], [ 20.33136, 54.39511 ], [ 19.64733, 54.44727 ], [ 19.40837, 54.61169 ], [ 19.50858, 54.68355 ], [ 19.58461, 54.77262 ], [ 19.57351, 54.86918 ], [ 19.58918, 54.95461 ], [ 19.63488, 55.02533 ], [ 19.72775, 55.10661 ], [ 19.82198, 55.14569 ], [ 19.9205, 55.16401 ], [ 20.20131, 55.16615 ], [ 20.39793, 55.18633 ], [ 20.65365, 55.3899 ], [ 20.95439, 55.28694 ], [ 21.09934, 55.26235 ], [ 21.27184, 55.25158 ], [ 21.38577, 55.29945 ], [ 21.43505, 55.25676 ], [ 21.45261, 55.22705 ], [ 21.50256, 55.19329 ], [ 21.56952, 55.20409 ], [ 21.65011, 55.18673 ], [ 21.71247, 55.15668 ], [ 21.72595, 55.13858 ], [ 21.81586, 55.12522 ], [ 21.85347, 55.1025 ], [ 21.92037, 55.08658 ], [ 21.96346, 55.0801 ], [ 21.99622, 55.09254 ], [ 22.03355, 55.09001 ], [ 22.04595, 55.07927 ], [ 22.0409, 55.04771 ], [ 22.07676, 55.03107 ], [ 22.11668, 55.03312 ], [ 22.13061, 55.05093 ], [ 22.1606, 55.06165 ], [ 22.29012, 55.071 ], [ 22.47057, 55.05064 ], [ 22.59123, 55.07575 ], [ 22.60258, 55.02726 ], [ 22.64782, 54.9875 ], [ 22.65115, 54.9726 ], [ 22.65624, 54.9868 ], [ 22.68043, 54.99268 ], [ 22.69528, 54.97819 ], [ 22.72969, 54.96771 ], [ 22.73776, 54.95228 ], [ 22.76934, 54.94047 ], [ 22.77229, 54.92998 ], [ 22.78564, 54.92998 ], [ 22.79607, 54.90969 ], [ 22.82176, 54.91769 ], [ 22.85917, 54.89211 ], [ 22.8486, 54.869 ], [ 22.87459, 54.8553 ], [ 22.86936, 54.84295 ], [ 22.89215, 54.81546 ], [ 22.88011, 54.80362 ], [ 22.88351, 54.78865 ], [ 22.86373, 54.78234 ], [ 22.86419, 54.77399 ], [ 22.84556, 54.76117 ], [ 22.81955, 54.75959 ], [ 22.80989, 54.7428 ], [ 22.78026, 54.74346 ], [ 22.74835, 54.72438 ], [ 22.75458, 54.7047 ], [ 22.73321, 54.68658 ], [ 22.74301, 54.68216 ], [ 22.74373, 54.66534 ], [ 22.76275, 54.65463 ], [ 22.75463, 54.63005 ], [ 22.69213, 54.58511 ], [ 22.71956, 54.56434 ], [ 22.68861, 54.53217 ], [ 22.70476, 54.50897 ], [ 22.7093, 54.45891 ], [ 22.74021, 54.44744 ], [ 22.7962, 54.35926 ], [ 22.22727, 54.33593 ] ] ] ] } } ] } osmium-tool-1.17.0/test/extract/polygon-russia-west.geojson000066400000000000000000000013221474143067200240640ustar00rootroot00000000000000{ "type": "Feature", "properties": { "name": "polygon" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -180, 72.2916 ], [ -180, 72.29053 ], [ -180, 62.26134 ], [ -172.074188, 64.033556 ], [ -168.725284, 65.414875 ], [ -168.684085, 65.990095 ], [ -169.907891, 72.234092 ], [ -180, 72.2916 ] ] ] ] } } osmium-tool-1.17.0/test/extract/polygon-two-outer.poly000066400000000000000000000001701474143067200230620ustar00rootroot00000000000000foo 1 10.0 10.0 19.0 10.0 19.0 19.0 10.0 19.0 10.0 10.0 END 2 20.0 20.0 29.0 20.0 29.0 29.0 20.0 29.0 20.0 20.0 END END osmium-tool-1.17.0/test/extract/polygon-two-ways.osm.opl000066400000000000000000000002621474143067200233150ustar00rootroot00000000000000n10 x10.0 y10.0 n11 x19.0 y10.0 n12 x19.0 y19.0 n13 x10.0 y19.0 n20 x20.0 y20.0 n21 x29.0 y20.0 n22 x29.0 y29.0 n23 x20.0 y29.0 w40 Nn10,n11,n12,n13,n10 w41 Nn20,n21,n22,n23,n20 osmium-tool-1.17.0/test/extract/polygon-us-alaska.geojson000066400000000000000000000047271474143067200234730ustar00rootroot00000000000000{ "type": "Feature", "properties": { "name": "none" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 180, 54.19453 ], [ 180, 51.11044 ], [ 171.7602, 51.13801 ], [ 171.8152, 54.08518 ], [ 180, 54.19453 ] ] ], [ [ [ -180, 49.80942 ], [ -180, 60.09775 ], [ -169.0686, 65.40802 ], [ -168.9478, 66.01132 ], [ -169.1147, 71.19564 ], [ -140.9715, 72.98845 ], [ -140.9775, 60.31064 ], [ -139.0488, 60.36127 ], [ -139.1508, 60.10438 ], [ -138.6734, 59.9144 ], [ -138.6363, 59.81201 ], [ -137.5517, 59.23372 ], [ -137.4664, 58.94576 ], [ -136.7081, 59.21237 ], [ -136.3698, 59.61097 ], [ -135.3911, 59.82867 ], [ -134.7243, 59.3922 ], [ -134.4972, 59.15539 ], [ -133.3385, 58.42044 ], [ -131.6441, 56.6537 ], [ -129.7998, 56.04294 ], [ -130.1171, 55.74696 ], [ -129.8715, 55.26134 ], [ -130.5575, 54.64634 ], [ -131.6262, 54.4781 ], [ -132.6944, 54.45706 ], [ -133.7018, 54.51622 ], [ -133.5648, 53.42951 ], [ -180, 49.80942 ] ] ] ] } }osmium-tool-1.17.0/test/extract/polygon-us-alaska.poly000066400000000000000000000020701474143067200227770ustar00rootroot00000000000000none 1 1.80E+02 5.419453E+01 1.80E+02 5.111044E+01 1.717602E+02 5.113801E+01 1.718152E+02 5.408518E+01 1.80E+02 5.419453E+01 END 2 -1.80E+02 4.980942E+01 -1.80E+02 6.009775E+01 -1.690686E+02 6.540802E+01 -1.689478E+02 6.601132E+01 -1.691147E+02 7.119564E+01 -1.409715E+02 7.298845E+01 -1.409775E+02 6.031064E+01 -1.390488E+02 6.036127E+01 -1.391508E+02 6.010438E+01 -1.386734E+02 5.991440E+01 -1.386363E+02 5.981201E+01 -1.375517E+02 5.923372E+01 -1.374664E+02 5.894576E+01 -1.367081E+02 5.921237E+01 -1.363698E+02 5.961097E+01 -1.353911E+02 5.982867E+01 -1.347243E+02 5.939220E+01 -1.344972E+02 5.915539E+01 -1.333385E+02 5.842044E+01 -1.316441E+02 5.665370E+01 -1.297998E+02 5.604294E+01 -1.301171E+02 5.574696E+01 -1.298715E+02 5.526134E+01 -1.305575E+02 5.464634E+01 -1.316262E+02 5.447810E+01 -1.326944E+02 5.445706E+01 -1.337018E+02 5.451622E+01 -1.335648E+02 5.342951E+01 -1.80E+02 4.980942E+01 END END osmium-tool-1.17.0/test/extract/polygon-way.osm.opl000066400000000000000000000001311474143067200223160ustar00rootroot00000000000000n10 x10.0 y10.0 n11 x19.0 y10.0 n12 x19.0 y19.0 n13 x10.0 y19.0 w40 Nn10,n11,n12,n13,n10 osmium-tool-1.17.0/test/extract/test_unit.cpp000066400000000000000000000220541474143067200212520ustar00rootroot00000000000000 #include "test.hpp" // IWYU pragma: keep #include "exception.hpp" #include "geojson_file_parser.hpp" #include "geometry_util.hpp" #include "osm_file_parser.hpp" #include "poly_file_parser.hpp" #include #include TEST_CASE("Parse poly files") { osmium::memory::Buffer buffer{1024}; SECTION("Missing file") { REQUIRE_THROWS(PolyFileParser(buffer, "test/extract/missing.poly")()); } SECTION("Empty file") { PolyFileParser parser{buffer, "test/extract/empty.poly"}; REQUIRE_THROWS_AS(parser(), poly_error); } SECTION("One line file") { PolyFileParser parser{buffer, "test/extract/one-line.poly"}; REQUIRE_THROWS_AS(parser(), poly_error); } SECTION("Two line file") { PolyFileParser parser{buffer, "test/extract/two-line.poly"}; REQUIRE_THROWS_AS(parser(), poly_error); } SECTION("Missing END ring") { PolyFileParser parser{buffer, "test/extract/missing-end-ring.poly"}; REQUIRE_THROWS_AS(parser(), poly_error); } SECTION("Missing END polygon") { PolyFileParser parser{buffer, "test/extract/missing-end-polygon.poly"}; REQUIRE_THROWS_AS(parser(), poly_error); } SECTION("File with one polygon with one outer ring") { PolyFileParser parser{buffer, "test/extract/polygon-one-outer.poly"}; REQUIRE(parser() == 0); const osmium::Area& area = buffer.get(0); const auto nr = area.num_rings(); REQUIRE(nr.first == 1); REQUIRE(nr.second == 0); auto it = area.outer_rings().begin(); REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(10.0, 10.0)); ++it; REQUIRE(it == area.outer_rings().end()); } SECTION("File with one polygons with two outer rings") { PolyFileParser parser{buffer, "test/extract/polygon-two-outer.poly"}; REQUIRE(parser() == 0); const osmium::Area& area = buffer.get(0); const auto nr = area.num_rings(); REQUIRE(nr.first == 2); REQUIRE(nr.second == 0); auto it = area.outer_rings().begin(); REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(10.0, 10.0)); ++it; REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(20.0, 20.0)); ++it; REQUIRE(it == area.outer_rings().end()); } SECTION("File with one polygon with outer and inner rings") { PolyFileParser parser{buffer, "test/extract/polygon-outer-inner.poly"}; REQUIRE(parser() == 0); const osmium::Area& area = buffer.get(0); const auto nr = area.num_rings(); REQUIRE(nr.first == 1); REQUIRE(nr.second == 1); auto it = area.outer_rings().begin(); REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(10.0, 10.0)); const auto& inner_ring = *area.inner_rings(*it).begin(); REQUIRE(inner_ring.front().location() == osmium::Location(11.0, 11.0)); ++it; REQUIRE(it == area.outer_rings().end()); } SECTION("Two concatenated files") { PolyFileParser parser{buffer, "test/extract/two-polygons.poly"}; REQUIRE(parser() == 0); const osmium::Area& area = buffer.get(0); const auto nr = area.num_rings(); REQUIRE(nr.first == 2); REQUIRE(nr.second == 1); auto it = area.outer_rings().begin(); REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(10.0, 10.0)); const auto& inner_ring = *area.inner_rings(*it).begin(); REQUIRE(inner_ring.front().location() == osmium::Location(11.0, 11.0)); ++it; REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(20.0, 20.0)); ++it; REQUIRE(it == area.outer_rings().end()); } SECTION("Two concatenated files with empty line in between") { PolyFileParser parser{buffer, "test/extract/two-polygons-empty-line.poly"}; REQUIRE(parser() == 0); const osmium::Area& area = buffer.get(0); const auto nr = area.num_rings(); REQUIRE(nr.first == 2); REQUIRE(nr.second == 1); } } TEST_CASE("Parse OSM files") { osmium::memory::Buffer buffer{1024}; SECTION("Missing OSM file") { REQUIRE_THROWS(OSMFileParser(buffer, "test/extract/missing.osm.opl")()); } SECTION("Empty OSM file") { OSMFileParser parser{buffer, "test/extract/empty.osm.opl"}; REQUIRE_THROWS(parser()); } SECTION("OSM file without polygon") { OSMFileParser parser{buffer, "test/extract/no-polygon.osm.opl"}; REQUIRE_THROWS(parser()); } SECTION("OSM file with simple polygon") { OSMFileParser parser{buffer, "test/extract/polygon-way.osm.opl"}; REQUIRE(parser() == 0); const osmium::Area& area = buffer.get(0); const auto nr = area.num_rings(); REQUIRE(nr.first == 1); REQUIRE(nr.second == 0); auto it = area.outer_rings().begin(); REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(10.0, 10.0)); ++it; REQUIRE(it == area.outer_rings().end()); } SECTION("OSM file with two simple polygons") { OSMFileParser parser{buffer, "test/extract/polygon-two-ways.osm.opl"}; REQUIRE(parser() == 0); const osmium::Area& area = buffer.get(0); const auto nr = area.num_rings(); REQUIRE(nr.first == 2); REQUIRE(nr.second == 0); auto it = area.outer_rings().begin(); REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(10.0, 10.0)); ++it; REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(20.0, 20.0)); ++it; REQUIRE(it == area.outer_rings().end()); } SECTION("OSM file with multipolygon relation") { OSMFileParser parser{buffer, "test/extract/multipolygon.osm.opl"}; REQUIRE(parser() == 0); const osmium::Area& area = buffer.get(0); const auto nr = area.num_rings(); REQUIRE(nr.first == 2); REQUIRE(nr.second == 1); auto it = area.outer_rings().begin(); REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(10.0, 10.0)); const auto& inner_ring = *area.inner_rings(*it).begin(); REQUIRE(inner_ring.front().location() == osmium::Location(11.0, 11.0)); ++it; REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(20.0, 20.0)); ++it; REQUIRE(it == area.outer_rings().end()); } SECTION("File with CRLF") { PolyFileParser parser{buffer, "test/extract/polygon-crlf.poly"}; REQUIRE(parser() == 0); const osmium::Area& area = buffer.get(0); const auto nr = area.num_rings(); REQUIRE(nr.first == 1); REQUIRE(nr.second == 0); auto it = area.outer_rings().begin(); REQUIRE(it != area.outer_rings().end()); REQUIRE(it->front().location() == osmium::Location(10.0, 10.0)); ++it; REQUIRE(it == area.outer_rings().end()); } } TEST_CASE("Parse GeoJSON files") { osmium::memory::Buffer buffer{1024}; SECTION("Missing GeoJSON file") { REQUIRE_THROWS(GeoJSONFileParser(buffer, "test/extract/missing.geojson")()); } SECTION("Empty GeoJSON file") { GeoJSONFileParser parser{buffer, "test/extract/empty.geojson"}; REQUIRE_THROWS(parser()); } SECTION("Invalid GeoJSON file") { GeoJSONFileParser parser{buffer, "test/extract/invalid.geojson"}; REQUIRE_THROWS_AS(parser(), geojson_error); } SECTION("Invalid GeoJSON file: Root not an object") { GeoJSONFileParser parser{buffer, "test/extract/invalid-root.geojson"}; REQUIRE_THROWS_AS(parser(), geojson_error); } SECTION("Invalid GeoJSON file: Empty root object") { GeoJSONFileParser parser{buffer, "test/extract/empty-root.geojson"}; REQUIRE_THROWS_AS(parser(), geojson_error); } SECTION("Invalid GeoJSON file: Wrong geometry type") { GeoJSONFileParser parser{buffer, "test/extract/wrong-geometry-type.geojson"}; REQUIRE_THROWS_AS(parser(), geojson_error); } } TEST_CASE("Ring orientation (clockwise)") { using oc = osmium::geom::Coordinates; std::vector c = {oc{0, 0}, oc{0, 1}, oc{1, 1}, oc{1, 0}, oc{0, 0}}; REQUIRE(calculate_double_area(c) == Approx(-2.0)); REQUIRE_FALSE(is_ccw(c)); } TEST_CASE("Ring orientation (counter-clockwise)") { using oc = osmium::geom::Coordinates; std::vector c = {oc{0, 0}, oc{1, 0}, oc{1, 1}, oc{0, 1}, oc{0, 0}}; REQUIRE(calculate_double_area(c) == Approx(2.0)); REQUIRE(is_ccw(c)); } osmium-tool-1.17.0/test/extract/two-line.poly000066400000000000000000000000101474143067200211570ustar00rootroot00000000000000foo bar osmium-tool-1.17.0/test/extract/two-polygons-empty-line.poly000066400000000000000000000002731474143067200241760ustar00rootroot00000000000000foo 1 10.0 10.0 19.0 10.0 19.0 19.0 10.0 19.0 10.0 10.0 END !1s 11.0 11.0 18.0 11.0 18.0 18.0 11.0 18.0 11.0 11.0 END END bar 2 20.0 20.0 29.0 20.0 29.0 29.0 20.0 29.0 20.0 20.0 END END osmium-tool-1.17.0/test/extract/two-polygons.poly000066400000000000000000000002721474143067200221140ustar00rootroot00000000000000foo 1 10.0 10.0 19.0 10.0 19.0 19.0 10.0 19.0 10.0 10.0 END !1s 11.0 11.0 18.0 11.0 18.0 18.0 11.0 18.0 11.0 11.0 END END bar 2 20.0 20.0 29.0 20.0 29.0 29.0 20.0 29.0 20.0 20.0 END END osmium-tool-1.17.0/test/extract/w42394837.opl000066400000000000000000000020511474143067200203550ustar00rootroot00000000000000n529267768 v4 dV c18157685 t2013-10-03T09:27:25Z i90780 uVerdy_p T x180 y51.7940888 n529268301 v4 dV c18109681 t2013-09-30T12:42:56Z i90780 uVerdy_p T x180 y52.1384488 n2477601610 v2 dV c18157685 t2013-10-03T09:27:24Z i90780 uVerdy_p T x180 y51.8434451 n2477601612 v2 dV c18157685 t2013-10-03T09:27:24Z i90780 uVerdy_p T x180 y51.8927474 n2477601614 v2 dV c18157685 t2013-10-03T09:27:24Z i90780 uVerdy_p T x180 y51.9419957 n2477601616 v2 dV c18157685 t2013-10-03T09:27:24Z i90780 uVerdy_p T x180 y51.9911899 n2477601618 v2 dV c18157685 t2013-10-03T09:27:24Z i90780 uVerdy_p T x180 y52.0403302 n2477601621 v2 dV c18157685 t2013-10-03T09:27:24Z i90780 uVerdy_p T x180 y52.0894164 w42394837 v7 dV c74735267 t2019-09-20T21:14:03Z i8407767 uВаÑиль%20%Бойчук Tclosure_segment=yes,maritime=yes,name=Antimeridian%20%(180°%20%East),note=segment%20%closing%20%the%20%nautical%20%border%20%in%20%2%20%polygons%20%left%20%and%20%right%20%of%20%the%20%180th%20%meridian Nn529267768,n2477601610,n2477601612,n2477601614,n2477601616,n2477601618,n2477601621,n529268301 osmium-tool-1.17.0/test/extract/w42394837.osm000066400000000000000000000042301474143067200203620ustar00rootroot00000000000000 osmium-tool-1.17.0/test/extract/w46113981.opl000066400000000000000000000020311474143067200203440ustar00rootroot00000000000000n529215046 v4 dV c18157685 t2013-10-03T09:27:24Z i90780 uVerdy_p T x-180 y51.7940888 n529215726 v4 dV c18112005 t2013-09-30T14:47:23Z i90780 uVerdy_p T x-180 y52.138489 n2480990121 v1 dV c18157685 t2013-10-03T09:22:55Z i90780 uVerdy_p T x-180 y51.8434509 n2480990124 v1 dV c18157685 t2013-10-03T09:22:55Z i90780 uVerdy_p T x-180 y51.892759 n2480990126 v1 dV c18157685 t2013-10-03T09:22:55Z i90780 uVerdy_p T x-180 y51.942013 n2480990128 v1 dV c18157685 t2013-10-03T09:22:56Z i90780 uVerdy_p T x-180 y51.991213 n2480990129 v1 dV c18157685 t2013-10-03T09:22:56Z i90780 uVerdy_p T x-180 y52.0403589 n2480990140 v1 dV c18157685 t2013-10-03T09:22:56Z i90780 uVerdy_p T x-180 y52.0894509 w46113981 v7 dV c24927728 t2014-08-22T09:27:42Z i1781102 uelazarev Tclosure_segment=yes,maritime=yes,name=Antimeridian%20%(180°%20%West),note=segment%20%closing%20%the%20%nautical%20%border%20%in%20%2%20%polygons%20%left%20%and%20%right%20%of%20%the%20%180th%20%meridian Nn529215726,n2480990140,n2480990129,n2480990128,n2480990126,n2480990124,n2480990121,n529215046 osmium-tool-1.17.0/test/extract/w46113981.osm000066400000000000000000000042171474143067200203600ustar00rootroot00000000000000 osmium-tool-1.17.0/test/extract/wrong-geometry-type.geojson000066400000000000000000000001131474143067200240520ustar00rootroot00000000000000{ "type": "Feature", "geometry": { "type": "Point" } } osmium-tool-1.17.0/test/fileinfo/000077500000000000000000000000001474143067200166465ustar00rootroot00000000000000osmium-tool-1.17.0/test/fileinfo/CMakeLists.txt000066400000000000000000000207751474143067200214210ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - fileinfo # #----------------------------------------------------------------------------- if(NOT WIN32) function(check_fileinfo _name _options _input _output) check_output(fileinfo ${_name} "fileinfo ${_options} fileinfo/${_input}" "fileinfo/${_output}") endfunction() check_fileinfo(fi1-extended "--extended --crc" fi1.osm fi1-result.txt) # Nlohmann JSON library before 3.9 don't have an ordered JSON type, # don't run tests that will not work because of that. if(nlohmann_json_VERSION VERSION_GREATER_EQUAL "3.9") check_fileinfo(fi1-extended-json "--extended --crc --json" fi1.osm fi1-result.json) endif() endif() #----------------------------------------------------------------------------- add_test(NAME fileinfo-g-generator COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi1.osm -g header.option.generator) set_tests_properties(fileinfo-g-generator PROPERTIES PASS_REGULAR_EXPRESSION "^testdata\n$") add_test(NAME fileinfo-g-unknown-option COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi1.osm -g header.option.foo) set_tests_properties(fileinfo-g-unknown-option PROPERTIES PASS_REGULAR_EXPRESSION "^$") add_test(NAME fileinfo-g-fail COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi1.osm -g foobar) set_tests_properties(fileinfo-g-fail PROPERTIES WILL_FAIL true) #----------------------------------------------------------------------------- # Test the metadata properties #----------------------------------------------------------------------------- # The input file has objects with only version+timestamp and objects with all metadata attributes. # searching for metadata.all_objects.version add_test(NAME fileinfo-metadata-mixed-all-version COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi2.osm -e -g metadata.all_objects.version) set_tests_properties(fileinfo-metadata-mixed-all-version PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file has objects with only version+timestamp and objects with all metadata attributes. # searching for metadata.all_objects.timestamp add_test(NAME fileinfo-metadata-mixed-all-timestamp COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi2.osm -e -g metadata.all_objects.timestamp) set_tests_properties(fileinfo-metadata-mixed-all-timestamp PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file has objects with only version+timestamp and objects with all metadata attributes. # searching for metadata.all_objects.changeset add_test(NAME fileinfo-metadata-mixed-all-changeset COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi2.osm -e -g metadata.all_objects.changeset) set_tests_properties(fileinfo-metadata-mixed-all-changeset PROPERTIES PASS_REGULAR_EXPRESSION "^no\n$") # The input file has objects with only version+timestamp and objects with all metadata attributes. # searching for metadata.some_objects.version add_test(NAME fileinfo-metadata-mixed-some-version COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi2.osm -e -g metadata.some_objects.version) set_tests_properties(fileinfo-metadata-mixed-some-version PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file has objects with only version+timestamp and objects with all metadata attributes. # searching for metadata.some_objects.timestamp add_test(NAME fileinfo-metadata-mixed-some-timestamp COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi2.osm -e -g metadata.some_objects.timestamp) set_tests_properties(fileinfo-metadata-mixed-some-timestamp PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file has objects with only version+timestamp and objects with all metadata attributes. # searching for metadata.some_objects.changeset add_test(NAME fileinfo-metadata-mixed-some-changeset COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi2.osm -e -g metadata.some_objects.changeset) set_tests_properties(fileinfo-metadata-mixed-some-changeset PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file has objects with only version+timestamp and objects with all metadata attributes. # searching for metadata.some_objects.uid add_test(NAME fileinfo-metadata-mixed-some-uid COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi2.osm -e -g metadata.some_objects.uid) set_tests_properties(fileinfo-metadata-mixed-some-uid PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file has objects with only version+timestamp and objects with all metadata attributes. # searching for metadata.some_objects.user add_test(NAME fileinfo-metadata-mixed-some-user COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi2.osm -e -g metadata.some_objects.user) set_tests_properties(fileinfo-metadata-mixed-some-user PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file contains only objects with version+timestamp. # searching for metadata.all_objects.version add_test(NAME fileinfo-metadata-homogenous-all-version COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi3.osm -e -g metadata.all_objects.version) set_tests_properties(fileinfo-metadata-homogenous-all-version PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file contains only objects with version+timestamp. # searching for metadata.all_objects.timestamp add_test(NAME fileinfo-metadata-homogenous-all-timestamp COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi3.osm -e -g metadata.all_objects.timestamp) set_tests_properties(fileinfo-metadata-homogenous-all-timestamp PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file contains only objects with version+timestamp. # searching for metadata.all_objects.changeset add_test(NAME fileinfo-metadata-homogenous-all-changeset COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi3.osm -e -g metadata.all_objects.changeset) set_tests_properties(fileinfo-metadata-homogenous-all-changeset PROPERTIES PASS_REGULAR_EXPRESSION "^no\n$") # The input file contains only objects with version+timestamp. # searching for metadata.all_objects.uid add_test(NAME fileinfo-metadata-homogenous-all-uid COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi3.osm -e -g metadata.all_objects.uid) set_tests_properties(fileinfo-metadata-homogenous-all-uid PROPERTIES PASS_REGULAR_EXPRESSION "^no\n$") # The input file contains only objects with version+timestamp. # searching for metadata.all_objects.user add_test(NAME fileinfo-metadata-homogenous-all-user COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi3.osm -e -g metadata.all_objects.user) set_tests_properties(fileinfo-metadata-homogenous-all-user PROPERTIES PASS_REGULAR_EXPRESSION "^no\n$") # The input file contains only objects with version+timestamp. # searching for metadata.some_objects.version add_test(NAME fileinfo-metadata-homogenous-some-version COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi3.osm -e -g metadata.some_objects.version) set_tests_properties(fileinfo-metadata-homogenous-some-version PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file contains only objects with version+timestamp. # searching for metadata.some_objects.timestamp add_test(NAME fileinfo-metadata-homogenous-some-timestamp COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi3.osm -e -g metadata.some_objects.timestamp) set_tests_properties(fileinfo-metadata-homogenous-some-timestamp PROPERTIES PASS_REGULAR_EXPRESSION "^yes\n$") # The input file contains only objects with version+timestamp. # searching for metadata.some_objects.changeset add_test(NAME fileinfo-metadata-homogenous-some-changeset COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi3.osm -e -g metadata.some_objects.changeset) set_tests_properties(fileinfo-metadata-homogenous-some-changeset PROPERTIES PASS_REGULAR_EXPRESSION "^no\n$") # The input file contains only objects with version+timestamp. # searching for metadata.some_objects.uid add_test(NAME fileinfo-metadata-homogenous-some-uid COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi3.osm -e -g metadata.some_objects.uid) set_tests_properties(fileinfo-metadata-homogenous-some-uid PROPERTIES PASS_REGULAR_EXPRESSION "^no\n$") # The input file contains only objects with version+timestamp. # searching for metadata.some_objects.user add_test(NAME fileinfo-metadata-homogenous-some-user COMMAND osmium fileinfo ${CMAKE_SOURCE_DIR}/test/fileinfo/fi3.osm -e -g metadata.some_objects.user) set_tests_properties(fileinfo-metadata-homogenous-some-user PROPERTIES PASS_REGULAR_EXPRESSION "^no\n$") #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/fileinfo/fi1-result.json000066400000000000000000000031501474143067200215330ustar00rootroot00000000000000{ "file": { "name": "fileinfo/fi1.osm", "format": "XML", "compression": "none", "size": 630 }, "header": { "boxes": [], "with_history": false, "option": { "generator": "testdata", "version": "0.6", "xml_josm_upload": "false" } }, "data": { "bbox": [ 1.0, 1.0, 1.0, 3.0 ], "timestamp": { "first": "2015-01-01T01:00:00Z", "last": "2015-01-01T04:00:00Z" }, "objects_ordered": true, "multiple_versions": false, "crc32": "95828746", "count": { "changesets": 0, "nodes": 3, "ways": 2, "relations": 0 }, "minid": { "changesets": 0, "nodes": 1, "ways": -4, "relations": 0 }, "maxid": { "changesets": 0, "nodes": 4, "ways": -3, "relations": 0 }, "buffers": { "count": 1, "size": 224, "capacity": 1048576 }, "metadata": { "all_objects": { "version": true, "timestamp": true, "changeset": true, "user": true, "uid": true }, "some_objects": { "version": true, "timestamp": true, "changeset": true, "user": true, "uid": true } } } } osmium-tool-1.17.0/test/fileinfo/fi1-result.txt000066400000000000000000000016611474143067200214060ustar00rootroot00000000000000File: Name: fileinfo/fi1.osm Format: XML Compression: none Size: 630 Header: Bounding boxes: With history: no Options: generator=testdata version=0.6 xml_josm_upload=false Data: Bounding box: (1,1,1,3) Timestamps: First: 2015-01-01T01:00:00Z Last: 2015-01-01T04:00:00Z Objects ordered (by type and id): yes Multiple versions of same object: no CRC32: 95828746 Number of changesets: 0 Number of nodes: 3 Number of ways: 2 Number of relations: 0 Smallest changeset ID: 0 Smallest node ID: 1 Smallest way ID: -4 Smallest relation ID: 0 Largest changeset ID: 0 Largest node ID: 4 Largest way ID: -3 Largest relation ID: 0 Number of buffers: 1 (avg 5 objects per buffer) Sum of buffer sizes: 224 (0 GB) Sum of buffer capacities: 1048576 (0.001 GB, 0% full) Metadata: All objects have following metadata attributes: all Some objects have following metadata attributes: all osmium-tool-1.17.0/test/fileinfo/fi1.osm000066400000000000000000000011661474143067200200510ustar00rootroot00000000000000 osmium-tool-1.17.0/test/fileinfo/fi2.osm000066400000000000000000000005621474143067200200510ustar00rootroot00000000000000 osmium-tool-1.17.0/test/fileinfo/fi3.osm000066400000000000000000000005201474143067200200440ustar00rootroot00000000000000 osmium-tool-1.17.0/test/formats/000077500000000000000000000000001474143067200165265ustar00rootroot00000000000000osmium-tool-1.17.0/test/formats/CMakeLists.txt000066400000000000000000000057411474143067200212750ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - formats # #----------------------------------------------------------------------------- function(check_formats _name _input _format _output) check_output(formats ${_name} "cat --generator=test --output-header xml_josm_upload=false -f ${_format} ${PROJECT_SOURCE_DIR}/test/formats/${_input}" "formats/${_output}") endfunction() #----------------------------------------------------------------------------- # empty file (no objects) check_formats(emptyxx empty.osm xml empty.osm) check_formats(emptyxo empty.osm opl empty.osm.opl) check_formats(emptyxp empty.osm pbf empty.osm.pbf) check_formats(emptyxpd empty.osm pbf,pbf_dense_nodes=false empty-nodensenodes.osm.pbf) check_formats(emptyxpc empty.osm pbf,pbf_compression=none empty-nocompression.osm.pbf) check_formats(emptyxpm empty.osm pbf,add_metadata=false empty-nometadata.osm.pbf) check_formats(emptyxpdm empty.osm pbf,pbf_dense_nodes=false,add_metadata=false empty-nodensenodes-nometadata.osm.pbf) check_formats(emptypx empty.osm.pbf xml empty.osm) check_formats(emptypo empty.osm.pbf opl empty.osm.opl) check_formats(emptypp empty.osm.pbf pbf empty.osm.pbf) check_formats(emptypxd empty-nodensenodes.osm.pbf xml empty.osm) check_formats(emptypod empty-nodensenodes.osm.pbf opl empty.osm.opl) check_formats(emptyppd empty-nodensenodes.osm.pbf pbf empty.osm.pbf) check_formats(emptypxc empty-nocompression.osm.pbf xml empty.osm) check_formats(emptypoc empty-nocompression.osm.pbf opl empty.osm.opl) check_formats(emptyppc empty-nocompression.osm.pbf pbf empty.osm.pbf) # normal file check_formats(f1xx f1.osm xml f1.osm) check_formats(f1xo f1.osm opl f1.osm.opl) if(RUN_TESTS_WITH_BINARY_COMPARE) check_formats(f1xp f1.osm pbf f1.osm.pbf) check_formats(f1xpd f1.osm pbf,pbf_dense_nodes=false f1-nodensenodes.osm.pbf) check_formats(f1xpm f1.osm pbf,add_metadata=false f1-nometadata.osm.pbf) check_formats(f1xpdm f1.osm pbf,pbf_dense_nodes=false,add_metadata=false f1-nodensenodes-nometadata.osm.pbf) endif() check_formats(f1xpc f1.osm pbf,pbf_compression=none f1-nocompression.osm.pbf) check_formats(f1px f1.osm.pbf xml f1.osm) check_formats(f1po f1.osm.pbf opl f1.osm.opl) check_formats(f1pxd f1-nodensenodes.osm.pbf xml f1.osm) check_formats(f1pod f1-nodensenodes.osm.pbf opl f1.osm.opl) check_formats(f1pxc f1-nocompression.osm.pbf xml f1.osm) check_formats(f1poc f1-nocompression.osm.pbf opl f1.osm.opl) if(RUN_TESTS_WITH_BINARY_COMPARE) check_formats(f1pp f1.osm.pbf pbf f1.osm.pbf) check_formats(f1ppd f1-nodensenodes.osm.pbf pbf f1.osm.pbf) check_formats(f1ppc f1-nocompression.osm.pbf pbf f1.osm.pbf) endif() #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/formats/empty-nocompression.osm.pbf000066400000000000000000000000661474143067200240500ustar00rootroot00000000000000 OSMHeader% #"OsmSchema-V0.6" DenseNodes‚testosmium-tool-1.17.0/test/formats/empty-nodensenodes-nometadata.osm.pbf000066400000000000000000000000641474143067200257470ustar00rootroot00000000000000 OSMHeader#xœSâó/Î NÎHÍMÔ 3Ð3kbd)I-.R›osmium-tool-1.17.0/test/formats/empty-nodensenodes.osm.pbf000066400000000000000000000000641474143067200236340ustar00rootroot00000000000000 OSMHeader#xœSâó/Î NÎHÍMÔ 3Ð3kbd)I-.R›osmium-tool-1.17.0/test/formats/empty-nometadata.osm.pbf000066400000000000000000000001001474143067200232540ustar00rootroot00000000000000 OSMHeader/#+xœSâó/Î NÎHÍMÔ 3Ð3SârIÍ+NõËOI-nbd)I-.¿` #osmium-tool-1.17.0/test/formats/empty.osm000066400000000000000000000001421474143067200204010ustar00rootroot00000000000000 osmium-tool-1.17.0/test/formats/empty.osm.opl000066400000000000000000000000001474143067200211630ustar00rootroot00000000000000osmium-tool-1.17.0/test/formats/empty.osm.pbf000066400000000000000000000001001474143067200211410ustar00rootroot00000000000000 OSMHeader/#+xœSâó/Î NÎHÍMÔ 3Ð3SârIÍ+NõËOI-nbd)I-.¿` #osmium-tool-1.17.0/test/formats/f1-nocompression.osm.pbf000066400000000000000000000006041474143067200232160ustar00rootroot00000000000000 OSMHeader% #"OsmSchema-V0.6" DenseNodes‚test OSMDataq o  test foo\Z *+ €ìé³ Àñœ<Þ‡Ò9‚‹Ì "*B€ÚÄ œìî äÇš €ÚÄ J €ÚÄ ð¼Ÿ?R OSMDataf d # foo xyz !@$ bar *#/ test=#"¸’¥ (B"¸’¥ (B OSMDataJ H  xyz abc test some way&"$"¸’¥ (BJRosmium-tool-1.17.0/test/formats/f1-nodensenodes-nometadata.osm.pbf000066400000000000000000000004411474143067200251160ustar00rootroot00000000000000 OSMHeader#xœSâó/Î NÎHÍMÔ 3Ð3kbd)I-.R› OSMData=>9xœãbâb²àâáqh¸u„ÓDybsŽmöø0í 7'áÐÐwN&'åÐðb’˜8o¦ OSMDataG>Cxœã’åbàbNËÏQ•U\ÌŠ*\ÌI‰E\ÌZÊúB²RÂ"B,ŒLÌ,R,¬¬LlNÌ"LLRl¢NLL" OSMData<28xœã’àbàb®¨¬âbNLJ²9ŠósSÊ+…Ä”D8ä„¥™œ˜˜Y¼˜$‚˜éDâosmium-tool-1.17.0/test/formats/f1-nodensenodes.osm.pbf000066400000000000000000000006221474143067200230040ustar00rootroot00000000000000 OSMHeader#xœSâó/Î NÎHÍMÔ 3Ð3kbd)I-.R› OSMData|‹wxœãâçbàb)I-.ÒÌiùùB\2"J|Œ ß¾Üd‘`T`Ô`th¸u„ÓDeÅÀ²Ö5ÿÉ2h09Ì9¶YØãô'Ü@Y °ìùMo¦°J0)0k0;4ô“é•ËNØ1i)«3Ää“ÔÀ²â<&ñ OSMDatabd^xœãRæbàbNËÏQ•U\ÌŠ*\ÌI‰E\ÌZÊú\,%©Å%B¶RÊ"B,ŒLÌ,R,¬¬LlJ|ŒvLZÊ*Á¢À¨ÁîÄ,ÂÄ$%Æ!Š$Á–`’`,¦¥ OSMDataSHOxœã’ãbàb®¨¬âbNLJæb)I-.Špçç¦*”'V ©)©pÈ 12J12)ñq0 LØ1i)«££³ «“„@# osmium-tool-1.17.0/test/formats/f1-nometadata.osm.pbf000066400000000000000000000004531474143067200224370ustar00rootroot00000000000000 OSMHeader/#+xœSâó/Î NÎHÍMÔ 3Ð3SârIÍ+NõËOI-nbd)I-.¿` # OSMData;57xœãbâbÒÒåbabbrh¸u„sΛwœOŽÏâ±½xAä‡=ó™Þ1C §™ OSMDataG>Cxœã’åbàbNËÏQ•U\ÌŠ*\ÌI‰E\ÌZÊúB²RÂ"B,ŒLÌ,R,¬¬LlNÌ"LLRl¢NLL" OSMData<28xœã’àbàb®¨¬âbNLJ²9ŠósSÊ+…Ä”D8ä„¥™œ˜˜Y¼˜$‚˜éDâosmium-tool-1.17.0/test/formats/f1.osm000066400000000000000000000022341474143067200175550ustar00rootroot00000000000000 osmium-tool-1.17.0/test/formats/f1.osm.opl000066400000000000000000000006601474143067200203470ustar00rootroot00000000000000n10 v1 dV c1 t2010-01-01T00:00:00Z i1 utest T x1 y1 n11 v1 dV c1 t2012-01-01T22:00:00Z i0 u T x1.2355 y2.034523 n12 v1 dV c2 t2013-12-01T11:11:11Z i3 ufoo T x1 y3 n13 v1 dV c3 t2015-01-01T01:00:00Z i1 utest T x1 y4 w20 v1 dV c4 t2015-01-01T01:00:00Z i1 utest Tfoo=bar,=bar,xyz=,!%40%$=*#/ Nn10,n11,n12 w21 v1 dV c1 t2015-01-01T01:00:00Z i1 utest T Nn12,n13 r30 v1 dV c1 t2015-01-01T01:00:00Z i1 utest Txyz=abc Mn12@,w20@some%20%way osmium-tool-1.17.0/test/formats/f1.osm.pbf000066400000000000000000000006241474143067200203240ustar00rootroot00000000000000 OSMHeader/#+xœSâó/Î NÎHÍMÔ 3Ð3SârIÍ+NõËOI-nbd)I-.¿` # OSMDataronxœãâçbàb)I-.ÒÌiùùB1BQ\,"LLLZÚ\,Œ@ $ØðæåfÎçØÜk¿dÙÔ}FAŠ…‰‰I‰…‰‘Y‹¨–ÙI áÖÎ9oÞq>9>‹Äöâ‘öÌgzÄ A, @= C OSMDatabd^xœãRæbàbNËÏQ•U\ÌŠ*\ÌI‰E\ÌZÊú\,%©Å%B¶RÊ"B,ŒLÌ,R,¬¬LlJ|ŒvLZÊ*Á¢À¨ÁîÄ,ÂÄ$%Æ!Š$Á–`’`,¦¥ OSMDataSHOxœã’ãbàb®¨¬âbNLJæb)I-.Špçç¦*”'V ©)©pÈ 12J12)ñq0 LØ1i)«££³ «“„@# osmium-tool-1.17.0/test/getid/000077500000000000000000000000001474143067200161475ustar00rootroot00000000000000osmium-tool-1.17.0/test/getid/CMakeLists.txt000066400000000000000000000040631474143067200207120ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - getid # #----------------------------------------------------------------------------- function(check_getid _name _input _output) check_output(getid ${_name} "getid --generator=test --output-header=xml_josm_upload=false -f osm getid/${_input} n11,n12 w21" "getid/${_output}") endfunction() function(check_getid_file _name _file _input _output) check_output(getid ${_name} "getid --generator=test --output-header=xml_josm_upload=false -i getid/${_file} -f osm getid/${_input}" "getid/${_output}") endfunction() check_getid(n input.osm output.osm) check_getid_file(file1 idfile input.osm output-file.osm) #----------------------------------------------------------------------------- function(check_getid_r _name _source _input _output) check_output(getid ${_name} "getid -r --generator=test -f osm getid/${_source}.osm -I getid/${_input}.osm" "getid/${_output}.osm") check_output(getid ${_name}-i "getid -r --generator=test -f osm getid/${_source}.osm -i getid/${_input}.id" "getid/${_output}.osm") endfunction() function(check_getid_r_fail _name _input) check_output(getid ${_name} "getid -r --generator=test -f osm getid/source.osm -I getid/${_input}.osm" "getid/out-empty.osm" 1) check_output(getid ${_name}-i "getid -r --generator=test -f osm getid/source.osm -i getid/${_input}.id" "getid/out-empty.osm" 1) endfunction() check_getid_r(n10 source in10 out10) check_getid_r(w21 source in21 out21) check_getid_r(r30 source in30 out30) check_getid_r(r31 source in31 out31) check_getid_r(r32 source in32 out32) check_getid_r(n10nrr source-no-rr in10 out10) check_getid_r(w21nrr source-no-rr in21 out21) check_getid_r(r30nrr source-no-rr in30 out30) check_getid_r(r32nrr source-no-rr in32 out32) check_getid_r_fail(missing-n19 in19) check_getid_r_fail(missing-w29 in29) check_getid_r_fail(missing-r39 in39) check_getid_r(relloop relloop relloop relloop-out) #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/getid/idfile000066400000000000000000000000741474143067200173270ustar00rootroot00000000000000n11 n12 foo n10 n13 # comment # comment w21 osmium-tool-1.17.0/test/getid/in10.id000066400000000000000000000000041474143067200172260ustar00rootroot00000000000000n10 osmium-tool-1.17.0/test/getid/in10.osm000066400000000000000000000003271474143067200174400ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/in19.id000066400000000000000000000000041474143067200172370ustar00rootroot00000000000000n19 osmium-tool-1.17.0/test/getid/in19.osm000066400000000000000000000003271474143067200174510ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/in21.id000066400000000000000000000000041474143067200172300ustar00rootroot00000000000000w21 osmium-tool-1.17.0/test/getid/in21.osm000066400000000000000000000003641474143067200174430ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/in29.id000066400000000000000000000000041474143067200172400ustar00rootroot00000000000000w29 osmium-tool-1.17.0/test/getid/in29.osm000066400000000000000000000003641474143067200174530ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/in30.id000066400000000000000000000000041474143067200172300ustar00rootroot00000000000000r30 osmium-tool-1.17.0/test/getid/in30.osm000066400000000000000000000005271474143067200174440ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/in31.id000066400000000000000000000000041474143067200172310ustar00rootroot00000000000000r31 osmium-tool-1.17.0/test/getid/in31.osm000066400000000000000000000004071474143067200174420ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/in32.id000066400000000000000000000000041474143067200172320ustar00rootroot00000000000000r32 osmium-tool-1.17.0/test/getid/in32.osm000066400000000000000000000004031474143067200174370ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/in39.id000066400000000000000000000000041474143067200172410ustar00rootroot00000000000000r39 osmium-tool-1.17.0/test/getid/in39.osm000066400000000000000000000004031474143067200174460ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/input.osm000066400000000000000000000021321474143067200200240ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/out-empty.osm000066400000000000000000000001421474143067200206270ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/out10.osm000066400000000000000000000003231474143067200176350ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/out21.osm000066400000000000000000000007221474143067200176420ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/out30.osm000066400000000000000000000017021474143067200176410ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/out31.osm000066400000000000000000000021431474143067200176420ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/out32.osm000066400000000000000000000005601474143067200176440ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/output-file.osm000066400000000000000000000013171474143067200211460ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/output.osm000066400000000000000000000007551474143067200202360ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/relloop-out.osm000066400000000000000000000006441474143067200211540ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/relloop.id000066400000000000000000000000101474143067200201300ustar00rootroot00000000000000r30 r31 osmium-tool-1.17.0/test/getid/relloop.osm000066400000000000000000000006501474143067200203440ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/source-no-rr.osm000066400000000000000000000025421474143067200212250ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getid/source.osm000066400000000000000000000030031474143067200201630ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getparents/000077500000000000000000000000001474143067200172275ustar00rootroot00000000000000osmium-tool-1.17.0/test/getparents/CMakeLists.txt000066400000000000000000000022101474143067200217620ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - getparents # #----------------------------------------------------------------------------- function(check_getparents _name _input _ids _output) check_output(getparents ${_name} "getparents --generator=test --output-header=xml_josm_upload=false -f osm getparents/${_input} ${_ids}" "getparents/${_output}") endfunction() function(check_getparents_r _name _input _ids _output) check_output(getparents ${_name}-s "getparents --generator=test --output-header=xml_josm_upload=false -f osm --add-self getparents/${_input} ${_ids}" "getparents/${_output}") endfunction() #----------------------------------------------------------------------------- check_getparents(n10 input.osm n10 out-n10.osm) check_getparents(n12 input.osm n12 out-n12.osm) check_getparents(w20 input.osm w20 out-w20.osm) check_getparents_r(n10 input.osm n10 out-n10-s.osm) check_getparents_r(n12 input.osm n12 out-n12-s.osm) check_getparents_r(w20 input.osm w20 out-w20-s.osm) #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/getparents/input.osm000066400000000000000000000021321474143067200211040ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getparents/out-n10-s.osm000066400000000000000000000006171474143067200214160ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getparents/out-n10.osm000066400000000000000000000004361474143067200211550ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getparents/out-n12-s.osm000066400000000000000000000014031474143067200214120ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getparents/out-n12.osm000066400000000000000000000012221474143067200211510ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getparents/out-w20-s.osm000066400000000000000000000007511474143067200214270ustar00rootroot00000000000000 osmium-tool-1.17.0/test/getparents/out-w20.osm000066400000000000000000000004551474143067200211700ustar00rootroot00000000000000 osmium-tool-1.17.0/test/help/000077500000000000000000000000001474143067200160035ustar00rootroot00000000000000osmium-tool-1.17.0/test/help/CMakeLists.txt000066400000000000000000000011001474143067200205330ustar00rootroot00000000000000#----------------------------------------------------------------------------- # # CMake Config # # Osmium Tool Tests - help # #----------------------------------------------------------------------------- do_test(help1 "osmium" "^Usage: .*COMMANDS:") do_test(help2 "osmium help" "^Usage: .*COMMANDS:") do_test(help3 "osmium --help" "^Usage: .*COMMANDS:") do_test(help4 "osmium -h" "^Usage: .*COMMANDS:") do_test(help_topic_unknown "osmium help x" "^Unknown help topic 'x'.\n") #----------------------------------------------------------------------------- osmium-tool-1.17.0/test/include/000077500000000000000000000000001474143067200164765ustar00rootroot00000000000000osmium-tool-1.17.0/test/include/catch.hpp000066400000000000000000024040031474143067200202740ustar00rootroot00000000000000/* * Catch v2.13.10 * Generated: 2022-10-16 11:01:23.452308 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED // start catch.hpp #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 #define CATCH_VERSION_PATCH 10 #ifdef __clang__ # pragma clang system_header #elif defined __GNUC__ # pragma GCC system_header #endif // start catch_suppress_warnings.h #ifdef __clang__ # ifdef __ICC // icpc defines the __clang__ macro # pragma warning(push) # pragma warning(disable: 161 1682) # else // __ICC # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wswitch-enum" # pragma clang diagnostic ignored "-Wcovered-switch-default" # endif #elif defined __GNUC__ // Because REQUIREs trigger GCC's -Wparentheses, and because still // supported version of g++ have only buggy support for _Pragmas, // Wparentheses have to be suppressed globally. # pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunused-variable" # pragma GCC diagnostic ignored "-Wpadded" #endif // end catch_suppress_warnings.h #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) # define CATCH_IMPL # define CATCH_CONFIG_ALL_PARTS #endif // In the impl file, we want to have access to all parts of the headers // Can also be used to sanely support PCHs #if defined(CATCH_CONFIG_ALL_PARTS) # define CATCH_CONFIG_EXTERNAL_INTERFACES # if defined(CATCH_CONFIG_DISABLE_MATCHERS) # undef CATCH_CONFIG_DISABLE_MATCHERS # endif # if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER # endif #endif #if !defined(CATCH_CONFIG_IMPL_ONLY) // start catch_platform.h // See e.g.: // https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html #ifdef __APPLE__ # include # if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) # define CATCH_PLATFORM_MAC # elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) # define CATCH_PLATFORM_IPHONE # endif #elif defined(linux) || defined(__linux) || defined(__linux__) # define CATCH_PLATFORM_LINUX #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) # define CATCH_PLATFORM_WINDOWS #endif // end catch_platform.h #ifdef CATCH_IMPL # ifndef CLARA_CONFIG_MAIN # define CLARA_CONFIG_MAIN_NOT_DEFINED # define CLARA_CONFIG_MAIN # endif #endif // start catch_user_interfaces.h namespace Catch { unsigned int rngSeed(); } // end catch_user_interfaces.h // start catch_tag_alias_autoregistrar.h // start catch_common.h // start catch_compiler_capabilities.h // Detect a number of compiler features - by compiler // The following features are defined: // // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? // **************** // Note to maintainers: if new toggles are added please document them // in configuration.md, too // **************** // In general each macro has a _NO_ form // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. // Many features, at point of detection, define an _INTERNAL_ macro, so they // can be combined, en-mass, with the _NO_ forms later. #ifdef __cplusplus # if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) # define CATCH_CPP14_OR_GREATER # endif # if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) # define CATCH_CPP17_OR_GREATER # endif #endif // Only GCC compiler should be used in this block, so other compilers trying to // mask themselves as GCC should be ignored. #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) #endif #if defined(__clang__) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug // which results in calls to destructors being emitted for each temporary, // without a matching initialization. In practice, this can result in something // like `std::string::~string` being called on an uninitialized value. // // For example, this code will likely segfault under IBM XL: // ``` // REQUIRE(std::string("12") + "34" == "1234") // ``` // // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. # if !defined(__ibmxl__) && !defined(__CUDACC__) # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ # endif # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) #endif // __clang__ //////////////////////////////////////////////////////////////////////////////// // Assume that non-Windows platforms support posix signals by default #if !defined(CATCH_PLATFORM_WINDOWS) #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS #endif //////////////////////////////////////////////////////////////////////////////// // We know some environments not to support full POSIX signals #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS #endif #ifdef __OS400__ # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS # define CATCH_CONFIG_COLOUR_NONE #endif //////////////////////////////////////////////////////////////////////////////// // Android somehow still does not support std::to_string #if defined(__ANDROID__) # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING # define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE #endif //////////////////////////////////////////////////////////////////////////////// // Not all Windows environments support SEH properly #if defined(__MINGW32__) # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH #endif //////////////////////////////////////////////////////////////////////////////// // PS4 #if defined(__ORBIS__) # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE #endif //////////////////////////////////////////////////////////////////////////////// // Cygwin #ifdef __CYGWIN__ // Required for some versions of Cygwin to declare gettimeofday // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin # define _BSD_SOURCE // some versions of cygwin (most) do not support std::to_string. Use the libstd check. // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING # endif #endif // __CYGWIN__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ #if defined(_MSC_VER) // Universal Windows platform does not support SEH // Or console colours (or console at all...) # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) # define CATCH_CONFIG_COLOUR_NONE # else # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH # endif # if !defined(__clang__) // Handle Clang masquerading for msvc // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ // _MSVC_TRADITIONAL == 0 means new conformant preprocessor // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR # endif // MSVC_TRADITIONAL // Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) # endif // __clang__ #endif // _MSC_VER #if defined(_REENTRANT) || defined(_MSC_VER) // Enable async processing, as -pthread is specified or no additional linking is required # define CATCH_INTERNAL_CONFIG_USE_ASYNC #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// // Check if we are compiled with -fno-exceptions or equivalent #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED #endif //////////////////////////////////////////////////////////////////////////////// // DJGPP #ifdef __DJGPP__ # define CATCH_INTERNAL_CONFIG_NO_WCHAR #endif // __DJGPP__ //////////////////////////////////////////////////////////////////////////////// // Embarcadero C++Build #if defined(__BORLANDC__) #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN #endif //////////////////////////////////////////////////////////////////////////////// // Use of __COUNTER__ is suppressed during code analysis in // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly // handled by it. // Otherwise all supported compilers support COUNTER macro, // but user still might want to turn it off #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) #define CATCH_INTERNAL_CONFIG_COUNTER #endif //////////////////////////////////////////////////////////////////////////////// // RTX is a special version of Windows that is real time. // This means that it is detected as Windows, but does not provide // the same set of capabilities as real Windows does. #if defined(UNDER_RTSS) || defined(RTX64_BUILD) #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH #define CATCH_INTERNAL_CONFIG_NO_ASYNC #define CATCH_CONFIG_COLOUR_NONE #endif #if !defined(_GLIBCXX_USE_C99_MATH_TR1) #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER #endif // Various stdlib support checks that require __has_include #if defined(__has_include) // Check if string_view is available and usable #if __has_include() && defined(CATCH_CPP17_OR_GREATER) # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW #endif // Check if optional is available and usable # if __has_include() && defined(CATCH_CPP17_OR_GREATER) # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) // Check if byte is available and usable # if __has_include() && defined(CATCH_CPP17_OR_GREATER) # include # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) # define CATCH_INTERNAL_CONFIG_CPP17_BYTE # endif # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) // Check if variant is available and usable # if __has_include() && defined(CATCH_CPP17_OR_GREATER) # if defined(__clang__) && (__clang_major__ < 8) // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 // fix should be in clang 8, workaround in libstdc++ 8.2 # include # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) # define CATCH_CONFIG_NO_CPP17_VARIANT # else # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) # else # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT # endif // defined(__clang__) && (__clang_major__ < 8) # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) #endif // defined(__has_include) #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) # define CATCH_CONFIG_COUNTER #endif #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) # define CATCH_CONFIG_WINDOWS_SEH #endif // This is set by default, because we assume that unix compilers are posix-signal-compatible by default. #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) # define CATCH_CONFIG_POSIX_SIGNALS #endif // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) # define CATCH_CONFIG_WCHAR #endif #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) # define CATCH_CONFIG_CPP11_TO_STRING #endif #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) # define CATCH_CONFIG_CPP17_OPTIONAL #endif #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) # define CATCH_CONFIG_CPP17_STRING_VIEW #endif #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) # define CATCH_CONFIG_CPP17_VARIANT #endif #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) # define CATCH_CONFIG_CPP17_BYTE #endif #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE #endif #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) # define CATCH_CONFIG_NEW_CAPTURE #endif #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) # define CATCH_CONFIG_DISABLE_EXCEPTIONS #endif #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) # define CATCH_CONFIG_POLYFILL_ISNAN #endif #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) # define CATCH_CONFIG_USE_ASYNC #endif #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) # define CATCH_CONFIG_ANDROID_LOGWRITE #endif #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) # define CATCH_CONFIG_GLOBAL_NEXTAFTER #endif // Even if we do not think the compiler has that warning, we still have // to provide a macro that can be used by the code. #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION #endif #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION #endif #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS #endif // The goal of this macro is to avoid evaluation of the arguments, but // still have the compiler warn on problems inside... #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) #endif #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #elif defined(__clang__) && (__clang_major__ < 5) # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #endif #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) #define CATCH_TRY if ((true)) #define CATCH_CATCH_ALL if ((false)) #define CATCH_CATCH_ANON(type) if ((false)) #else #define CATCH_TRY try #define CATCH_CATCH_ALL catch (...) #define CATCH_CATCH_ANON(type) catch (type) #endif #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #endif // end catch_compiler_capabilities.h #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) #ifdef CATCH_CONFIG_COUNTER # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) #else # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) #endif #include #include #include // We need a dummy global operator<< so we can bring it into Catch namespace later struct Catch_global_namespace_dummy {}; std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); namespace Catch { struct CaseSensitive { enum Choice { Yes, No }; }; class NonCopyable { NonCopyable( NonCopyable const& ) = delete; NonCopyable( NonCopyable && ) = delete; NonCopyable& operator = ( NonCopyable const& ) = delete; NonCopyable& operator = ( NonCopyable && ) = delete; protected: NonCopyable(); virtual ~NonCopyable(); }; struct SourceLineInfo { SourceLineInfo() = delete; SourceLineInfo( char const* _file, std::size_t _line ) noexcept : file( _file ), line( _line ) {} SourceLineInfo( SourceLineInfo const& other ) = default; SourceLineInfo& operator = ( SourceLineInfo const& ) = default; SourceLineInfo( SourceLineInfo&& ) noexcept = default; SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; bool empty() const noexcept { return file[0] == '\0'; } bool operator == ( SourceLineInfo const& other ) const noexcept; bool operator < ( SourceLineInfo const& other ) const noexcept; char const* file; std::size_t line; }; std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); // Bring in operator<< from global namespace into Catch namespace // This is necessary because the overload of operator<< above makes // lookup stop at namespace Catch using ::operator<<; // Use this in variadic streaming macros to allow // >> +StreamEndStop // as well as // >> stuff +StreamEndStop struct StreamEndStop { std::string operator+() const; }; template T const& operator + ( T const& value, StreamEndStop ) { return value; } } #define CATCH_INTERNAL_LINEINFO \ ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) // end catch_common.h namespace Catch { struct RegistrarForTagAliases { RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); }; } // end namespace Catch #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION // end catch_tag_alias_autoregistrar.h // start catch_test_registry.h // start catch_interfaces_testcase.h #include namespace Catch { class TestSpec; struct ITestInvoker { virtual void invoke () const = 0; virtual ~ITestInvoker(); }; class TestCase; struct IConfig; struct ITestCaseRegistry { virtual ~ITestCaseRegistry(); virtual std::vector const& getAllTests() const = 0; virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; }; bool isThrowSafe( TestCase const& testCase, IConfig const& config ); bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); std::vector const& getAllTestCasesSorted( IConfig const& config ); } // end catch_interfaces_testcase.h // start catch_stringref.h #include #include #include #include namespace Catch { /// A non-owning string class (similar to the forthcoming std::string_view) /// Note that, because a StringRef may be a substring of another string, /// it may not be null terminated. class StringRef { public: using size_type = std::size_t; using const_iterator = const char*; private: static constexpr char const* const s_empty = ""; char const* m_start = s_empty; size_type m_size = 0; public: // construction constexpr StringRef() noexcept = default; StringRef( char const* rawChars ) noexcept; constexpr StringRef( char const* rawChars, size_type size ) noexcept : m_start( rawChars ), m_size( size ) {} StringRef( std::string const& stdString ) noexcept : m_start( stdString.c_str() ), m_size( stdString.size() ) {} explicit operator std::string() const { return std::string(m_start, m_size); } public: // operators auto operator == ( StringRef const& other ) const noexcept -> bool; auto operator != (StringRef const& other) const noexcept -> bool { return !(*this == other); } auto operator[] ( size_type index ) const noexcept -> char { assert(index < m_size); return m_start[index]; } public: // named queries constexpr auto empty() const noexcept -> bool { return m_size == 0; } constexpr auto size() const noexcept -> size_type { return m_size; } // Returns the current start pointer. If the StringRef is not // null-terminated, throws std::domain_exception auto c_str() const -> char const*; public: // substrings and searches // Returns a substring of [start, start + length). // If start + length > size(), then the substring is [start, size()). // If start > size(), then the substring is empty. auto substr( size_type start, size_type length ) const noexcept -> StringRef; // Returns the current start pointer. May not be null-terminated. auto data() const noexcept -> char const*; constexpr auto isNullTerminated() const noexcept -> bool { return m_start[m_size] == '\0'; } public: // iterators constexpr const_iterator begin() const { return m_start; } constexpr const_iterator end() const { return m_start + m_size; } }; auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { return StringRef( rawChars, size ); } } // namespace Catch constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { return Catch::StringRef( rawChars, size ); } // end catch_stringref.h // start catch_preprocessor.hpp #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ // MSVC needs more evaluations #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) #else #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) #endif #define CATCH_REC_END(...) #define CATCH_REC_OUT #define CATCH_EMPTY() #define CATCH_DEFER(id) id CATCH_EMPTY() #define CATCH_REC_GET_END2() 0, CATCH_REC_END #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, // and passes userdata as the first parameter to each invocation, // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) #else // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) #endif #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) #else #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) #endif #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) #define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) #define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N #define INTERNAL_CATCH_TYPE_GEN\ template struct TypeList {};\ template\ constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ template class...> struct TemplateTypeList{};\ template class...Cs>\ constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ template\ struct append;\ template\ struct rewrap;\ template class, typename...>\ struct create;\ template class, typename>\ struct convert;\ \ template \ struct append { using type = T; };\ template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ template< template class L1, typename...E1, typename...Rest>\ struct append, TypeList, Rest...> { using type = L1; };\ \ template< template class Container, template class List, typename...elems>\ struct rewrap, List> { using type = TypeList>; };\ template< template class Container, template class List, class...Elems, typename...Elements>\ struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ \ template