[libosmium] 01/05: Imported Upstream version 2.2.0
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Sat Jul 4 13:04:42 UTC 2015
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository libosmium.
commit c64b95a55d1335fadfbc70d9f829bfa31fbc8d01
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sat Jul 4 14:19:12 2015 +0200
Imported Upstream version 2.2.0
---
.travis.yml | 79 +--
CHANGELOG.md | 44 +-
CMakeLists.txt | 65 +-
appveyor.yml | 70 +-
benchmarks/osmium_benchmark_count.cpp | 7 +-
benchmarks/osmium_benchmark_count_tag.cpp | 5 +-
cmake/FindOsmium.cmake | 2 +-
doc/CMakeLists.txt | 2 -
doc/Doxyfile.in | 4 +-
doc/README.md | 2 +-
examples/osmium_count.cpp | 7 +-
examples/osmium_create_node_cache.cpp | 3 +-
examples/osmium_serdump.cpp | 3 +-
examples/osmium_use_node_cache.cpp | 3 +-
include/mmap_for_windows.hpp | 103 ---
include/osmium/area/assembler.hpp | 24 +-
include/osmium/area/detail/segment_list.hpp | 2 +-
include/osmium/area/multipolygon_collector.hpp | 24 +-
include/osmium/builder/builder.hpp | 4 +-
include/osmium/builder/osm_object_builder.hpp | 14 +-
include/osmium/geom/factory.hpp | 164 +++--
include/osmium/geom/geos.hpp | 49 +-
include/osmium/geom/haversine.hpp | 2 +-
include/osmium/geom/mercator_projection.hpp | 1 +
include/osmium/geom/rapid_geojson.hpp | 190 ++++++
include/osmium/geom/tile.hpp | 101 +++
include/osmium/geom/wkb.hpp | 2 +-
include/osmium/handler/dump.hpp | 2 +-
.../mmap_vector_anon.hpp => bool_vector.hpp} | 59 +-
include/osmium/index/detail/mmap_vector_anon.hpp | 21 +-
include/osmium/index/detail/mmap_vector_base.hpp | 82 ++-
include/osmium/index/detail/mmap_vector_file.hpp | 26 +-
include/osmium/index/detail/typed_mmap.hpp | 229 -------
include/osmium/index/detail/vector_map.hpp | 10 +-
include/osmium/index/detail/vector_multimap.hpp | 34 +
include/osmium/index/index.hpp | 2 +-
include/osmium/index/map.hpp | 16 +-
include/osmium/index/map/sparse_mem_table.hpp | 4 +-
include/osmium/io/bzip2_compression.hpp | 2 +-
include/osmium/io/detail/pbf.hpp | 31 -
include/osmium/io/detail/pbf_input_format.hpp | 3 +-
include/osmium/io/detail/pbf_output_format.hpp | 64 +-
include/osmium/io/detail/pbf_parser.hpp | 25 +-
include/osmium/io/detail/pbf_stringtable.hpp | 2 +-
.../io/detail/{pbf.hpp => pbf_type_conv.hpp} | 31 +-
include/osmium/io/detail/read_write.hpp | 2 +-
include/osmium/io/detail/xml_input_format.hpp | 1 +
include/osmium/io/detail/xml_output_format.hpp | 2 +-
include/osmium/io/gzip_compression.hpp | 2 +-
include/osmium/io/reader.hpp | 2 +-
include/osmium/memory/buffer.hpp | 18 +
include/osmium/memory/item.hpp | 2 +-
include/osmium/osm/changeset.hpp | 1 +
include/osmium/osm/diff_object.hpp | 29 +-
include/osmium/osm/item_type.hpp | 20 +
include/osmium/osm/node_ref.hpp | 2 +-
include/osmium/osm/object.hpp | 1 +
include/osmium/osm/relation.hpp | 7 +-
include/osmium/osm/timestamp.hpp | 15 +
include/osmium/osm/types.hpp | 21 -
include/osmium/osm/types_from_string.hpp | 116 ++++
include/osmium/relations/collector.hpp | 4 +-
include/osmium/thread/pool.hpp | 3 +-
include/osmium/thread/queue.hpp | 31 +-
include/osmium/thread/sorted_queue.hpp | 4 +-
include/osmium/util/cast.hpp | 3 +-
include/osmium/util/data_file.hpp | 192 ++++++
.../detail/mmap_vector_anon.hpp => util/delta.hpp} | 71 +-
include/osmium/util/file.hpp | 118 ++++
include/osmium/util/memory_mapping.hpp | 723 +++++++++++++++++++++
include/osmium/util/minmax.hpp | 123 ++++
include/osmium/util/string.hpp | 42 +-
include/osmium/util/verbose_output.hpp | 2 +-
scripts/travis_install.sh | 26 +
scripts/travis_script.sh | 31 +
test/CMakeLists.txt | 96 ++-
test/data-tests/testdata-xml.cpp | 8 +-
test/t/area/test_area_id.cpp | 32 +-
test/t/area/test_node_ref_segment.cpp | 208 +++---
test/t/basic/test_box.cpp | 158 ++---
test/t/basic/test_entity_bits.cpp | 36 +-
test/t/basic/test_location.cpp | 278 ++++----
test/t/basic/test_node_ref.cpp | 94 +--
test/t/basic/test_object_comparisons.cpp | 268 ++++----
test/t/basic/test_timestamp.cpp | 87 ++-
test/t/basic/test_types_from_string.cpp | 90 +++
test/t/buffer/test_buffer_node.cpp | 122 ++--
test/t/buffer/test_buffer_purge.cpp | 14 +-
test/t/geom/test_exception.cpp | 16 +
test/t/geom/test_factory_with_projection.cpp | 42 +-
test/t/geom/test_mercator.cpp | 58 +-
test/t/geom/test_projection.cpp | 18 +
test/t/geom/test_tile.cpp | 93 +++
test/t/geom/test_tile_data.hpp | 475 ++++++++++++++
test/t/geom/test_wkt.cpp | 8 +
test/t/index/test_id_to_location.cpp | 138 ++--
test/t/index/test_typed_mmap.cpp | 99 ---
test/t/io/test_bzip2.cpp | 34 +-
test/t/io/test_file_formats.cpp | 480 +++++++-------
test/t/tags/test_filter.cpp | 302 ++++-----
test/t/tags/test_operators.cpp | 92 +--
test/t/tags/test_tag_list.cpp | 114 ++--
test/t/thread/test_pool.cpp | 7 +-
test/t/util/test_data_file.cpp | 81 +++
test/t/util/test_delta.cpp | 44 ++
test/t/util/test_double.cpp | 50 +-
test/t/util/test_file.cpp | 69 ++
test/t/util/test_memory_mapping.cpp | 393 +++++++++++
test/t/util/test_minmax.cpp | 68 ++
test/t/util/test_options.cpp | 74 +--
test/t/util/test_string.cpp | 107 +--
111 files changed, 5265 insertions(+), 2321 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 73dff72..5499433 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,46 +6,49 @@
language: cpp
-compiler:
- - gcc
- - clang
-
-env:
- - CONFIGURATION=Dev
- - CONFIGURATION=Release
-
-before_install:
- # we need at least g++-4.8 for c++11 features
- - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test
- - sudo apt-get update --yes --quiet
+sudo: required
+
+matrix:
+ include:
+ - os: linux
+ compiler: clang
+ env: BUILD_TYPE=Dev
+ - os: linux
+ compiler: clang
+ env: BUILD_TYPE=Release
+ - os: linux
+ compiler: gcc
+ env: BUILD_TYPE=Dev
+ - os: linux
+ compiler: gcc
+ env: BUILD_TYPE=Release
+ - os: osx
+ compiler: clang
+ env: BUILD_TYPE=Dev
+ - os: osx
+ compiler: clang
+ env: BUILD_TYPE=Release
+
+# http://docs.travis-ci.com/user/apt/
+addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-4.8
+ - gcc-4.8
+ - libboost-dev
+ - libboost-program-options-dev
+ - libgeos++-dev
+ - libproj-dev
+ - libprotobuf-dev
+ - libsparsehash-dev
+ - protobuf-compiler
+ - spatialite-bin
install:
- - cd ..
- # upgrade compilers
- - sudo apt-get install --yes gcc-4.8 g++-4.8
- # make sure 'cpp' is the just installed current one
- - sudo rm /usr/bin/cpp
- - sudo ln -s /usr/bin/cpp-4.8 /usr/bin/cpp
- # upgrade libosmium dependencies
- - sudo apt-get install --yes make libboost-dev libboost-program-options-dev libsparsehash-dev libprotobuf-dev protobuf-compiler libgeos++-dev libproj-dev libgdal1h libgdal-dev
- - git clone https://github.com/osmcode/osm-testdata.git
- # OSMPBF is too old, install from git
- #- sudo apt-get install --yes libosmpbf-dev
- - git clone https://github.com/scrosby/OSM-binary.git
- - cd OSM-binary/src
- - make
- - sudo make install
- - cd ../..
- - cd libosmium
-
-before_script:
- - true
+ - scripts/travis_install.sh
script:
- - if [ "${CXX}" = 'g++' ]; then export CXX=g++-4.8; fi;
- - mkdir build
- - cd build
- - cmake -LA -DCMAKE_BUILD_TYPE=${CONFIGURATION} ..
- - make VERBOSE=1
- - ctest --output-on-failure
+ - scripts/travis_script.sh
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4c345a4..3e7bea6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,47 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased] -
+### Added
+
+### Changed
+
+### Fixed
+
+## [2.2.0] - 2015-07-04
+
+### Added
+
+- Conversion functions for some low-level types.
+- BoolVector index class.
+- `min_op`/`max_op` utility functions.
+- More tests here and there.
+- Helper methods `is_between()` and `is_visible_at()` to DiffObject.
+- GeoJSON factory using the RapidJSON library.
+- Support for tile calculations.
+- Create simple polygons from ways in geom factories.
+- `MemoryMapping` and `TypedMemoryMapping` helper classes.
+- `close()` function to `mmap_vector_base` class.
+- Function on `Buffer` class to get iterator to specific offset.
+- Explicit cast operator from `osmium::Timestamp` to `uint32_t`.
+
+### Changed
+
+- Throw exception on illegal values in functions parsing strings to get ids,
+ versions, etc.
+- Improved error message for geometry exceptions.
+
+### Fixed
+
+- Throw exception from `dump_as_array()` and `dump_as_list()` functions if not
+ implemented in an index.
+- After writing OSM files, program could stall up to a second.
+- Dense location store was written out only partially.
+- Use `uint64_t` as counter in benchmarks, so there can be no overflows.
+- Example programs now read packed XML files, too.
+- Refactoring of memory mapping code. Removes leak on Windows.
+- Better check for invalid locations.
+- Mark `cbegin()` and `cend()` of `mmap_vector_base` as const functions.
+
## [2.1.0] - 2015-03-31
### Added
@@ -26,6 +67,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
Doxygen (up to version 1.8.8). This version contains a workaround to fix
this.
-[unreleased]: https://github.com/osmcode/libosmium/compare/v2.1.0...HEAD
+[unreleased]: https://github.com/osmcode/libosmium/compare/v2.2.0...HEAD
+[2.2.0]: https://github.com/osmcode/libosmium/compare/v2.1.0...v2.2.0
[2.1.0]: https://github.com/osmcode/libosmium/compare/v2.0.0...v2.1.0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a277765..f01a20b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,6 +9,8 @@
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
#-----------------------------------------------------------------------------
#
@@ -16,7 +18,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
#
#-----------------------------------------------------------------------------
-set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel;Dev"
+set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel;Dev;Coverage"
CACHE STRING
"List of available configuration types"
FORCE)
@@ -24,11 +26,13 @@ set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel;Dev"
project(libosmium)
set(LIBOSMIUM_VERSION_MAJOR 2)
-set(LIBOSMIUM_VERSION_MINOR 1)
+set(LIBOSMIUM_VERSION_MINOR 2)
set(LIBOSMIUM_VERSION_PATCH 0)
set(LIBOSMIUM_VERSION
- ${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH})
+ "${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}"
+ CACHE STRING
+ "Libosmium version")
#-----------------------------------------------------------------------------
@@ -55,6 +59,57 @@ option(BUILD_DATA_TESTS "compile data tests, please run them with ctest" ${dev_b
#-----------------------------------------------------------------------------
#
+# Coverage support
+#
+#-----------------------------------------------------------------------------
+
+include(CheckCXXCompilerFlag)
+check_cxx_compiler_flag("-fkeep-inline-functions" HAS_KEEP_INLINE_FUNCTIONS)
+if(HAS_KEEP_INLINE_FUNCTIONS)
+ set(extra_coverage_flags_ "-fkeep-inline-functions")
+endif()
+
+set(CMAKE_CXX_FLAGS_COVERAGE
+ "-g -O0 -fno-inline-functions -fno-inline --coverage ${extra_coverage_flags_}"
+ CACHE STRING "Flags used by the compiler during coverage builds.")
+
+set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ "--coverage"
+ CACHE STRING "Flags used by the linker during coverage builds.")
+
+if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
+ if(BUILD_EXAMPLES OR BUILD_HEADERS OR BUILD_BENCHMARKS OR BUILD_DATA_TESTS)
+ message(WARNING "Coverage builds don't work for anything but the unit tests")
+ endif()
+
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ string(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "llvm-cov-\\1.\\2"
+ gcov_ ${CMAKE_CXX_COMPILER_VERSION})
+ else()
+ set(gcov_ "gcov")
+ endif()
+
+ find_program(GCOV ${gcov_} DOC "Coverage tool")
+ find_program(GCOVR "gcovr" DOC "Coverage report tool")
+
+ set(coverage_report_dir "${CMAKE_BINARY_DIR}/coverage")
+ file(MAKE_DIRECTORY ${coverage_report_dir})
+ add_custom_target(coverage
+ ${GCOVR}
+ ${CMAKE_BINARY_DIR}
+ --root=${CMAKE_SOURCE_DIR}
+ --html --html-details
+ #--verbose
+ #--keep
+ '--filter=.*include/osmium.*'
+ --sort-percentage
+ --gcov-executable=${GCOV}
+ --output=${coverage_report_dir}/index.html)
+endif()
+
+
+#-----------------------------------------------------------------------------
+#
# Find external dependencies
#
#-----------------------------------------------------------------------------
@@ -111,8 +166,10 @@ endif()
#-----------------------------------------------------------------------------
if(MSVC)
set(USUAL_COMPILE_OPTIONS "/Ox")
+ set(USUAL_LINK_OPTIONS "/debug")
else()
set(USUAL_COMPILE_OPTIONS "-O3 -g")
+ set(USUAL_LINK_OPTIONS "")
endif()
if(WIN32)
@@ -124,7 +181,7 @@ set(CMAKE_CXX_FLAGS_DEV "${USUAL_COMPILE_OPTIONS}"
CACHE STRING "Flags used by the compiler during developer builds."
FORCE)
-set(CMAKE_EXE_LINKER_FLAGS_DEV ""
+set(CMAKE_EXE_LINKER_FLAGS_DEV "${USUAL_LINK_OPTIONS}"
CACHE STRING "Flags used by the linker during developer builds."
FORCE)
mark_as_advanced(
diff --git a/appveyor.yml b/appveyor.yml
index b3b3f51..965603b 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -15,6 +15,8 @@ branches:
only:
- master
+shallow_clone: true
+
# Operating system (build VM template)
os: Visual Studio 2014 CTP4
@@ -50,8 +52,8 @@ install:
#cmake cannot find it otherwise
- set LIBBZIP2=%LODEPSDIR%\bzip2\lib\libbz2.lib
- set LIBBZIP2=%LIBBZIP2:\=/%
- - ps: Start-FileDownload https://mapnik.s3.amazonaws.com/deps/cmake-3.1.0-win32-x86.7z -FileName cm.7z
- - ps: Start-FileDownload https://mapnik.s3.amazonaws.com/dist/dev/libosmium-deps-win-14.0-x64.7z -FileName lodeps.7z
+ - ps: Start-FileDownload https://mapbox.s3.amazonaws.com/windows-builds/windows-build-deps/cmake-3.1.0-win32-x86.7z -FileName cm.7z
+ - ps: Start-FileDownload https://mapbox.s3.amazonaws.com/windows-builds/windows-build-deps/libosmium-deps-win-14.0-x64.7z -FileName lodeps.7z
- 7z x cm.7z | %windir%\system32\find "ing archive"
- 7z x lodeps.7z | %windir%\system32\find "ing archive"
- echo %LODEPSDIR%
@@ -59,18 +61,74 @@ install:
- echo our own cmake
- cmake -version
- cd c:\projects
- - git clone https://github.com/osmcode/osm-testdata.git
+ - git clone --depth 1 https://github.com/osmcode/osm-testdata.git
build_script:
- cd c:\projects\libosmium
- mkdir build
- cd build
- echo %config%
- - cmake .. -LA -G "Visual Studio 14 Win64" -DOsmium_DEBUG=TRUE -DCMAKE_BUILD_TYPE=%config% -DBOOST_ROOT=%LODEPSDIR%\boost -DBoost_PROGRAM_OPTIONS_LIBRARY=%LODEPSDIR%\boost\lib\libboost_program_options-vc140-mt-1_57.lib -DOSMPBF_LIBRARY=%LODEPSDIR%\osmpbf\lib\osmpbf.lib -DOSMPBF_INCLUDE_DIR=%LODEPSDIR%\osmpbf\include -DPROTOBUF_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf.lib -DPROTOBUF_LITE_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf-lite.lib -DPROTOBUF_INCLUDE_DIR=%LODEPSDIR%\protobu [...]
+ # This will produce lots of LNK4099 warnings which can be ignored.
+ # Unfortunately they can't be disabled, see
+ # http://stackoverflow.com/questions/661606/visual-c-how-to-disable-specific-linker-warnings
+ - cmake .. -LA -G "Visual Studio 14 Win64"
+ -DOsmium_DEBUG=TRUE
+ -DCMAKE_BUILD_TYPE=%config%
+ -DBUILD_HEADERS=OFF
+ -DBOOST_ROOT=%LODEPSDIR%\boost
+ -DBoost_PROGRAM_OPTIONS_LIBRARY=%LODEPSDIR%\boost\lib\libboost_program_options-vc140-mt-1_57.lib
+ -DOSMPBF_LIBRARY=%LODEPSDIR%\osmpbf\lib\osmpbf.lib
+ -DOSMPBF_INCLUDE_DIR=%LODEPSDIR%\osmpbf\include
+ -DPROTOBUF_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf.lib
+ -DPROTOBUF_LITE_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf-lite.lib
+ -DPROTOBUF_INCLUDE_DIR=%LODEPSDIR%\protobuf\include
+ -DZLIB_LIBRARY=%LODEPSDIR%\zlib\lib\zlibwapi.lib
+ -DZLIB_INCLUDE_DIR=%LODEPSDIR%\zlib\include
+ -DEXPAT_LIBRARY=%LODEPSDIR%\expat\lib\libexpat.lib
+ -DEXPAT_INCLUDE_DIR=%LODEPSDIR%\expat\include
+ -DBZIP2_LIBRARIES=%LIBBZIP2%
+ -DBZIP2_INCLUDE_DIR=%LODEPSDIR%\bzip2\include
+ -DGDAL_LIBRARY=%LODEPSDIR%\gdal\lib\gdal_i.lib
+ -DGDAL_INCLUDE_DIR=%LODEPSDIR%\gdal\include
+ -DGEOS_LIBRARY=%LODEPSDIR%\geos\lib\geos.lib
+ -DGEOS_INCLUDE_DIR=%LODEPSDIR%\geos\include
+ -DPROJ_LIBRARY=%LODEPSDIR%\proj\lib\proj.lib
+ -DPROJ_INCLUDE_DIR=%LODEPSDIR%\proj\include
+ -DSPARSEHASH_INCLUDE_DIR=%LODEPSDIR%\sparsehash\include
+ -DGETOPT_LIBRARY=%LODEPSDIR%\wingetopt\lib\wingetopt.lib
+ -DGETOPT_INCLUDE_DIR=%LODEPSDIR%\wingetopt\include
- msbuild libosmium.sln /p:Configuration=%config% /toolsversion:14.0 /p:Platform=x64 /p:PlatformToolset=v140
- #- cmake .. -LA -G "NMake Makefiles" -DOsmium_DEBUG=TRUE -DCMAKE_BUILD_TYPE=%config% -DBOOST_ROOT=%LODEPSDIR%\boost -DBoost_PROGRAM_OPTIONS_LIBRARY=%LODEPSDIR%\boost\lib\libboost_program_options-vc140-mt-1_57.lib -DOSMPBF_LIBRARY=%LODEPSDIR%\osmpbf\lib\osmpbf.lib -DOSMPBF_INCLUDE_DIR=%LODEPSDIR%\osmpbf\include -DPROTOBUF_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf.lib -DPROTOBUF_LITE_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf-lite.lib -DPROTOBUF_INCLUDE_DIR=%LODEPSDIR%\protobuf\incl [...]
+ #- cmake .. -LA -G "NMake Makefiles"
+ # -DOsmium_DEBUG=TRUE
+ # -DCMAKE_BUILD_TYPE=%config%
+ # -DBOOST_ROOT=%LODEPSDIR%\boost
+ # -DBoost_PROGRAM_OPTIONS_LIBRARY=%LODEPSDIR%\boost\lib\libboost_program_options-vc140-mt-1_57.lib
+ # -DOSMPBF_LIBRARY=%LODEPSDIR%\osmpbf\lib\osmpbf.lib
+ # -DOSMPBF_INCLUDE_DIR=%LODEPSDIR%\osmpbf\include
+ # -DPROTOBUF_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf.lib
+ # -DPROTOBUF_LITE_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf-lite.lib
+ # -DPROTOBUF_INCLUDE_DIR=%LODEPSDIR%\protobuf\include
+ # -DZLIB_LIBRARY=%LODEPSDIR%\zlib\lib\zlibwapi.lib
+ # -DZLIB_INCLUDE_DIR=%LODEPSDIR%\zlib\include
+ # -DEXPAT_LIBRARY=%LODEPSDIR%\expat\lib\libexpat.lib
+ # -DEXPAT_INCLUDE_DIR=%LODEPSDIR%\expat\include
+ # -DBZIP2_LIBRARIES=%LIBBZIP2%
+ # -DBZIP2_INCLUDE_DIR=%LODEPSDIR%\bzip2\include
+ # -DGDAL_LIBRARY=%LODEPSDIR%\gdal\lib\gdal_i.lib
+ # -DGDAL_INCLUDE_DIR=%LODEPSDIR%\gdal\include
+ # -DGEOS_LIBRARY=%LODEPSDIR%\geos\lib\geos.lib
+ # -DGEOS_INCLUDE_DIR=%LODEPSDIR%\geos\include
+ # -DPROJ_LIBRARY=%LODEPSDIR%\proj\lib\proj.lib
+ # -DPROJ_INCLUDE_DIR=%LODEPSDIR%\proj\include
+ # -DSPARSEHASH_INCLUDE_DIR=%LODEPSDIR%\sparsehash\include
+ # -DGETOPT_LIBRARY=%LODEPSDIR%\wingetopt\lib\wingetopt.lib
+ # -DGETOPT_INCLUDE_DIR=%LODEPSDIR%\wingetopt\include
#- nmake
test_script:
- - ctest --output-on-failure -C %config%
+ # "-E testdata-overview" exempts one test we know fails on Appveyor
+ # because we currently don't have spatialite support.
+ - ctest --output-on-failure
+ -C %config%
+ -E testdata-overview
diff --git a/benchmarks/osmium_benchmark_count.cpp b/benchmarks/osmium_benchmark_count.cpp
index 701d6fa..4409448 100644
--- a/benchmarks/osmium_benchmark_count.cpp
+++ b/benchmarks/osmium_benchmark_count.cpp
@@ -4,6 +4,7 @@
*/
+#include <cstdint>
#include <iostream>
#include <osmium/io/any_input.hpp>
@@ -12,9 +13,9 @@
struct CountHandler : public osmium::handler::Handler {
- int nodes = 0;
- int ways = 0;
- int relations = 0;
+ uint64_t nodes = 0;
+ uint64_t ways = 0;
+ uint64_t relations = 0;
void node(osmium::Node&) {
++nodes;
diff --git a/benchmarks/osmium_benchmark_count_tag.cpp b/benchmarks/osmium_benchmark_count_tag.cpp
index 4a77c34..ca6771c 100644
--- a/benchmarks/osmium_benchmark_count_tag.cpp
+++ b/benchmarks/osmium_benchmark_count_tag.cpp
@@ -4,6 +4,7 @@
*/
+#include <cstdint>
#include <iostream>
#include <osmium/io/any_input.hpp>
@@ -12,8 +13,8 @@
struct CountHandler : public osmium::handler::Handler {
- int counter = 0;
- int all = 0;
+ uint64_t counter = 0;
+ uint64_t all = 0;
void node(osmium::Node& node) {
++all;
diff --git a/cmake/FindOsmium.cmake b/cmake/FindOsmium.cmake
index 1de41a0..56a5a4d 100644
--- a/cmake/FindOsmium.cmake
+++ b/cmake/FindOsmium.cmake
@@ -325,7 +325,7 @@ endif()
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 -Wno-return-type" CACHE STRING "Recommended warning options for libosmium")
+ 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")
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 9d69a16..5ea819b 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -21,8 +21,6 @@ if(DOXYGEN_FOUND)
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen" VERBATIM
)
-# install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html"
-# DESTINATION "share/doc/libosmium-dev")
else()
message(STATUS "Looking for doxygen - not found")
message(STATUS " Disabled making of documentation.")
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index 6bc0185..d5ed13d 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -1080,7 +1080,7 @@ HTML_STYLESHEET =
# see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_EXTRA_STYLESHEET = doc/osmium.css
+HTML_EXTRA_STYLESHEET = "@PROJECT_SOURCE_DIR@/doc/osmium.css"
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
@@ -1128,7 +1128,7 @@ HTML_COLORSTYLE_GAMMA = 80
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_TIMESTAMP = YES
+HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
diff --git a/doc/README.md b/doc/README.md
index 7ca8e7c..5e1cf4b 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -3,6 +3,6 @@ The `header.html` is created with:
`doxygen -w html header.html footer.html stylesheet.css`
-This might have to be rn again for newer Doxygen versions. After that add
+This might have to be run again for newer Doxygen versions. After that add
changes back in.
diff --git a/examples/osmium_count.cpp b/examples/osmium_count.cpp
index dca18bf..e249687 100644
--- a/examples/osmium_count.cpp
+++ b/examples/osmium_count.cpp
@@ -7,6 +7,7 @@
*/
+#include <cstdint>
#include <iostream>
#include <osmium/io/any_input.hpp>
@@ -15,9 +16,9 @@
struct CountHandler : public osmium::handler::Handler {
- int nodes = 0;
- int ways = 0;
- int relations = 0;
+ uint64_t nodes = 0;
+ uint64_t ways = 0;
+ uint64_t relations = 0;
void node(osmium::Node&) {
++nodes;
diff --git a/examples/osmium_create_node_cache.cpp b/examples/osmium_create_node_cache.cpp
index 74f7596..b52bd17 100644
--- a/examples/osmium_create_node_cache.cpp
+++ b/examples/osmium_create_node_cache.cpp
@@ -12,8 +12,7 @@
#include <fcntl.h>
#include <iostream>
-#include <osmium/io/pbf_input.hpp>
-#include <osmium/io/xml_input.hpp>
+#include <osmium/io/any_input.hpp>
#include <osmium/index/map/dummy.hpp>
#include <osmium/index/map/dense_mmap_array.hpp>
diff --git a/examples/osmium_serdump.cpp b/examples/osmium_serdump.cpp
index a774a8d..15dce3c 100644
--- a/examples/osmium_serdump.cpp
+++ b/examples/osmium_serdump.cpp
@@ -19,8 +19,7 @@
# include <direct.h>
#endif
-#include <osmium/io/pbf_input.hpp>
-#include <osmium/io/xml_input.hpp>
+#include <osmium/io/any_input.hpp>
#include <osmium/handler/disk_store.hpp>
#include <osmium/handler/object_relations.hpp>
diff --git a/examples/osmium_use_node_cache.cpp b/examples/osmium_use_node_cache.cpp
index 6b8f964..d800e8d 100644
--- a/examples/osmium_use_node_cache.cpp
+++ b/examples/osmium_use_node_cache.cpp
@@ -12,8 +12,7 @@
#include <fcntl.h>
#include <iostream>
-#include <osmium/io/pbf_input.hpp>
-#include <osmium/io/xml_input.hpp>
+#include <osmium/io/any_input.hpp>
#include <osmium/index/map/dummy.hpp>
#include <osmium/index/map/dense_file_array.hpp>
diff --git a/include/mmap_for_windows.hpp b/include/mmap_for_windows.hpp
deleted file mode 100644
index abe62d6..0000000
--- a/include/mmap_for_windows.hpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef MMAP_FOR_WINDOWS_HPP
-#define MMAP_FOR_WINDOWS_HPP
-
-/* mmap() replacement for Windows
- *
- * Author: Mike Frysinger <vapier at gentoo.org>
- * Placed into the public domain
- */
-
-/* References:
- * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
- * CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
- * MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
- * UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
- */
-
-#include <io.h>
-#include <windows.h>
-#include <sys/types.h>
-
-#define PROT_READ 0x1
-#define PROT_WRITE 0x2
-/* This flag is only available in WinXP+ */
-#ifdef FILE_MAP_EXECUTE
-#define PROT_EXEC 0x4
-#else
-#define PROT_EXEC 0x0
-#define FILE_MAP_EXECUTE 0
-#endif
-
-#define MAP_SHARED 0x01
-#define MAP_PRIVATE 0x02
-#define MAP_ANONYMOUS 0x20
-#define MAP_ANON MAP_ANONYMOUS
-#define MAP_FAILED ((void *) -1)
-
-static DWORD dword_hi(uint64_t x) {
- return static_cast<DWORD>(x >> 32);
-}
-
-static DWORD dword_lo(uint64_t x) {
- return static_cast<DWORD>(x & 0xffffffff);
-}
-
-static void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
-{
- if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
- return MAP_FAILED;
- if (fd == -1) {
- if (!(flags & MAP_ANON) || offset)
- return MAP_FAILED;
- } else if (flags & MAP_ANON)
- return MAP_FAILED;
-
- DWORD flProtect;
- if (prot & PROT_WRITE) {
- if (prot & PROT_EXEC)
- flProtect = PAGE_EXECUTE_READWRITE;
- else
- flProtect = PAGE_READWRITE;
- } else if (prot & PROT_EXEC) {
- if (prot & PROT_READ)
- flProtect = PAGE_EXECUTE_READ;
- else if (prot & PROT_EXEC)
- flProtect = PAGE_EXECUTE;
- } else
- flProtect = PAGE_READONLY;
-
- uint64_t end = static_cast<uint64_t>(length) + offset;
- HANDLE mmap_fd;
- if (fd == -1)
- mmap_fd = INVALID_HANDLE_VALUE;
- else
- mmap_fd = (HANDLE)_get_osfhandle(fd);
-
- HANDLE h = CreateFileMapping(mmap_fd, NULL, flProtect, dword_hi(end), dword_lo(end), NULL);
- if (h == NULL)
- return MAP_FAILED;
-
- DWORD dwDesiredAccess;
- if (prot & PROT_WRITE)
- dwDesiredAccess = FILE_MAP_WRITE;
- else
- dwDesiredAccess = FILE_MAP_READ;
- if (prot & PROT_EXEC)
- dwDesiredAccess |= FILE_MAP_EXECUTE;
- if (flags & MAP_PRIVATE)
- dwDesiredAccess |= FILE_MAP_COPY;
- void *ret = MapViewOfFile(h, dwDesiredAccess, dword_hi(offset), dword_lo(offset), length);
- if (ret == NULL) {
- CloseHandle(h);
- ret = MAP_FAILED;
- }
- return ret;
-}
-
-static int munmap(void *addr, size_t length)
-{
- return UnmapViewOfFile(addr) ? 0 : -1;
- /* ruh-ro, we leaked handle from CreateFileMapping() ... */
-}
-
-#endif
diff --git a/include/osmium/area/assembler.hpp b/include/osmium/area/assembler.hpp
index db769dd..f172991 100644
--- a/include/osmium/area/assembler.hpp
+++ b/include/osmium/area/assembler.hpp
@@ -65,7 +65,7 @@ namespace osmium {
// Enables debug output to stderr
bool debug;
- explicit AssemblerConfig(osmium::area::ProblemReporter* pr = nullptr, bool d=false) :
+ explicit AssemblerConfig(osmium::area::ProblemReporter* pr = nullptr, bool d = false) :
problem_reporter(pr),
debug(d) {
}
@@ -74,7 +74,7 @@ namespace osmium {
* Enable or disable debug output to stderr. This is for Osmium
* developers only.
*/
- void enable_debug_output(bool d=true) {
+ void enable_debug_output(bool d = true) {
debug = d;
}
@@ -171,7 +171,7 @@ namespace osmium {
}
void add_tags_to_area(osmium::builder::AreaBuilder& builder, const osmium::Relation& relation) const {
- auto count = std::count_if(relation.tags().begin(), relation.tags().end(), filter());
+ const auto count = std::count_if(relation.tags().begin(), relation.tags().end(), filter());
if (debug()) {
std::cerr << " found " << count << " tags on relation (without ignored ones)\n";
@@ -331,7 +331,7 @@ namespace osmium {
if (debug()) {
std::cerr << " has_closed_subring_back()\n";
}
- auto end = ring.segments().end();
+ const auto end = ring.segments().end();
for (auto it = ring.segments().begin() + 1; it != end - 1; ++it) {
if (has_same_location(nr, it->first())) {
split_off_subring(ring, it, it, end);
@@ -348,7 +348,7 @@ namespace osmium {
if (debug()) {
std::cerr << " has_closed_subring_front()\n";
}
- auto end = ring.segments().end();
+ const auto end = ring.segments().end();
for (auto it = ring.segments().begin() + 1; it != end - 1; ++it) {
if (has_same_location(nr, it->second())) {
split_off_subring(ring, it, ring.segments().begin(), it+1);
@@ -366,22 +366,22 @@ namespace osmium {
osmium::area::detail::ProtoRing::segments_type segments(ring.segments().size());
std::copy(ring.segments().begin(), ring.segments().end(), segments.begin());
std::sort(segments.begin(), segments.end());
- auto it = std::adjacent_find(segments.begin(), segments.end(), [this](const osmium::area::detail::NodeRefSegment& s1, const osmium::area::detail::NodeRefSegment& s2) {
+ const auto it = std::adjacent_find(segments.begin(), segments.end(), [this](const osmium::area::detail::NodeRefSegment& s1, const osmium::area::detail::NodeRefSegment& s2) {
return has_same_location(s1.first(), s2.first());
});
if (it == segments.end()) {
return false;
}
- auto r1 = std::find_first_of(ring.segments().begin(), ring.segments().end(), it, it+1);
+ const auto r1 = std::find_first_of(ring.segments().begin(), ring.segments().end(), it, it+1);
assert(r1 != ring.segments().end());
- auto r2 = std::find_first_of(ring.segments().begin(), ring.segments().end(), it+1, it+2);
+ const auto r2 = std::find_first_of(ring.segments().begin(), ring.segments().end(), it+1, it+2);
assert(r2 != ring.segments().end());
if (debug()) {
std::cerr << " found subring in ring " << ring << " at " << it->first() << "\n";
}
- auto m = std::minmax(r1, r2);
+ const auto m = std::minmax(r1, r2);
ProtoRing new_ring(m.first, m.second);
ring.remove_segments(m.first, m.second);
@@ -445,7 +445,7 @@ namespace osmium {
}
bool add_to_existing_ring(osmium::area::detail::NodeRefSegment segment) {
- int n=0;
+ int n = 0;
for (auto& ring : m_rings) {
if (debug()) {
std::cerr << " check against ring " << n << " " << ring;
@@ -537,7 +537,7 @@ namespace osmium {
}
for (const auto ringptr : m_outer_rings) {
- for (const auto segment : ringptr->segments()) {
+ for (const auto& segment : ringptr->segments()) {
if (!segment.role_outer()) {
++m_inner_outer_mismatches;
if (debug()) {
@@ -550,7 +550,7 @@ namespace osmium {
}
}
for (const auto ringptr : m_inner_rings) {
- for (const auto segment : ringptr->segments()) {
+ for (const auto& segment : ringptr->segments()) {
if (!segment.role_inner()) {
++m_inner_outer_mismatches;
if (debug()) {
diff --git a/include/osmium/area/detail/segment_list.hpp b/include/osmium/area/detail/segment_list.hpp
index 12ec97f..ca6071e 100644
--- a/include/osmium/area/detail/segment_list.hpp
+++ b/include/osmium/area/detail/segment_list.hpp
@@ -99,7 +99,7 @@ namespace osmium {
* Enable or disable debug output to stderr. This is for Osmium
* developers only.
*/
- void enable_debug_output(bool debug=true) noexcept {
+ void enable_debug_output(bool debug = true) noexcept {
m_debug = debug;
}
diff --git a/include/osmium/area/multipolygon_collector.hpp b/include/osmium/area/multipolygon_collector.hpp
index 84a5262..2cb8fe1 100644
--- a/include/osmium/area/multipolygon_collector.hpp
+++ b/include/osmium/area/multipolygon_collector.hpp
@@ -41,6 +41,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/memory/buffer.hpp>
#include <osmium/osm/item_type.hpp>
+#include <osmium/osm/location.hpp>
#include <osmium/osm/relation.hpp>
#include <osmium/osm/tag.hpp>
#include <osmium/osm/way.hpp>
@@ -49,8 +50,6 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
- struct invalid_location;
-
namespace relations {
class RelationMeta;
}
@@ -107,8 +106,8 @@ namespace osmium {
}
/**
- * We are interested in all relations tagged with type=multipolygon or
- * type=boundary.
+ * We are interested in all relations tagged with type=multipolygon
+ * or type=boundary.
*
* Overwritten from the base class.
*/
@@ -142,15 +141,22 @@ namespace osmium {
* Overwritten from the base class.
*/
void way_not_in_any_relation(const osmium::Way& way) {
- if (way.nodes().size() > 3 && way.ends_have_same_location()) {
- // way is closed and has enough nodes, build simple multipolygon
- try {
+ // you need at least 4 nodes to make up a polygon
+ if (way.nodes().size() <= 3) {
+ return;
+ }
+ try {
+ if (!way.nodes().front().location() || !way.nodes().back().location()) {
+ throw osmium::invalid_location("invalid location");
+ }
+ if (way.ends_have_same_location()) {
+ // way is closed and has enough nodes, build simple multipolygon
TAssembler assembler(m_assembler_config);
assembler(way, m_output_buffer);
possibly_flush_output_buffer();
- } catch (osmium::invalid_location&) {
- // XXX ignore
}
+ } catch (osmium::invalid_location&) {
+ // XXX ignore
}
}
diff --git a/include/osmium/builder/builder.hpp b/include/osmium/builder/builder.hpp
index 6606025..dcb95e2 100644
--- a/include/osmium/builder/builder.hpp
+++ b/include/osmium/builder/builder.hpp
@@ -100,7 +100,7 @@ namespace osmium {
* parent item (if any).
*
*/
- void add_padding(bool self=false) {
+ void add_padding(bool self = false) {
auto padding = osmium::memory::align_bytes - (size() % osmium::memory::align_bytes);
if (padding != osmium::memory::align_bytes) {
std::fill_n(m_buffer.reserve_space(padding), padding, 0);
@@ -175,7 +175,7 @@ namespace osmium {
public:
- explicit ObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
+ explicit ObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
Builder(buffer, parent, sizeof(TItem)) {
new (&item()) TItem();
}
diff --git a/include/osmium/builder/osm_object_builder.hpp b/include/osmium/builder/osm_object_builder.hpp
index b88765e..058f89e 100644
--- a/include/osmium/builder/osm_object_builder.hpp
+++ b/include/osmium/builder/osm_object_builder.hpp
@@ -61,7 +61,7 @@ namespace osmium {
public:
- explicit TagListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
+ explicit TagListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<TagList>(buffer, parent) {
}
@@ -97,7 +97,7 @@ namespace osmium {
public:
- explicit NodeRefListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
+ explicit NodeRefListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<T>(buffer, parent) {
}
@@ -110,7 +110,7 @@ namespace osmium {
static_cast<Builder*>(this)->add_size(sizeof(osmium::NodeRef));
}
- void add_node_ref(const object_id_type ref, const osmium::Location location=Location()) {
+ void add_node_ref(const object_id_type ref, const osmium::Location location = Location()) {
add_node_ref(NodeRef(ref, location));
}
@@ -160,7 +160,7 @@ namespace osmium {
public:
- explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
+ explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<RelationMemberList>(buffer, parent) {
}
@@ -215,7 +215,7 @@ namespace osmium {
public:
- explicit OSMObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
+ explicit OSMObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<T>(buffer, parent) {
static_cast<Builder*>(this)->reserve_space_for<string_size_type>();
static_cast<Builder*>(this)->add_size(sizeof(string_size_type));
@@ -237,7 +237,7 @@ namespace osmium {
public:
- explicit WayBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
+ explicit WayBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
OSMObjectBuilder<osmium::Way>(buffer, parent) {
}
@@ -254,7 +254,7 @@ namespace osmium {
public:
- explicit AreaBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
+ explicit AreaBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
OSMObjectBuilder<osmium::Area>(buffer, parent) {
}
diff --git a/include/osmium/geom/factory.hpp b/include/osmium/geom/factory.hpp
index a0a2080..9be050d 100644
--- a/include/osmium/geom/factory.hpp
+++ b/include/osmium/geom/factory.hpp
@@ -54,14 +54,43 @@ namespace osmium {
* Exception thrown when an invalid geometry is encountered. An example
* would be a linestring with less than two points.
*/
- struct geometry_error : public std::runtime_error {
+ class geometry_error : public std::runtime_error {
+
+ std::string m_message;
+ osmium::object_id_type m_id;
+
+ public:
+
+ geometry_error(const std::string& message, const char* object_type = "", osmium::object_id_type id = 0) :
+ std::runtime_error(message),
+ m_message(message),
+ m_id(id) {
+ if (m_id != 0) {
+ m_message += " (";
+ m_message += object_type;
+ m_message += "_id=";
+ m_message += std::to_string(m_id);
+ m_message += ")";
+ }
+ }
+
+ void set_id(const char* object_type, osmium::object_id_type id) {
+ if (m_id == 0 && id != 0) {
+ m_message += " (";
+ m_message += object_type;
+ m_message += "_id=";
+ m_message += std::to_string(id);
+ m_message += ")";
+ }
+ m_id = id;
+ }
- geometry_error(const std::string& what) :
- std::runtime_error(what) {
+ osmium::object_id_type id() const noexcept {
+ return m_id;
}
- geometry_error(const char* what) :
- std::runtime_error(what) {
+ virtual const char* what() const noexcept override {
+ return m_message.c_str();
}
}; // struct geometry_error
@@ -174,11 +203,21 @@ namespace osmium {
}
point_type create_point(const osmium::Node& node) {
- return create_point(node.location());
+ try {
+ return create_point(node.location());
+ } catch (osmium::geometry_error& e) {
+ e.set_id("node", node.id());
+ throw;
+ }
}
point_type create_point(const osmium::NodeRef& node_ref) {
- return create_point(node_ref.location());
+ try {
+ return create_point(node_ref.location());
+ } catch (osmium::geometry_error& e) {
+ e.set_id("node", node_ref.ref());
+ throw;
+ }
}
/* LineString */
@@ -214,7 +253,7 @@ namespace osmium {
return m_impl.linestring_finish(num_points);
}
- linestring_type create_linestring(const osmium::WayNodeList& wnl, use_nodes un=use_nodes::unique, direction dir=direction::forward) {
+ linestring_type create_linestring(const osmium::WayNodeList& wnl, use_nodes un = use_nodes::unique, direction dir = direction::forward) {
linestring_start();
size_t num_points = 0;
@@ -240,14 +279,19 @@ namespace osmium {
}
if (num_points < 2) {
- throw osmium::geometry_error("not enough points for linestring");
+ throw osmium::geometry_error("need at least two points for linestring");
}
return linestring_finish(num_points);
}
linestring_type create_linestring(const osmium::Way& way, use_nodes un=use_nodes::unique, direction dir=direction::forward) {
- return create_linestring(way.nodes(), un, dir);
+ try {
+ return create_linestring(way.nodes(), un, dir);
+ } catch (osmium::geometry_error& e) {
+ e.set_id("way", way.id());
+ throw;
+ }
}
/* Polygon */
@@ -283,40 +327,86 @@ namespace osmium {
return m_impl.polygon_finish(num_points);
}
+ polygon_type create_polygon(const osmium::WayNodeList& wnl, use_nodes un = use_nodes::unique, direction dir = direction::forward) {
+ polygon_start();
+ size_t num_points = 0;
+
+ if (un == use_nodes::unique) {
+ osmium::Location last_location;
+ switch (dir) {
+ case direction::forward:
+ num_points = fill_polygon_unique(wnl.cbegin(), wnl.cend());
+ break;
+ case direction::backward:
+ num_points = fill_polygon_unique(wnl.crbegin(), wnl.crend());
+ break;
+ }
+ } else {
+ switch (dir) {
+ case direction::forward:
+ num_points = fill_polygon(wnl.cbegin(), wnl.cend());
+ break;
+ case direction::backward:
+ num_points = fill_polygon(wnl.crbegin(), wnl.crend());
+ break;
+ }
+ }
+
+ if (num_points < 4) {
+ throw osmium::geometry_error("need at least four points for polygon");
+ }
+
+ return polygon_finish(num_points);
+ }
+
+ polygon_type create_polygon(const osmium::Way& way, use_nodes un=use_nodes::unique, direction dir=direction::forward) {
+ try {
+ return create_polygon(way.nodes(), un, dir);
+ } catch (osmium::geometry_error& e) {
+ e.set_id("way", way.id());
+ throw;
+ }
+ }
+
/* MultiPolygon */
multipolygon_type create_multipolygon(const osmium::Area& area) {
- size_t num_polygons = 0;
- size_t num_rings = 0;
- m_impl.multipolygon_start();
-
- for (auto it = area.cbegin(); it != area.cend(); ++it) {
- const osmium::OuterRing& ring = static_cast<const osmium::OuterRing&>(*it);
- if (it->type() == osmium::item_type::outer_ring) {
- if (num_polygons > 0) {
- m_impl.multipolygon_polygon_finish();
+ try {
+ size_t num_polygons = 0;
+ size_t num_rings = 0;
+ m_impl.multipolygon_start();
+
+ for (auto it = area.cbegin(); it != area.cend(); ++it) {
+ const osmium::OuterRing& ring = static_cast<const osmium::OuterRing&>(*it);
+ if (it->type() == osmium::item_type::outer_ring) {
+ if (num_polygons > 0) {
+ m_impl.multipolygon_polygon_finish();
+ }
+ m_impl.multipolygon_polygon_start();
+ m_impl.multipolygon_outer_ring_start();
+ add_points(ring);
+ m_impl.multipolygon_outer_ring_finish();
+ ++num_rings;
+ ++num_polygons;
+ } else if (it->type() == osmium::item_type::inner_ring) {
+ m_impl.multipolygon_inner_ring_start();
+ add_points(ring);
+ m_impl.multipolygon_inner_ring_finish();
+ ++num_rings;
}
- m_impl.multipolygon_polygon_start();
- m_impl.multipolygon_outer_ring_start();
- add_points(ring);
- m_impl.multipolygon_outer_ring_finish();
- ++num_rings;
- ++num_polygons;
- } else if (it->type() == osmium::item_type::inner_ring) {
- m_impl.multipolygon_inner_ring_start();
- add_points(ring);
- m_impl.multipolygon_inner_ring_finish();
- ++num_rings;
}
- }
- // if there are no rings, this area is invalid
- if (num_rings == 0) {
- throw osmium::geometry_error("invalid area");
- }
+ // if there are no rings, this area is invalid
+ if (num_rings == 0) {
+ throw osmium::geometry_error("area contains no rings");
+ }
- m_impl.multipolygon_polygon_finish();
- return m_impl.multipolygon_finish();
+ m_impl.multipolygon_polygon_finish();
+ return m_impl.multipolygon_finish();
+ } catch (osmium::geometry_error& e) {
+ e.set_id("area", area.id());
+ throw;
+ }
}
}; // class GeometryFactory
diff --git a/include/osmium/geom/geos.hpp b/include/osmium/geom/geos.hpp
index 3c73637..d4105b0 100644
--- a/include/osmium/geom/geos.hpp
+++ b/include/osmium/geom/geos.hpp
@@ -42,6 +42,7 @@ DEALINGS IN THE SOFTWARE.
* @attention If you include this file, you'll need to link with `libgeos`.
*/
+#include <string>
#include <utility>
#include <geos/geom/Coordinate.h>
@@ -69,8 +70,8 @@ namespace osmium {
struct geos_geometry_error : public geometry_error {
- geos_geometry_error() :
- geometry_error("geometry creation failed in GEOS library, see nested exception for details") {
+ geos_geometry_error(const char* message) :
+ geometry_error(std::string("geometry creation failed in GEOS library: ") + message) {
}
}; // struct geos_geometry_error
@@ -106,8 +107,8 @@ namespace osmium {
point_type make_point(const osmium::geom::Coordinates& xy) const {
try {
return point_type(m_geos_factory.createPoint(geos::geom::Coordinate(xy.x, xy.y)));
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
@@ -116,24 +117,24 @@ namespace osmium {
void linestring_start() {
try {
m_coordinate_sequence.reset(m_geos_factory.getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
void linestring_add_location(const osmium::geom::Coordinates& xy) {
try {
m_coordinate_sequence->add(geos::geom::Coordinate(xy.x, xy.y));
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
linestring_type linestring_finish(size_t /* num_points */) {
try {
return linestring_type(m_geos_factory.createLineString(m_coordinate_sequence.release()));
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
@@ -156,48 +157,48 @@ namespace osmium {
});
m_polygons.emplace_back(m_geos_factory.createPolygon(m_rings[0].release(), inner_rings));
m_rings.clear();
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
void multipolygon_outer_ring_start() {
try {
m_coordinate_sequence.reset(m_geos_factory.getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
void multipolygon_outer_ring_finish() {
try {
m_rings.emplace_back(m_geos_factory.createLinearRing(m_coordinate_sequence.release()));
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
void multipolygon_inner_ring_start() {
try {
m_coordinate_sequence.reset(m_geos_factory.getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
void multipolygon_inner_ring_finish() {
try {
m_rings.emplace_back(m_geos_factory.createLinearRing(m_coordinate_sequence.release()));
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
void multipolygon_add_location(const osmium::geom::Coordinates& xy) {
try {
m_coordinate_sequence->add(geos::geom::Coordinate(xy.x, xy.y));
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
@@ -209,8 +210,8 @@ namespace osmium {
});
m_polygons.clear();
return multipolygon_type(m_geos_factory.createMultiPolygon(polygons));
- } catch (geos::util::GEOSException&) {
- THROW(osmium::geos_geometry_error());
+ } catch (geos::util::GEOSException& e) {
+ THROW(osmium::geos_geometry_error(e.what()));
}
}
diff --git a/include/osmium/geom/haversine.hpp b/include/osmium/geom/haversine.hpp
index 14e18c5..e62a31b 100644
--- a/include/osmium/geom/haversine.hpp
+++ b/include/osmium/geom/haversine.hpp
@@ -74,7 +74,7 @@ namespace osmium {
* Calculate length of way.
*/
inline double distance(const osmium::WayNodeList& wnl) {
- double sum_length=0;
+ double sum_length = 0;
for (auto it = wnl.begin(); it != wnl.end(); ++it) {
if (std::next(it) != wnl.end()) {
diff --git a/include/osmium/geom/mercator_projection.hpp b/include/osmium/geom/mercator_projection.hpp
index a6d1d57..22a0d64 100644
--- a/include/osmium/geom/mercator_projection.hpp
+++ b/include/osmium/geom/mercator_projection.hpp
@@ -47,6 +47,7 @@ namespace osmium {
namespace detail {
constexpr double earth_radius_for_epsg3857 = 6378137.0;
+ constexpr double max_coordinate_epsg3857 = 20037508.34;
constexpr inline double lon_to_x(double lon) {
return earth_radius_for_epsg3857 * deg_to_rad(lon);
diff --git a/include/osmium/geom/rapid_geojson.hpp b/include/osmium/geom/rapid_geojson.hpp
new file mode 100644
index 0000000..a3d4687
--- /dev/null
+++ b/include/osmium/geom/rapid_geojson.hpp
@@ -0,0 +1,190 @@
+#ifndef OSMIUM_GEOM_RAPID_GEOJSON_HPP
+#define OSMIUM_GEOM_RAPID_GEOJSON_HPP
+
+/*
+
+This file is part of Osmium (http://osmcode.org/libosmium).
+
+Copyright 2013-2015 Jochen Topf <jochen at topf.org> and others (see README).
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <osmium/geom/coordinates.hpp>
+#include <osmium/geom/factory.hpp>
+
+namespace osmium {
+
+ namespace geom {
+
+ namespace detail {
+
+ /**
+ * A geometry factory implementation that can be used with the
+ * RapidJSON (https://github.com/miloyip/rapidjson) JSON writer.
+ */
+ template <class TWriter>
+ class RapidGeoJSONFactoryImpl {
+
+ TWriter* m_writer;
+
+ public:
+
+ typedef void point_type;
+ typedef void linestring_type;
+ typedef void polygon_type;
+ typedef void multipolygon_type;
+ typedef void ring_type;
+
+ RapidGeoJSONFactoryImpl(TWriter& writer) :
+ m_writer(&writer) {
+ }
+
+ /* Point */
+
+ // { "type": "Point", "coordinates": [100.0, 0.0] }
+ point_type make_point(const osmium::geom::Coordinates& xy) const {
+ m_writer->String("geometry");
+ m_writer->StartObject();
+ m_writer->String("type");
+ m_writer->String("Point");
+ m_writer->String("coordinates");
+ m_writer->StartArray();
+ m_writer->Double(xy.x);
+ m_writer->Double(xy.y);
+ m_writer->EndArray();
+ m_writer->EndObject();
+ }
+
+ /* LineString */
+
+ // { "type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] }
+ void linestring_start() {
+ m_writer->String("geometry");
+ m_writer->StartObject();
+ m_writer->String("type");
+ m_writer->String("LineString");
+ m_writer->String("coordinates");
+ m_writer->StartArray();
+ }
+
+ void linestring_add_location(const osmium::geom::Coordinates& xy) {
+ m_writer->StartArray();
+ m_writer->Double(xy.x);
+ m_writer->Double(xy.y);
+ m_writer->EndArray();
+ }
+
+ linestring_type linestring_finish(size_t /* num_points */) {
+ m_writer->EndArray();
+ m_writer->EndObject();
+ }
+
+ /* Polygon */
+
+ // { "type": "Polygon", "coordinates": [[[100.0, 0.0], [101.0, 1.0]]] }
+ void polygon_start() {
+ m_writer->String("geometry");
+ m_writer->StartObject();
+ m_writer->String("type");
+ m_writer->String("Polygon");
+ m_writer->String("coordinates");
+ m_writer->StartArray();
+ m_writer->StartArray();
+ }
+
+ void polygon_add_location(const osmium::geom::Coordinates& xy) {
+ m_writer->StartArray();
+ m_writer->Double(xy.x);
+ m_writer->Double(xy.y);
+ m_writer->EndArray();
+ }
+
+ polygon_type polygon_finish(size_t /* num_points */) {
+ m_writer->EndArray();
+ m_writer->EndArray();
+ m_writer->EndObject();
+ }
+
+ /* MultiPolygon */
+
+ void multipolygon_start() {
+ m_writer->String("geometry");
+ m_writer->StartObject();
+ m_writer->String("type");
+ m_writer->String("MultiPolygon");
+ m_writer->String("coordinates");
+ m_writer->StartArray();
+ }
+
+ void multipolygon_polygon_start() {
+ m_writer->StartArray();
+ }
+
+ void multipolygon_polygon_finish() {
+ m_writer->EndArray();
+ }
+
+ void multipolygon_outer_ring_start() {
+ m_writer->StartArray();
+ }
+
+ void multipolygon_outer_ring_finish() {
+ m_writer->EndArray();
+ }
+
+ void multipolygon_inner_ring_start() {
+ m_writer->StartArray();
+ }
+
+ void multipolygon_inner_ring_finish() {
+ m_writer->EndArray();
+ }
+
+ void multipolygon_add_location(const osmium::geom::Coordinates& xy) {
+ m_writer->StartArray();
+ m_writer->Double(xy.x);
+ m_writer->Double(xy.y);
+ m_writer->EndArray();
+ }
+
+ multipolygon_type multipolygon_finish() {
+ m_writer->EndArray();
+ m_writer->EndObject();
+ }
+
+ }; // class RapidGeoJSONFactoryImpl
+
+ } // namespace detail
+
+ template <class TWriter, class TProjection = IdentityProjection>
+ using RapidGeoJSONFactory = GeometryFactory<detail::RapidGeoJSONFactoryImpl<TWriter>, TProjection>;
+
+ } // namespace geom
+
+} // namespace osmium
+
+#endif // OSMIUM_GEOM_RAPID_GEOJSON_HPP
diff --git a/include/osmium/geom/tile.hpp b/include/osmium/geom/tile.hpp
new file mode 100644
index 0000000..9cd0b28
--- /dev/null
+++ b/include/osmium/geom/tile.hpp
@@ -0,0 +1,101 @@
+#ifndef OSMIUM_GEOM_TILE_HPP
+#define OSMIUM_GEOM_TILE_HPP
+
+/*
+
+This file is part of Osmium (http://osmcode.org/libosmium).
+
+Copyright 2013-2015 Jochen Topf <jochen at topf.org> and others (see README).
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <cstdint>
+
+#include <osmium/geom/mercator_projection.hpp>
+
+namespace osmium {
+
+ namespace geom {
+
+ namespace detail {
+
+ template <typename T>
+ inline T restrict_to_range(T value, T min, T max) {
+ if (value < min) return min;
+ if (value > max) return max;
+ return value;
+ }
+
+ } // namespace detail
+
+ /**
+ * A tile in the usual Mercator projection.
+ */
+ struct Tile {
+
+ uint32_t x;
+ uint32_t y;
+ uint32_t z;
+
+ explicit Tile(uint32_t zoom, uint32_t tx, uint32_t ty) noexcept : x(tx), y(ty), z(zoom) {
+ }
+
+ explicit Tile(uint32_t zoom, const osmium::Location& location) :
+ z(zoom) {
+ osmium::geom::Coordinates c = lonlat_to_mercator(location);
+ const int32_t n = 1LL << zoom;
+ const double scale = detail::max_coordinate_epsg3857 * 2 / n;
+ x = detail::restrict_to_range<int32_t>((c.x + detail::max_coordinate_epsg3857) / scale, 0, n-1);
+ y = detail::restrict_to_range<int32_t>((detail::max_coordinate_epsg3857 - c.y) / scale, 0, n-1);
+ }
+
+ }; // struct Tile
+
+ inline bool operator==(const Tile& a, const Tile& b) {
+ return a.z == b.z && a.x == b.x && a.y == b.y;
+ }
+
+ inline bool operator!=(const Tile& a, const Tile& b) {
+ return ! (a == b);
+ }
+
+ /**
+ * This defines an arbitrary order on tiles for use in std::map etc.
+ */
+ inline bool operator<(const Tile& a, const Tile& b) {
+ if (a.z < b.z) return true;
+ if (a.z > b.z) return false;
+ if (a.x < b.x) return true;
+ if (a.x > b.x) return false;
+ return a.y < b.y;
+ }
+
+ } // namespace geom
+
+} // namespace osmium
+
+#endif // OSMIUM_GEOM_TILE_HPP
diff --git a/include/osmium/geom/wkb.hpp b/include/osmium/geom/wkb.hpp
index 31fce71..2f32fe3 100644
--- a/include/osmium/geom/wkb.hpp
+++ b/include/osmium/geom/wkb.hpp
@@ -161,7 +161,7 @@ namespace osmium {
typedef std::string multipolygon_type;
typedef std::string ring_type;
- explicit WKBFactoryImpl(wkb_type wtype=wkb_type::wkb, out_type otype=out_type::binary) :
+ explicit WKBFactoryImpl(wkb_type wtype = wkb_type::wkb, out_type otype = out_type::binary) :
m_wkb_type(wtype),
m_out_type(otype) {
}
diff --git a/include/osmium/handler/dump.hpp b/include/osmium/handler/dump.hpp
index 564035c..a23236e 100644
--- a/include/osmium/handler/dump.hpp
+++ b/include/osmium/handler/dump.hpp
@@ -136,7 +136,7 @@ namespace osmium {
public:
- explicit Dump(std::ostream& out, bool with_size=true, const std::string& prefix="") :
+ explicit Dump(std::ostream& out, bool with_size = true, const std::string& prefix = "") :
m_out(&out),
m_with_size(with_size),
m_prefix(prefix) {
diff --git a/include/osmium/index/detail/mmap_vector_anon.hpp b/include/osmium/index/bool_vector.hpp
similarity index 58%
copy from include/osmium/index/detail/mmap_vector_anon.hpp
copy to include/osmium/index/bool_vector.hpp
index 0ea4f9d..94e1f72 100644
--- a/include/osmium/index/detail/mmap_vector_anon.hpp
+++ b/include/osmium/index/bool_vector.hpp
@@ -1,5 +1,5 @@
-#ifndef OSMIUM_INDEX_DETAIL_MMAP_VECTOR_ANON_HPP
-#define OSMIUM_INDEX_DETAIL_MMAP_VECTOR_ANON_HPP
+#ifndef OSMIUM_INDEX_BOOL_VECTOR_HPP
+#define OSMIUM_INDEX_BOOL_VECTOR_HPP
/*
@@ -33,46 +33,51 @@ DEALINGS IN THE SOFTWARE.
*/
-#ifdef __linux__
-
-#include <cstddef>
-
-#include <osmium/index/detail/typed_mmap.hpp>
-#include <osmium/index/detail/mmap_vector_base.hpp>
+#include <type_traits>
+#include <vector>
namespace osmium {
- namespace detail {
+ namespace index {
/**
- * This class looks and behaves like STL vector, but uses mmap internally.
+ * Index storing one bit for each Id. The index automatically scales
+ * with the Ids stored. Default value is 'false'. Storage uses
+ * std::vector<bool> and needs a minimum of memory if the Ids are
+ * dense.
*/
template <typename T>
- class mmap_vector_anon : public mmap_vector_base<T, mmap_vector_anon> {
+ class BoolVector {
+
+ static_assert(std::is_unsigned<T>::value, "Needs unsigned type");
+
+ std::vector<bool> m_bits;
public:
- mmap_vector_anon() :
- mmap_vector_base<T, osmium::detail::mmap_vector_anon>(
- -1,
- osmium::detail::mmap_vector_size_increment,
- 0,
- osmium::detail::typed_mmap<T>::map(osmium::detail::mmap_vector_size_increment)) {
- }
+ BoolVector() = default;
+ BoolVector(const BoolVector&) = default;
+ BoolVector(BoolVector&&) = default;
+ BoolVector& operator=(const BoolVector&) = default;
+ BoolVector& operator=(BoolVector&&) = default;
+ ~BoolVector() = default;
- void reserve(size_t new_capacity) {
- if (new_capacity > this->capacity()) {
- this->data(osmium::detail::typed_mmap<T>::remap(this->data(), this->capacity(), new_capacity));
- this->m_capacity = new_capacity;
+ void set(T id, bool value = true) {
+ if (m_bits.size() <= id) {
+ m_bits.resize(id + 1024 * 1024);
}
+
+ m_bits[id] = value;
+ }
+
+ bool get(T id) const {
+ return id < m_bits.size() && m_bits[id];
}
- }; // class mmap_vector_anon
+ }; // class BoolVector
- } // namespace detail
+ } // namespace index
} // namespace osmium
-#endif // __linux__
-
-#endif // OSMIUM_INDEX_DETAIL_MMAP_VECTOR_ANON_HPP
+#endif // OSMIUM_INDEX_BOOL_VECTOR_HPP
diff --git a/include/osmium/index/detail/mmap_vector_anon.hpp b/include/osmium/index/detail/mmap_vector_anon.hpp
index 0ea4f9d..fc01626 100644
--- a/include/osmium/index/detail/mmap_vector_anon.hpp
+++ b/include/osmium/index/detail/mmap_vector_anon.hpp
@@ -35,9 +35,6 @@ DEALINGS IN THE SOFTWARE.
#ifdef __linux__
-#include <cstddef>
-
-#include <osmium/index/detail/typed_mmap.hpp>
#include <osmium/index/detail/mmap_vector_base.hpp>
namespace osmium {
@@ -45,26 +42,16 @@ namespace osmium {
namespace detail {
/**
- * This class looks and behaves like STL vector, but uses mmap internally.
+ * This class looks and behaves like STL vector, but uses mmap
+ * internally.
*/
template <typename T>
- class mmap_vector_anon : public mmap_vector_base<T, mmap_vector_anon> {
+ class mmap_vector_anon : public mmap_vector_base<T> {
public:
mmap_vector_anon() :
- mmap_vector_base<T, osmium::detail::mmap_vector_anon>(
- -1,
- osmium::detail::mmap_vector_size_increment,
- 0,
- osmium::detail::typed_mmap<T>::map(osmium::detail::mmap_vector_size_increment)) {
- }
-
- void reserve(size_t new_capacity) {
- if (new_capacity > this->capacity()) {
- this->data(osmium::detail::typed_mmap<T>::remap(this->data(), this->capacity(), new_capacity));
- this->m_capacity = new_capacity;
- }
+ mmap_vector_base<T>() {
}
}; // class mmap_vector_anon
diff --git a/include/osmium/index/detail/mmap_vector_base.hpp b/include/osmium/index/detail/mmap_vector_base.hpp
index 3aff26d..2400f89 100644
--- a/include/osmium/index/detail/mmap_vector_base.hpp
+++ b/include/osmium/index/detail/mmap_vector_base.hpp
@@ -37,8 +37,7 @@ DEALINGS IN THE SOFTWARE.
#include <new>
#include <stdexcept>
-#include <osmium/index/detail/typed_mmap.hpp>
-#include <osmium/util/compatibility.hpp>
+#include <osmium/util/memory_mapping.hpp>
namespace osmium {
@@ -48,40 +47,29 @@ namespace osmium {
/**
* This is a base class for implementing classes that look like
- * STL vector but use mmap internally. This class can not be used
- * on it's own. Use the derived classes mmap_vector_anon or
- * mmap_vector_file.
+ * STL vector but use mmap internally. Do not use this class itself,
+ * use the derived classes mmap_vector_anon or mmap_vector_file.
*/
- template <typename T, template <typename> class TDerived>
+ template <typename T>
class mmap_vector_base {
protected:
- int m_fd;
- size_t m_capacity;
size_t m_size;
- T* m_data;
+ osmium::util::TypedMemoryMapping<T> m_mapping;
- explicit mmap_vector_base(int fd, size_t capacity, size_t size, T* data) noexcept :
- m_fd(fd),
- m_capacity(capacity),
- m_size(size),
- m_data(data) {
- }
+ public:
- explicit mmap_vector_base(int fd, size_t capacity, size_t size) :
- m_fd(fd),
- m_capacity(capacity),
+ explicit mmap_vector_base(int fd, size_t capacity, size_t size = 0) :
m_size(size),
- m_data(osmium::detail::typed_mmap<T>::grow_and_map(capacity, m_fd)) {
+ m_mapping(capacity, true, fd) {
}
- void data(T* data) {
- m_data = data;
+ explicit mmap_vector_base(size_t capacity = mmap_vector_size_increment) :
+ m_size(0),
+ m_mapping(capacity) {
}
- public:
-
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
@@ -90,12 +78,14 @@ namespace osmium {
typedef T* iterator;
typedef const T* const_iterator;
- ~mmap_vector_base() {
- osmium::detail::typed_mmap<T>::unmap(m_data, m_capacity);
+ ~mmap_vector_base() = default;
+
+ void close() {
+ m_mapping.unmap();
}
size_t capacity() const noexcept {
- return m_capacity;
+ return m_mapping.size();
}
size_t size() const noexcept {
@@ -106,23 +96,23 @@ namespace osmium {
return m_size == 0;
}
- const T* data() const noexcept {
- return m_data;
+ const T* data() const {
+ return m_mapping.begin();
}
- T* data() noexcept {
- return m_data;
+ T* data() {
+ return m_mapping.begin();
}
T& operator[](size_t n) {
- return m_data[n];
+ return data()[n];
}
T at(size_t n) const {
if (n >= m_size) {
throw std::out_of_range("out of range");
}
- return m_data[n];
+ return data()[n];
}
void clear() noexcept {
@@ -134,16 +124,22 @@ namespace osmium {
}
void push_back(const T& value) {
- if (m_size >= m_capacity) {
+ if (m_size >= capacity()) {
resize(m_size+1);
}
- m_data[m_size] = value;
+ data()[m_size] = value;
++m_size;
}
+ void reserve(size_t new_capacity) {
+ if (new_capacity > capacity()) {
+ m_mapping.resize(new_capacity);
+ }
+ }
+
void resize(size_t new_size) {
if (new_size > capacity()) {
- static_cast<TDerived<T>*>(this)->reserve(new_size + osmium::detail::mmap_vector_size_increment);
+ reserve(new_size + osmium::detail::mmap_vector_size_increment);
}
if (new_size > size()) {
new (data() + size()) T[new_size - size()];
@@ -152,27 +148,27 @@ namespace osmium {
}
iterator begin() noexcept {
- return m_data;
+ return data();
}
iterator end() noexcept {
- return m_data + m_size;
+ return data() + m_size;
}
const_iterator begin() const noexcept {
- return m_data;
+ return data();
}
const_iterator end() const noexcept {
- return m_data + m_size;
+ return data() + m_size;
}
- const_iterator cbegin() noexcept {
- return m_data;
+ const_iterator cbegin() const noexcept {
+ return data();
}
- const_iterator cend() noexcept {
- return m_data + m_size;
+ const_iterator cend() const noexcept {
+ return data() + m_size;
}
}; // class mmap_vector_base
diff --git a/include/osmium/index/detail/mmap_vector_file.hpp b/include/osmium/index/detail/mmap_vector_file.hpp
index 55077d1..1336003 100644
--- a/include/osmium/index/detail/mmap_vector_file.hpp
+++ b/include/osmium/index/detail/mmap_vector_file.hpp
@@ -35,7 +35,6 @@ DEALINGS IN THE SOFTWARE.
#include <cstddef>
-#include <osmium/index/detail/typed_mmap.hpp>
#include <osmium/index/detail/mmap_vector_base.hpp>
#include <osmium/index/detail/tmpfile.hpp>
@@ -48,32 +47,19 @@ namespace osmium {
* internally.
*/
template <typename T>
- class mmap_vector_file : public mmap_vector_base<T, mmap_vector_file> {
+ class mmap_vector_file : public mmap_vector_base<T> {
public:
- explicit mmap_vector_file() :
- mmap_vector_base<T, osmium::detail::mmap_vector_file>(
+ explicit mmap_vector_file() : mmap_vector_base<T>(
osmium::detail::create_tmp_file(),
- osmium::detail::mmap_vector_size_increment,
- 0) {
+ osmium::detail::mmap_vector_size_increment) {
}
- explicit mmap_vector_file(int fd) :
- mmap_vector_base<T, osmium::detail::mmap_vector_file>(
+ explicit mmap_vector_file(int fd) : mmap_vector_base<T>(
fd,
- osmium::detail::typed_mmap<T>::file_size(fd) == 0 ?
- osmium::detail::mmap_vector_size_increment :
- osmium::detail::typed_mmap<T>::file_size(fd),
- osmium::detail::typed_mmap<T>::file_size(fd)) {
- }
-
- void reserve(size_t new_capacity) {
- if (new_capacity > this->capacity()) {
- typed_mmap<T>::unmap(this->data(), this->capacity());
- this->data(typed_mmap<T>::grow_and_map(new_capacity, this->m_fd));
- this->m_capacity = new_capacity;
- }
+ osmium::util::file_size(fd) / sizeof(T),
+ osmium::util::file_size(fd) / sizeof(T)) {
}
}; // class mmap_vector_file
diff --git a/include/osmium/index/detail/typed_mmap.hpp b/include/osmium/index/detail/typed_mmap.hpp
deleted file mode 100644
index 77b065e..0000000
--- a/include/osmium/index/detail/typed_mmap.hpp
+++ /dev/null
@@ -1,229 +0,0 @@
-#ifndef OSMIUM_INDEX_DETAIL_TYPED_MMAP_HPP
-#define OSMIUM_INDEX_DETAIL_TYPED_MMAP_HPP
-
-/*
-
-This file is part of Osmium (http://osmcode.org/libosmium).
-
-Copyright 2013-2015 Jochen Topf <jochen at topf.org> and others (see README).
-
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
-*/
-
-#include <cerrno>
-#include <cstddef>
-#include <stdexcept>
-#include <system_error>
-
-#include <sys/stat.h>
-
-#ifndef _WIN32
-# include <sys/mman.h>
-#else
-# include <mmap_for_windows.hpp>
-#endif
-
-#ifndef _MSC_VER
-# include <unistd.h>
-#else
-# define ftruncate _chsize
-#endif
-
-// for bsd systems
-#ifndef MAP_ANONYMOUS
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-#include <osmium/util/cast.hpp>
-
-namespace osmium {
-
- /**
- * @brief Namespace for Osmium internal use
- */
- namespace detail {
-
- /**
- * This is a helper class for working with memory mapped files and
- * anonymous shared memory. It wraps the necessary system calls
- * adding:
- * - error checking: all functions throw exceptions where needed
- * - internal casts and size calculations allow use with user defined
- * type T instead of void*
- *
- * This class only contains static functions. It should never be
- * instantiated.
- *
- * @tparam T Type of objects we want to store.
- */
- template <typename T>
- class typed_mmap {
-
- public:
-
- /**
- * Create anonymous private memory mapping with enough space for size
- * objects of type T.
- *
- * Note that no constructor is called for any of the objects in this memory!
- *
- * @param size Number of objects of type T that should fit into this memory
- * @returns Pointer to mapped memory
- * @throws std::system_error If mmap(2) failed
- */
- static T* map(size_t size) {
- void* addr = ::mmap(nullptr, sizeof(T) * size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
- if (addr == MAP_FAILED) {
- throw std::system_error(errno, std::system_category(), "mmap failed");
- }
-#pragma GCC diagnostic pop
- return reinterpret_cast<T*>(addr);
- }
-
- /**
- * Create shared memory mapping of a file with enough space for size
- * objects of type T. The file must already have at least the
- * required size.
- *
- * Note that no constructor is called for any of the objects in this memory!
- *
- * @param size Number of objects of type T that should fit into this memory
- * @param fd File descriptor
- * @param write True if data should be writable
- * @returns Pointer to mapped memory
- * @throws std::system_error If mmap(2) failed
- */
- static T* map(size_t size, int fd, bool write = false) {
- int prot = PROT_READ;
- if (write) {
- prot |= PROT_WRITE;
- }
- void* addr = ::mmap(nullptr, sizeof(T) * size, prot, MAP_SHARED, fd, 0);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
- if (addr == MAP_FAILED) {
- throw std::system_error(errno, std::system_category(), "mmap failed");
- }
-#pragma GCC diagnostic pop
- return reinterpret_cast<T*>(addr);
- }
-
-// mremap(2) is only available on linux systems
-#ifdef __linux__
- /**
- * Grow memory mapping created with map().
- *
- * Note that no constructor is called for any of the objects in this memory!
- *
- * @param data Pointer to current mapping (as returned by typed_mmap())
- * @param old_size Number of objects currently stored in this memory
- * @param new_size Number of objects we want to have space for
- * @throws std::system_error If mremap(2) call failed
- */
- static T* remap(T* data, size_t old_size, size_t new_size) {
- void* addr = ::mremap(reinterpret_cast<void*>(data), sizeof(T) * old_size, sizeof(T) * new_size, MREMAP_MAYMOVE);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
- if (addr == MAP_FAILED) {
- throw std::system_error(errno, std::system_category(), "mremap failed");
- }
-#pragma GCC diagnostic pop
- return reinterpret_cast<T*>(addr);
- }
-#endif
-
- /**
- * Release memory from map() call.
- *
- * Note that no destructor is called for the objects in this memory!
- *
- * @param data Pointer to the data
- * @param size Number of objects of type T stored
- * @throws std::system_error If munmap(2) call failed
- */
- static void unmap(T* data, size_t size) {
- if (::munmap(reinterpret_cast<void*>(data), sizeof(T) * size) != 0) {
- throw std::system_error(errno, std::system_category(), "munmap failed");
- }
- }
-
- /**
- * Get number of objects of type T that would fit into a file.
- *
- * @param fd File descriptor
- * @returns Number of objects of type T in this file
- * @throws std::system_error If fstat(2) call failed
- * @throws std::length_error If size of the file isn't a multiple of sizeof(T)
- */
- static size_t file_size(int fd) {
- struct stat s;
- if (fstat(fd, &s) < 0) {
- throw std::system_error(errno, std::system_category(), "fstat failed");
- }
- if (static_cast<size_t>(s.st_size) % sizeof(T) != 0) {
- throw std::length_error("file size has to be multiple of object size");
- }
- return static_cast<size_t>(s.st_size) / sizeof(T);
- }
-
- /**
- * Grow file so there is enough space for at least new_size objects
- * of type T. If the file is large enough already, nothing is done.
- * The file is never shrunk.
- *
- * @param new_size Number of objects of type T that should fit into this file
- * @param fd File descriptor
- * @throws std::system_error If ftruncate(2) call failed
- */
- static void grow_file(size_t new_size, int fd) {
- if (file_size(fd) < new_size) {
- if (::ftruncate(fd, static_cast_with_assert<off_t>(sizeof(T) * new_size)) < 0) {
- throw std::system_error(errno, std::system_category(), "ftruncate failed");
- }
- }
- }
-
- /**
- * Grow file to given size (if it is smaller) and mmap it.
- *
- * @param size Number of objects of type T that should fit into this file
- * @param fd File descriptor
- * @throws Errors thrown by grow_file() or map()
- */
- static T* grow_and_map(size_t size, int fd) {
- grow_file(size, fd);
- return map(size, fd, true);
- }
-
- }; // class typed_mmap
-
- } // namespace detail
-
-} // namespace osmium
-
-#endif // OSMIUM_INDEX_DETAIL_TYPED_MMAP_HPP
diff --git a/include/osmium/index/detail/vector_map.hpp b/include/osmium/index/detail/vector_map.hpp
index 73c5a37..9c1cf4e 100644
--- a/include/osmium/index/detail/vector_map.hpp
+++ b/include/osmium/index/detail/vector_map.hpp
@@ -68,7 +68,7 @@ namespace osmium {
m_vector(fd) {
}
- ~VectorBasedDenseMap() {}
+ ~VectorBasedDenseMap() = default;
void reserve(const size_t size) override final {
m_vector.reserve(size);
@@ -97,6 +97,10 @@ namespace osmium {
return m_vector.size();
}
+ size_t byte_size() const {
+ return m_vector.size() * sizeof(element_type);
+ }
+
size_t used_memory() const override final {
return sizeof(TValue) * size();
}
@@ -106,6 +110,10 @@ namespace osmium {
m_vector.shrink_to_fit();
}
+ void dump_as_array(const int fd) override final {
+ osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size());
+ }
+
iterator begin() {
return m_vector.begin();
}
diff --git a/include/osmium/index/detail/vector_multimap.hpp b/include/osmium/index/detail/vector_multimap.hpp
index c2b2e1f..1d875fc 100644
--- a/include/osmium/index/detail/vector_multimap.hpp
+++ b/include/osmium/index/detail/vector_multimap.hpp
@@ -67,6 +67,16 @@ namespace osmium {
public:
+ VectorBasedSparseMultimap() :
+ m_vector() {
+ }
+
+ explicit VectorBasedSparseMultimap(int fd) :
+ m_vector(fd) {
+ }
+
+ ~VectorBasedSparseMultimap() = default;
+
void set(const TId id, const TValue value) override final {
m_vector.push_back(element_type(id, value));
}
@@ -141,6 +151,30 @@ namespace osmium {
osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size());
}
+ iterator begin() {
+ return m_vector.begin();
+ }
+
+ iterator end() {
+ return m_vector.end();
+ }
+
+ const_iterator cbegin() const {
+ return m_vector.cbegin();
+ }
+
+ const_iterator cend() const {
+ return m_vector.cend();
+ }
+
+ const_iterator begin() const {
+ return m_vector.cbegin();
+ }
+
+ const_iterator end() const {
+ return m_vector.cend();
+ }
+
}; // class VectorBasedSparseMultimap
} // namespace multimap
diff --git a/include/osmium/index/index.hpp b/include/osmium/index/index.hpp
index b73b319..f415192 100644
--- a/include/osmium/index/index.hpp
+++ b/include/osmium/index/index.hpp
@@ -67,7 +67,7 @@ namespace osmium {
template <typename TKey>
OSMIUM_NORETURN void not_found_error(TKey key) {
std::stringstream s;
- s << "id " << key << " no found";
+ s << "id " << key << " not found";
throw not_found(s.str());
}
diff --git a/include/osmium/index/map.hpp b/include/osmium/index/map.hpp
index 7b44b8e..61af672 100644
--- a/include/osmium/index/map.hpp
+++ b/include/osmium/index/map.hpp
@@ -148,7 +148,11 @@ namespace osmium {
}
virtual void dump_as_list(const int /*fd*/) {
- std::runtime_error("can't dump as list");
+ throw std::runtime_error("can't dump as list");
+ }
+
+ virtual void dump_as_array(const int /*fd*/) {
+ throw std::runtime_error("can't dump as array");
}
}; // class Map
@@ -195,6 +199,10 @@ namespace osmium {
return m_callbacks.emplace(map_type_name, func).second;
}
+ bool has_map_type(const std::string& map_type_name) const {
+ return m_callbacks.count(map_type_name);
+ }
+
std::vector<std::string> map_types() const {
std::vector<std::string> result;
@@ -242,9 +250,13 @@ namespace osmium {
});
}
+#define OSMIUM_CONCATENATE_DETAIL_(x, y) x##y
+#define OSMIUM_CONCATENATE_(x, y) OSMIUM_CONCATENATE_DETAIL_(x, y)
+#define OSMIUM_MAKE_UNIQUE_(x) OSMIUM_CONCATENATE_(x, __COUNTER__)
+
#define REGISTER_MAP(id, value, klass, name) \
namespace { \
- const bool registered_index_map_##name = osmium::index::register_map<id, value, klass>(#name); \
+ const bool OSMIUM_MAKE_UNIQUE_(registered_index_map_##name) = osmium::index::register_map<id, value, klass>(#name); \
}
} // namespace index
diff --git a/include/osmium/index/map/sparse_mem_table.hpp b/include/osmium/index/map/sparse_mem_table.hpp
index 8998a91..09ee81b 100644
--- a/include/osmium/index/map/sparse_mem_table.hpp
+++ b/include/osmium/index/map/sparse_mem_table.hpp
@@ -83,7 +83,7 @@ namespace osmium {
* The storage will grow by at least this size
* every time it runs out of space.
*/
- explicit SparseMemTable(const TId grow_size=10000) :
+ explicit SparseMemTable(const TId grow_size = 10000) :
m_grow_size(grow_size),
m_elements(grow_size) {
}
@@ -123,7 +123,7 @@ namespace osmium {
void dump_as_list(const int fd) override final {
std::vector<std::pair<TId, TValue>> v;
- int n=0;
+ int n = 0;
for (const TValue value : m_elements) {
if (value != osmium::index::empty_value<TValue>()) {
v.emplace_back(n, value);
diff --git a/include/osmium/io/bzip2_compression.hpp b/include/osmium/io/bzip2_compression.hpp
index de1364c..7e86c15 100644
--- a/include/osmium/io/bzip2_compression.hpp
+++ b/include/osmium/io/bzip2_compression.hpp
@@ -82,7 +82,7 @@ namespace osmium {
namespace detail {
- OSMIUM_NORETURN inline void throw_bzip2_error(BZFILE* bzfile, const char* msg, int bzlib_error=0) {
+ OSMIUM_NORETURN inline void throw_bzip2_error(BZFILE* bzfile, const char* msg, int bzlib_error = 0) {
std::string error("bzip2 error: ");
error += msg;
error += ": ";
diff --git a/include/osmium/io/detail/pbf.hpp b/include/osmium/io/detail/pbf.hpp
index e64e51a..f2975c5 100644
--- a/include/osmium/io/detail/pbf.hpp
+++ b/include/osmium/io/detail/pbf.hpp
@@ -35,8 +35,6 @@ DEALINGS IN THE SOFTWARE.
#include <stdexcept>
-#include <osmpbf/osmpbf.h>
-
// needed for htonl and ntohl
#ifndef _WIN32
# include <netinet/in.h>
@@ -45,38 +43,9 @@ DEALINGS IN THE SOFTWARE.
#endif
#include <osmium/io/error.hpp>
-#include <osmium/osm/item_type.hpp>
namespace osmium {
-// avoid g++ false positive
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wreturn-type"
- inline item_type osmpbf_membertype_to_item_type(const OSMPBF::Relation::MemberType mt) {
- switch (mt) {
- case OSMPBF::Relation::NODE:
- return item_type::node;
- case OSMPBF::Relation::WAY:
- return item_type::way;
- case OSMPBF::Relation::RELATION:
- return item_type::relation;
- }
- }
-#pragma GCC diagnostic pop
-
- inline OSMPBF::Relation::MemberType item_type_to_osmpbf_membertype(const item_type type) {
- switch (type) {
- case item_type::node:
- return OSMPBF::Relation::NODE;
- case item_type::way:
- return OSMPBF::Relation::WAY;
- case item_type::relation:
- return OSMPBF::Relation::RELATION;
- default:
- throw std::runtime_error("Unknown relation member type");
- }
- }
-
/**
* Exception thrown when there was a problem with parsing the PBF format of
* a file.
diff --git a/include/osmium/io/detail/pbf_input_format.hpp b/include/osmium/io/detail/pbf_input_format.hpp
index ac69cbd..93ba6ca 100644
--- a/include/osmium/io/detail/pbf_input_format.hpp
+++ b/include/osmium/io/detail/pbf_input_format.hpp
@@ -51,6 +51,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/io/detail/input_format.hpp>
#include <osmium/io/detail/pbf.hpp> // IWYU pragma: export
+#include <osmium/io/detail/pbf_type_conv.hpp>
#include <osmium/io/detail/pbf_parser.hpp>
#include <osmium/io/error.hpp>
#include <osmium/io/file.hpp>
@@ -152,7 +153,7 @@ namespace osmium {
void parse_osm_data(osmium::osm_entity_bits::type read_types) {
osmium::thread::set_thread_name("_osmium_pbf_in");
- int n=0;
+ int n = 0;
while (auto size = read_blob_header("OSMData")) {
if (m_use_thread_pool) {
diff --git a/include/osmium/io/detail/pbf_output_format.hpp b/include/osmium/io/detail/pbf_output_format.hpp
index acce67d..7afd2ee 100644
--- a/include/osmium/io/detail/pbf_output_format.hpp
+++ b/include/osmium/io/detail/pbf_output_format.hpp
@@ -112,6 +112,7 @@ More complete outlines of real .osm.pbf files can be created using the osmpbf-ou
#include <osmium/handler.hpp>
#include <osmium/io/detail/output_format.hpp>
#include <osmium/io/detail/pbf.hpp> // IWYU pragma: export
+#include <osmium/io/detail/pbf_type_conv.hpp>
#include <osmium/io/detail/pbf_stringtable.hpp>
#include <osmium/io/detail/zlib.hpp>
#include <osmium/io/file.hpp>
@@ -129,6 +130,7 @@ More complete outlines of real .osm.pbf files can be created using the osmpbf-ou
#include <osmium/osm/timestamp.hpp>
#include <osmium/osm/way.hpp>
#include <osmium/util/cast.hpp>
+#include <osmium/util/delta.hpp>
#include <osmium/visitor.hpp>
namespace osmium {
@@ -190,34 +192,6 @@ namespace osmium {
class PBFOutputFormat : public osmium::io::detail::OutputFormat, public osmium::handler::Handler {
/**
- * This class models a variable that keeps track of the value
- * it was last set to and returns the delta between old and
- * new value from the update() call.
- */
- template <typename T>
- class Delta {
-
- T m_value;
-
- public:
-
- Delta() :
- m_value(0) {
- }
-
- void clear() {
- m_value = 0;
- }
-
- T update(T new_value) {
- using std::swap;
- swap(m_value, new_value);
- return m_value - new_value;
- }
-
- }; // class Delta
-
- /**
* Maximum number of items in a primitive block.
*
* The uncompressed length of a Blob *should* be less
@@ -332,13 +306,13 @@ namespace osmium {
* delta-encoding while storing dense-nodes. It holds the last seen values
* from which the difference is stored into the protobuf.
*/
- Delta<int64_t> m_delta_id;
- Delta<int64_t> m_delta_lat;
- Delta<int64_t> m_delta_lon;
- Delta<int64_t> m_delta_timestamp;
- Delta<int64_t> m_delta_changeset;
- Delta<int64_t> m_delta_uid;
- Delta<::google::protobuf::int32> m_delta_user_sid;
+ osmium::util::DeltaEncode<int64_t> m_delta_id;
+ osmium::util::DeltaEncode<int64_t> m_delta_lat;
+ osmium::util::DeltaEncode<int64_t> m_delta_lon;
+ osmium::util::DeltaEncode<int64_t> m_delta_timestamp;
+ osmium::util::DeltaEncode<int64_t> m_delta_changeset;
+ osmium::util::DeltaEncode<int64_t> m_delta_uid;
+ osmium::util::DeltaEncode<::google::protobuf::int32> m_delta_user_sid;
bool debug;
@@ -355,7 +329,7 @@ namespace osmium {
if (dense->has_denseinfo()) {
OSMPBF::DenseInfo* denseinfo = dense->mutable_denseinfo();
- for (int i=0, l=denseinfo->user_sid_size(); i<l; ++i) {
+ for (int i = 0, l=denseinfo->user_sid_size(); i<l; ++i) {
auto user_sid = denseinfo->user_sid(i);
denseinfo->set_user_sid(i, m_delta_user_sid.update(user_sid));
}
@@ -374,7 +348,7 @@ namespace osmium {
// test, if the node-block has been allocated
if (pbf_nodes) {
// iterate over all nodes, passing them to the map_common_string_ids function
- for (int i=0, l=pbf_nodes->nodes_size(); i<l; ++i) {
+ for (int i = 0, l=pbf_nodes->nodes_size(); i<l; ++i) {
map_common_string_ids(pbf_nodes->mutable_nodes(i));
}
@@ -386,7 +360,7 @@ namespace osmium {
// in the densenodes structure keys and vals are encoded in an intermixed
// array, individual nodes are seperated by a value of 0 (0 in the StringTable
// is always unused). String-ids of 0 are thus kept alone.
- for (int i=0, l=dense->keys_vals_size(); i<l; ++i) {
+ for (int i = 0, l=dense->keys_vals_size(); i<l; ++i) {
// map interim string-ids > 0 to real string ids
auto sid = dense->keys_vals(i);
if (sid > 0) {
@@ -400,7 +374,7 @@ namespace osmium {
OSMPBF::DenseInfo* denseinfo = dense->mutable_denseinfo();
// iterate over all username string-ids
- for (int i=0, l=denseinfo->user_sid_size(); i<l; ++i) {
+ for (int i = 0, l=denseinfo->user_sid_size(); i<l; ++i) {
// map interim string-ids > 0 to real string ids
auto user_sid = string_table.map_string_id(denseinfo->user_sid(i));
@@ -414,7 +388,7 @@ namespace osmium {
// test, if the ways-block has been allocated
if (pbf_ways) {
// iterate over all ways, passing them to the map_common_string_ids function
- for (int i=0, l=pbf_ways->ways_size(); i<l; ++i) {
+ for (int i = 0, l=pbf_ways->ways_size(); i<l; ++i) {
map_common_string_ids(pbf_ways->mutable_ways(i));
}
}
@@ -422,7 +396,7 @@ namespace osmium {
// test, if the relations-block has been allocated
if (pbf_relations) {
// iterate over all relations
- for (int i=0, l=pbf_relations->relations_size(); i<l; ++i) {
+ for (int i = 0, l=pbf_relations->relations_size(); i<l; ++i) {
// get a pointer to the relation
OSMPBF::Relation* relation = pbf_relations->mutable_relations(i);
@@ -431,7 +405,7 @@ namespace osmium {
// iterate over all relation members, mapping the interim string-ids
// of the role to real string ids
- for (int mi=0; mi < relation->roles_sid_size(); ++mi) {
+ for (int mi = 0; mi < relation->roles_sid_size(); ++mi) {
relation->set_roles_sid(mi, string_table.map_string_id(relation->roles_sid(mi)));
}
}
@@ -454,7 +428,7 @@ namespace osmium {
}
// iterate over all tags and map the interim-ids of the key and the value to real ids
- for (int i=0, l=in->keys_size(); i<l; ++i) {
+ for (int i = 0, l=in->keys_size(); i<l; ++i) {
in->set_keys(i, string_table.map_string_id(in->keys(i)));
in->set_vals(i, string_table.map_string_id(in->vals(i)));
}
@@ -690,7 +664,7 @@ namespace osmium {
apply_common_info(way, pbf_way);
// last way-node-id used for delta-encoding
- Delta<int64_t> delta_id;
+ osmium::util::DeltaEncode<int64_t> delta_id;
for (const auto& node_ref : way.nodes()) {
// copy the way-node-id, delta encoded
@@ -713,7 +687,7 @@ namespace osmium {
// copy the common meta-info from the osmium-object to the pbf-object
apply_common_info(relation, pbf_relation);
- Delta<int64_t> delta_id;
+ osmium::util::DeltaEncode<int64_t> delta_id;
for (const auto& member : relation.members()) {
// record the relation-member role to the interim stringtable and copy the
diff --git a/include/osmium/io/detail/pbf_parser.hpp b/include/osmium/io/detail/pbf_parser.hpp
index d99819d..f626b0b 100644
--- a/include/osmium/io/detail/pbf_parser.hpp
+++ b/include/osmium/io/detail/pbf_parser.hpp
@@ -42,6 +42,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/builder/osm_object_builder.hpp>
#include <osmium/io/detail/pbf.hpp> // IWYU pragma: export
+#include <osmium/io/detail/pbf_type_conv.hpp>
#include <osmium/io/detail/zlib.hpp>
#include <osmium/io/header.hpp>
#include <osmium/osm/location.hpp>
@@ -106,7 +107,7 @@ namespace osmium {
m_date_factor = pbf_primitive_block.date_granularity() / 1000;
m_granularity = pbf_primitive_block.granularity();
- for (int i=0; i < pbf_primitive_block.primitivegroup_size(); ++i) {
+ for (int i = 0; i < pbf_primitive_block.primitivegroup_size(); ++i) {
const OSMPBF::PrimitiveGroup& group = pbf_primitive_block.primitivegroup(i);
if (group.has_dense()) {
@@ -148,7 +149,7 @@ namespace osmium {
}
void parse_node_group(const OSMPBF::PrimitiveGroup& group) {
- for (int i=0; i < group.nodes_size(); ++i) {
+ for (int i = 0; i < group.nodes_size(); ++i) {
osmium::builder::NodeBuilder builder(m_buffer);
const OSMPBF::Node& pbf_node = group.nodes(i);
parse_attributes(builder, pbf_node);
@@ -161,7 +162,7 @@ namespace osmium {
if (pbf_node.keys_size() > 0) {
osmium::builder::TagListBuilder tl_builder(m_buffer, &builder);
- for (int tag=0; tag < pbf_node.keys_size(); ++tag) {
+ for (int tag = 0; tag < pbf_node.keys_size(); ++tag) {
tl_builder.add_tag(m_stringtable->s(static_cast<int>(pbf_node.keys(tag))),
m_stringtable->s(static_cast<int>(pbf_node.vals(tag))));
}
@@ -172,7 +173,7 @@ namespace osmium {
}
void parse_way_group(const OSMPBF::PrimitiveGroup& group) {
- for (int i=0; i < group.ways_size(); ++i) {
+ for (int i = 0; i < group.ways_size(); ++i) {
osmium::builder::WayBuilder builder(m_buffer);
const OSMPBF::Way& pbf_way = group.ways(i);
parse_attributes(builder, pbf_way);
@@ -180,7 +181,7 @@ namespace osmium {
if (pbf_way.refs_size() > 0) {
osmium::builder::WayNodeListBuilder wnl_builder(m_buffer, &builder);
int64_t ref = 0;
- for (int n=0; n < pbf_way.refs_size(); ++n) {
+ for (int n = 0; n < pbf_way.refs_size(); ++n) {
ref += pbf_way.refs(n);
wnl_builder.add_node_ref(ref);
}
@@ -188,7 +189,7 @@ namespace osmium {
if (pbf_way.keys_size() > 0) {
osmium::builder::TagListBuilder tl_builder(m_buffer, &builder);
- for (int tag=0; tag < pbf_way.keys_size(); ++tag) {
+ for (int tag = 0; tag < pbf_way.keys_size(); ++tag) {
tl_builder.add_tag(m_stringtable->s(static_cast<int>(pbf_way.keys(tag))),
m_stringtable->s(static_cast<int>(pbf_way.vals(tag))));
}
@@ -199,7 +200,7 @@ namespace osmium {
}
void parse_relation_group(const OSMPBF::PrimitiveGroup& group) {
- for (int i=0; i < group.relations_size(); ++i) {
+ for (int i = 0; i < group.relations_size(); ++i) {
osmium::builder::RelationBuilder builder(m_buffer);
const OSMPBF::Relation& pbf_relation = group.relations(i);
parse_attributes(builder, pbf_relation);
@@ -207,7 +208,7 @@ namespace osmium {
if (pbf_relation.types_size() > 0) {
osmium::builder::RelationMemberListBuilder rml_builder(m_buffer, &builder);
int64_t ref = 0;
- for (int n=0; n < pbf_relation.types_size(); ++n) {
+ for (int n = 0; n < pbf_relation.types_size(); ++n) {
ref += pbf_relation.memids(n);
rml_builder.add_member(osmpbf_membertype_to_item_type(pbf_relation.types(n)), ref, m_stringtable->s(pbf_relation.roles_sid(n)));
}
@@ -215,7 +216,7 @@ namespace osmium {
if (pbf_relation.keys_size() > 0) {
osmium::builder::TagListBuilder tl_builder(m_buffer, &builder);
- for (int tag=0; tag < pbf_relation.keys_size(); ++tag) {
+ for (int tag = 0; tag < pbf_relation.keys_size(); ++tag) {
tl_builder.add_tag(m_stringtable->s(static_cast<int>(pbf_relation.keys(tag))),
m_stringtable->s(static_cast<int>(pbf_relation.vals(tag))));
}
@@ -264,7 +265,7 @@ namespace osmium {
const OSMPBF::DenseNodes& dense = group.dense();
- for (int i=0; i < dense.id_size(); ++i) {
+ for (int i = 0; i < dense.id_size(); ++i) {
bool visible = true;
last_dense_id += dense.id(i);
@@ -361,7 +362,7 @@ namespace osmium {
}
osmium::io::Header header;
- for (int i=0; i < pbf_header_block.required_features_size(); ++i) {
+ for (int i = 0; i < pbf_header_block.required_features_size(); ++i) {
const std::string& feature = pbf_header_block.required_features(i);
if (feature == "OsmSchema-V0.6") continue;
@@ -377,7 +378,7 @@ namespace osmium {
throw osmium::pbf_error(std::string("required feature not supported: ") + feature);
}
- for (int i=0; i < pbf_header_block.optional_features_size(); ++i) {
+ for (int i = 0; i < pbf_header_block.optional_features_size(); ++i) {
const std::string& feature = pbf_header_block.optional_features(i);
header.set("pbf_optional_feature_" + std::to_string(i), feature);
}
diff --git a/include/osmium/io/detail/pbf_stringtable.hpp b/include/osmium/io/detail/pbf_stringtable.hpp
index e3d6fe3..5f540f1 100644
--- a/include/osmium/io/detail/pbf_stringtable.hpp
+++ b/include/osmium/io/detail/pbf_stringtable.hpp
@@ -162,7 +162,7 @@ namespace osmium {
return std::pair<string_info, std::string>(p.second, p.first);
});
- string_id_type n=0;
+ string_id_type n = 0;
for (const auto& mapping : sortedbycount) {
// add the string of the current item to the pbf StringTable
diff --git a/include/osmium/io/detail/pbf.hpp b/include/osmium/io/detail/pbf_type_conv.hpp
similarity index 79%
copy from include/osmium/io/detail/pbf.hpp
copy to include/osmium/io/detail/pbf_type_conv.hpp
index e64e51a..799869a 100644
--- a/include/osmium/io/detail/pbf.hpp
+++ b/include/osmium/io/detail/pbf_type_conv.hpp
@@ -1,5 +1,5 @@
-#ifndef OSMIUM_IO_DETAIL_PBF_HPP
-#define OSMIUM_IO_DETAIL_PBF_HPP
+#ifndef OSMIUM_IO_DETAIL_PBF_TYPE_CONV_HPP
+#define OSMIUM_IO_DETAIL_PBF_TYPE_CONV_HPP
/*
@@ -33,18 +33,8 @@ DEALINGS IN THE SOFTWARE.
*/
-#include <stdexcept>
-
#include <osmpbf/osmpbf.h>
-// needed for htonl and ntohl
-#ifndef _WIN32
-# include <netinet/in.h>
-#else
-# include <winsock2.h>
-#endif
-
-#include <osmium/io/error.hpp>
#include <osmium/osm/item_type.hpp>
namespace osmium {
@@ -77,22 +67,7 @@ namespace osmium {
}
}
- /**
- * Exception thrown when there was a problem with parsing the PBF format of
- * a file.
- */
- struct pbf_error : public io_error {
-
- pbf_error(const std::string& what) :
- io_error(std::string("PBF error: ") + what) {
- }
-
- pbf_error(const char* what) :
- io_error(std::string("PBF error: ") + what) {
- }
-
- }; // struct pbf_error
} // namespace osmium
-#endif // OSMIUM_IO_DETAIL_PBF_HPP
+#endif // OSMIUM_IO_DETAIL_PBF_TYPE_CONV_HPP
diff --git a/include/osmium/io/detail/read_write.hpp b/include/osmium/io/detail/read_write.hpp
index 6651cce..9863bd7 100644
--- a/include/osmium/io/detail/read_write.hpp
+++ b/include/osmium/io/detail/read_write.hpp
@@ -122,7 +122,7 @@ namespace osmium {
* @throws std::system_error On error.
*/
inline void reliable_write(const int fd, const unsigned char* output_buffer, const size_t size) {
- constexpr size_t max_write = 100 * 1024 * 1024; // Max 100 MByte per write
+ constexpr size_t max_write = 100L * 1024L * 1024L; // Max 100 MByte per write
size_t offset = 0;
do {
auto write_count = size - offset;
diff --git a/include/osmium/io/detail/xml_input_format.hpp b/include/osmium/io/detail/xml_input_format.hpp
index c03f84d..a1c6666 100644
--- a/include/osmium/io/detail/xml_input_format.hpp
+++ b/include/osmium/io/detail/xml_input_format.hpp
@@ -66,6 +66,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/location.hpp>
#include <osmium/osm/object.hpp>
#include <osmium/osm/types.hpp>
+#include <osmium/osm/types_from_string.hpp>
#include <osmium/thread/queue.hpp>
#include <osmium/thread/util.hpp>
#include <osmium/util/cast.hpp>
diff --git a/include/osmium/io/detail/xml_output_format.hpp b/include/osmium/io/detail/xml_output_format.hpp
index 73a7263..65ba171 100644
--- a/include/osmium/io/detail/xml_output_format.hpp
+++ b/include/osmium/io/detail/xml_output_format.hpp
@@ -130,7 +130,7 @@ namespace osmium {
const bool m_write_change_ops;
void write_spaces(int num) {
- for (; num!=0; --num) {
+ for (; num != 0; --num) {
*m_out += ' ';
}
}
diff --git a/include/osmium/io/gzip_compression.hpp b/include/osmium/io/gzip_compression.hpp
index 8bc1e5a..2723977 100644
--- a/include/osmium/io/gzip_compression.hpp
+++ b/include/osmium/io/gzip_compression.hpp
@@ -76,7 +76,7 @@ namespace osmium {
namespace detail {
- OSMIUM_NORETURN inline void throw_gzip_error(gzFile gzfile, const char* msg, int zlib_error=0) {
+ OSMIUM_NORETURN inline void throw_gzip_error(gzFile gzfile, const char* msg, int zlib_error = 0) {
std::string error("gzip error: ");
error += msg;
error += ": ";
diff --git a/include/osmium/io/reader.hpp b/include/osmium/io/reader.hpp
index 8d24652..c68a8e1 100644
--- a/include/osmium/io/reader.hpp
+++ b/include/osmium/io/reader.hpp
@@ -109,7 +109,7 @@ namespace osmium {
}
if (pid == 0) { // child
// close all file descriptors except one end of the pipe
- for (int i=0; i < 32; ++i) {
+ for (int i = 0; i < 32; ++i) {
if (i != pipefd[1]) {
::close(i);
}
diff --git a/include/osmium/memory/buffer.hpp b/include/osmium/memory/buffer.hpp
index 85a3a46..ecf8f33 100644
--- a/include/osmium/memory/buffer.hpp
+++ b/include/osmium/memory/buffer.hpp
@@ -414,6 +414,15 @@ namespace osmium {
}
template <class T>
+ t_iterator<T> get_iterator(size_t offset) {
+ return t_iterator<T>(m_data + offset, m_data + m_committed);
+ }
+
+ iterator get_iterator(size_t offset) {
+ return iterator(m_data + offset, m_data + m_committed);
+ }
+
+ template <class T>
t_iterator<T> end() {
return t_iterator<T>(m_data + m_committed, m_data + m_committed);
}
@@ -432,6 +441,15 @@ namespace osmium {
}
template <class T>
+ t_const_iterator<T> get_iterator(size_t offset) const {
+ return t_const_iterator<T>(m_data + offset, m_data + m_committed);
+ }
+
+ const_iterator get_iterator(size_t offset) const {
+ return const_iterator(m_data + offset, m_data + m_committed);
+ }
+
+ template <class T>
t_const_iterator<T> cend() const {
return t_const_iterator<T>(m_data + m_committed, m_data + m_committed);
}
diff --git a/include/osmium/memory/item.hpp b/include/osmium/memory/item.hpp
index 58d63df..2679ca6 100644
--- a/include/osmium/memory/item.hpp
+++ b/include/osmium/memory/item.hpp
@@ -118,7 +118,7 @@ namespace osmium {
protected:
- explicit Item(item_size_type size=0, item_type type=item_type()) noexcept :
+ explicit Item(item_size_type size = 0, item_type type = item_type()) noexcept :
m_size(size),
m_type(type),
m_removed(false),
diff --git a/include/osmium/osm/changeset.hpp b/include/osmium/osm/changeset.hpp
index 0ab4e9b..20def70 100644
--- a/include/osmium/osm/changeset.hpp
+++ b/include/osmium/osm/changeset.hpp
@@ -44,6 +44,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/tag.hpp>
#include <osmium/osm/timestamp.hpp>
#include <osmium/osm/types.hpp>
+#include <osmium/osm/types_from_string.hpp>
namespace osmium {
diff --git a/include/osmium/osm/diff_object.hpp b/include/osmium/osm/diff_object.hpp
index 55a5cef..1e053fd 100644
--- a/include/osmium/osm/diff_object.hpp
+++ b/include/osmium/osm/diff_object.hpp
@@ -112,8 +112,35 @@ namespace osmium {
return m_curr->timestamp();
}
+ /**
+ * Return the timestamp when the current version of the object is
+ * not valid any more, ie the time when the next version of the object
+ * is valid. If this is the last version of the object, this will
+ * return a special "end of time" timestamp that is guaranteed to
+ * be larger than any normal timestamp.
+ */
const osmium::Timestamp end_time() const noexcept {
- return last() ? osmium::Timestamp() : m_next->timestamp();
+ return last() ? osmium::end_of_time() : m_next->timestamp();
+ }
+
+ /**
+ * Current object version is valid between time "from" (inclusive) and
+ * time "to" (not inclusive).
+ *
+ * This is a bit more complex than you'd think, because we have to
+ * handle the case properly where the start_time() == end_time().
+ */
+ bool is_between(const osmium::Timestamp& from, const osmium::Timestamp& to) const noexcept {
+ return start_time() < to &&
+ ((start_time() != end_time() && end_time() > from) ||
+ (start_time() == end_time() && end_time() >= from));
+ }
+
+ /**
+ * Current object version is visible at the given timestamp.
+ */
+ bool is_visible_at(const osmium::Timestamp& timestamp) const noexcept {
+ return start_time() <= timestamp && end_time() > timestamp && m_curr->visible();
}
}; // class DiffObject
diff --git a/include/osmium/osm/item_type.hpp b/include/osmium/osm/item_type.hpp
index c2187a3..54975e3 100644
--- a/include/osmium/osm/item_type.hpp
+++ b/include/osmium/osm/item_type.hpp
@@ -33,6 +33,7 @@ DEALINGS IN THE SOFTWARE.
*/
+#include <cassert>
#include <cstdint> // IWYU pragma: keep
#include <iosfwd>
#include <stdexcept>
@@ -56,6 +57,25 @@ namespace osmium {
}; // enum class item_type
+ /**
+ * Return item_type for index:
+ * 0 -> node, 1 -> way, 2 -> relation
+ */
+ inline item_type nwr_index_to_item_type(unsigned int i) noexcept {
+ assert(i <= 2);
+ return item_type(i+1);
+ }
+
+ /**
+ * Return index for item_type:
+ * node -> 0, way -> 1, relation -> 2
+ */
+ inline unsigned int item_type_to_nwr_index(item_type type) noexcept {
+ unsigned int i = static_cast<unsigned int>(type);
+ assert(i >= 1 && i <= 3);
+ return i - 1;
+ }
+
inline item_type char_to_item_type(const char c) noexcept {
switch (c) {
case 'X':
diff --git a/include/osmium/osm/node_ref.hpp b/include/osmium/osm/node_ref.hpp
index 1a66607..76afa75 100644
--- a/include/osmium/osm/node_ref.hpp
+++ b/include/osmium/osm/node_ref.hpp
@@ -54,7 +54,7 @@ namespace osmium {
public:
- NodeRef(const osmium::object_id_type ref=0, const osmium::Location& location=Location()) noexcept :
+ NodeRef(const osmium::object_id_type ref = 0, const osmium::Location& location = Location()) noexcept :
m_ref(ref),
m_location(location) {
}
diff --git a/include/osmium/osm/object.hpp b/include/osmium/osm/object.hpp
index d5ae48a..8c745ce 100644
--- a/include/osmium/osm/object.hpp
+++ b/include/osmium/osm/object.hpp
@@ -48,6 +48,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/tag.hpp>
#include <osmium/osm/timestamp.hpp>
#include <osmium/osm/types.hpp>
+#include <osmium/osm/types_from_string.hpp>
namespace osmium {
diff --git a/include/osmium/osm/relation.hpp b/include/osmium/osm/relation.hpp
index 6c03815..99a4f4c 100644
--- a/include/osmium/osm/relation.hpp
+++ b/include/osmium/osm/relation.hpp
@@ -101,7 +101,7 @@ namespace osmium {
static constexpr item_type collection_type = item_type::relation_member_list;
- RelationMember(const object_id_type ref=0, const item_type type=item_type(), const bool full=false) noexcept :
+ RelationMember(const object_id_type ref = 0, const item_type type = item_type(), const bool full = false) noexcept :
m_ref(ref),
m_type(type),
m_flags(full ? 1 : 0) {
@@ -120,6 +120,11 @@ namespace osmium {
return static_cast<unsigned_object_id_type>(std::abs(m_ref));
}
+ RelationMember& set_ref(const osmium::object_id_type ref) noexcept {
+ m_ref = ref;
+ return *this;
+ }
+
item_type type() const noexcept {
return m_type;
}
diff --git a/include/osmium/osm/timestamp.hpp b/include/osmium/osm/timestamp.hpp
index f36ea36..e4c6807 100644
--- a/include/osmium/osm/timestamp.hpp
+++ b/include/osmium/osm/timestamp.hpp
@@ -42,6 +42,7 @@ DEALINGS IN THE SOFTWARE.
#include <time.h>
#include <osmium/util/compatibility.hpp>
+#include <osmium/util/minmax.hpp>
namespace osmium {
@@ -113,6 +114,10 @@ namespace osmium {
return static_cast<time_t>(m_timestamp);
}
+ explicit constexpr operator uint32_t() const noexcept {
+ return m_timestamp;
+ }
+
template <typename T>
void operator+=(T time_difference) noexcept {
m_timestamp += time_difference;
@@ -166,6 +171,16 @@ namespace osmium {
return out;
}
+ template <>
+ inline osmium::Timestamp min_op_start_value<osmium::Timestamp>() {
+ return end_of_time();
+ }
+
+ template <>
+ inline osmium::Timestamp max_op_start_value<osmium::Timestamp>() {
+ return start_of_time();
+ }
+
} // namespace osmium
#endif // OSMIUM_OSM_TIMESTAMP_HPP
diff --git a/include/osmium/osm/types.hpp b/include/osmium/osm/types.hpp
index aea61bd..b3414e5 100644
--- a/include/osmium/osm/types.hpp
+++ b/include/osmium/osm/types.hpp
@@ -34,7 +34,6 @@ DEALINGS IN THE SOFTWARE.
*/
#include <cstdint>
-#include <cstdlib>
namespace osmium {
@@ -58,26 +57,6 @@ namespace osmium {
*/
typedef uint16_t string_size_type;
- inline object_id_type string_to_object_id(const char* string) {
- return std::atoll(string);
- }
-
- inline object_version_type string_to_object_version(const char* string) {
- return static_cast<object_version_type>(std::atol(string));
- }
-
- inline changeset_id_type string_to_changeset_id(const char* string) {
- return static_cast<changeset_id_type>(std::atol(string));
- }
-
- inline signed_user_id_type string_to_user_id(const char* string) {
- return static_cast<signed_user_id_type>(std::atol(string));
- }
-
- inline num_changes_type string_to_num_changes(const char* string) {
- return static_cast<num_changes_type>(std::atol(string));
- }
-
} // namespace osmium
#endif // OSMIUM_OSM_TYPES_HPP
diff --git a/include/osmium/osm/types_from_string.hpp b/include/osmium/osm/types_from_string.hpp
new file mode 100644
index 0000000..b8de14c
--- /dev/null
+++ b/include/osmium/osm/types_from_string.hpp
@@ -0,0 +1,116 @@
+#ifndef OSMIUM_OSM_TYPES_FROM_STRING_HPP
+#define OSMIUM_OSM_TYPES_FROM_STRING_HPP
+
+/*
+
+This file is part of Osmium (http://osmcode.org/libosmium).
+
+Copyright 2013-2015 Jochen Topf <jochen at topf.org> and others (see README).
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <cassert>
+#include <cctype>
+#include <cstdint>
+#include <cstdlib>
+#include <limits>
+#include <string>
+#include <utility>
+
+#include <osmium/osm/entity_bits.hpp>
+#include <osmium/osm/types.hpp>
+
+namespace osmium {
+
+ inline object_id_type string_to_object_id(const char* input) {
+ assert(input);
+ if (*input != '\0' && !std::isspace(*input)) {
+ char* end;
+ auto id = std::strtoll(input, &end, 10);
+ if (id != std::numeric_limits<long long>::min() && id != std::numeric_limits<long long>::max() && *end == '\0') {
+ return id;
+ }
+ }
+ throw std::range_error(std::string("illegal id: '") + input + "'");
+ }
+
+ inline std::pair<osmium::item_type, osmium::object_id_type> string_to_object_id(const char* input, osmium::osm_entity_bits::type types) {
+ assert(input);
+ assert(types != osmium::osm_entity_bits::nothing);
+ if (*input != '\0') {
+ if (std::isdigit(*input)) {
+ return std::make_pair(osmium::item_type::undefined, string_to_object_id(input));
+ }
+ osmium::item_type t = osmium::char_to_item_type(*input);
+ if (osmium::osm_entity_bits::from_item_type(t) & types) {
+ return std::make_pair(t, string_to_object_id(input+1));
+ }
+ }
+ throw std::range_error(std::string("not a valid id: '") + input + "'");
+ }
+
+ namespace detail {
+
+ inline long string_to_ulong(const char* input, const char *name) {
+ if (*input != '\0' && *input != '-' && !std::isspace(*input)) {
+ char* end;
+ auto value = std::strtoul(input, &end, 10);
+ if (value != std::numeric_limits<unsigned long>::max() && *end == '\0') {
+ return value;
+ }
+ }
+ throw std::range_error(std::string("illegal ") + name + ": '" + input + "'");
+ }
+
+ } // namespace detail
+
+ inline object_version_type string_to_object_version(const char* input) {
+ assert(input);
+ return static_cast<object_version_type>(detail::string_to_ulong(input, "version"));
+ }
+
+ inline changeset_id_type string_to_changeset_id(const char* input) {
+ assert(input);
+ return static_cast<changeset_id_type>(detail::string_to_ulong(input, "changeset"));
+ }
+
+ inline signed_user_id_type string_to_user_id(const char* input) {
+ assert(input);
+ if (input[0] == '-' && input[1] == '1' && input[2] == '\0') {
+ return -1;
+ }
+ return static_cast<signed_user_id_type>(detail::string_to_ulong(input, "user id"));
+ }
+
+ inline num_changes_type string_to_num_changes(const char* input) {
+ assert(input);
+ return static_cast<num_changes_type>(detail::string_to_ulong(input, "value for num changes"));
+ }
+
+} // namespace osmium
+
+#endif // OSMIUM_OSM_TYPES_FROM_STRING_HPP
diff --git a/include/osmium/relations/collector.hpp b/include/osmium/relations/collector.hpp
index d4af916..40e3773 100644
--- a/include/osmium/relations/collector.hpp
+++ b/include/osmium/relations/collector.hpp
@@ -389,7 +389,7 @@ namespace osmium {
RelationMeta relation_meta(offset);
- int n=0;
+ int n = 0;
for (auto& member : m_relations_buffer.get<osmium::Relation>(offset).members()) {
if (static_cast<TCollector*>(this)->keep_member(relation_meta, member)) {
member_meta(member.type()).emplace_back(member.ref(), m_relations.size(), n);
@@ -512,7 +512,7 @@ namespace osmium {
double percent = static_cast<double>(size_before - size_after);
percent /= size_before;
percent *= 100;
- std::cerr << "PURGE (size before=" << size_before << " after=" << size_after << " purged=" << (size_before - size_after) << " / " << static_cast<int>(percent) << "%)\n";
+// std::cerr << "PURGE (size before=" << size_before << " after=" << size_after << " purged=" << (size_before - size_after) << " / " << static_cast<int>(percent) << "%)\n";
m_count_complete = 0;
}
}
diff --git a/include/osmium/thread/pool.hpp b/include/osmium/thread/pool.hpp
index bc1e9a8..3916031 100644
--- a/include/osmium/thread/pool.hpp
+++ b/include/osmium/thread/pool.hpp
@@ -128,7 +128,7 @@ namespace osmium {
}
try {
- for (int i=0; i < m_num_threads; ++i) {
+ for (int i = 0; i < m_num_threads; ++i) {
m_threads.push_back(std::thread(&Pool::worker_thread, this));
}
} catch (...) {
@@ -149,6 +149,7 @@ namespace osmium {
~Pool() {
m_done = true;
+ m_work_queue.shutdown();
}
size_t queue_size() const {
diff --git a/include/osmium/thread/queue.hpp b/include/osmium/thread/queue.hpp
index 12e5932..7fa6469 100644
--- a/include/osmium/thread/queue.hpp
+++ b/include/osmium/thread/queue.hpp
@@ -49,7 +49,7 @@ namespace osmium {
namespace thread {
- OSMIUM_CONSTEXPR std::chrono::milliseconds full_queue_sleep_duration { 10 }; // XXX
+ static const std::chrono::milliseconds full_queue_sleep_duration { 10 }; // XXX
/**
* A thread-safe queue.
@@ -71,6 +71,8 @@ namespace osmium {
/// Used to signal readers when data is available in the queue.
std::condition_variable m_data_available;
+ std::atomic<bool> m_done;
+
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
/// The largest size the queue has been so far.
size_t m_largest_size;
@@ -94,7 +96,8 @@ namespace osmium {
m_name(name),
m_mutex(),
m_queue(),
- m_data_available()
+ m_data_available(),
+ m_done(false)
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
,
m_largest_size(0),
@@ -104,6 +107,7 @@ namespace osmium {
}
~Queue() {
+ shutdown();
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
std::cerr << "queue '" << m_name << "' with max_size=" << m_max_size << " had largest size " << m_largest_size << " and was full " << m_full_counter << " times\n";
#endif
@@ -132,24 +136,33 @@ namespace osmium {
m_data_available.notify_one();
}
+ void shutdown() {
+ m_done = true;
+ m_data_available.notify_all();
+ }
+
void wait_and_pop(T& value) {
std::unique_lock<std::mutex> lock(m_mutex);
m_data_available.wait(lock, [this] {
- return !m_queue.empty();
+ return !m_queue.empty() || m_done;
});
- value=std::move(m_queue.front());
- m_queue.pop();
+ if (!m_queue.empty()) {
+ value = std::move(m_queue.front());
+ m_queue.pop();
+ }
}
void wait_and_pop_with_timeout(T& value) {
std::unique_lock<std::mutex> lock(m_mutex);
if (!m_data_available.wait_for(lock, std::chrono::seconds(1), [this] {
- return !m_queue.empty();
+ return !m_queue.empty() || m_done;
})) {
return;
}
- value=std::move(m_queue.front());
- m_queue.pop();
+ if (!m_queue.empty()) {
+ value = std::move(m_queue.front());
+ m_queue.pop();
+ }
}
bool try_pop(T& value) {
@@ -157,7 +170,7 @@ namespace osmium {
if (m_queue.empty()) {
return false;
}
- value=std::move(m_queue.front());
+ value = std::move(m_queue.front());
m_queue.pop();
return true;
}
diff --git a/include/osmium/thread/sorted_queue.hpp b/include/osmium/thread/sorted_queue.hpp
index e0181eb..e76ade1 100644
--- a/include/osmium/thread/sorted_queue.hpp
+++ b/include/osmium/thread/sorted_queue.hpp
@@ -107,7 +107,7 @@ namespace osmium {
m_data_available.wait(lock, [this] {
return !empty_intern();
});
- value=std::move(m_queue.front());
+ value = std::move(m_queue.front());
m_queue.pop_front();
++m_offset;
}
@@ -122,7 +122,7 @@ namespace osmium {
if (empty_intern()) {
return false;
}
- value=std::move(m_queue.front());
+ value = std::move(m_queue.front());
m_queue.pop_front();
++m_offset;
return true;
diff --git a/include/osmium/util/cast.hpp b/include/osmium/util/cast.hpp
index 80adadf..4866fde 100644
--- a/include/osmium/util/cast.hpp
+++ b/include/osmium/util/cast.hpp
@@ -37,6 +37,7 @@ DEALINGS IN THE SOFTWARE.
# include <cassert>
#endif
+#include <cstdint>
#include <limits>
#include <type_traits>
@@ -93,7 +94,7 @@ namespace osmium {
template <typename T, typename F, typename std::enable_if<are_real_integers<T, F>::value && !std::is_same<T, F>::value && (sizeof(T) <= sizeof(F)) && std::is_signed<T>::value && std::is_unsigned<F>::value, int>::type = 0>
inline T static_cast_with_assert(const F value) {
- assert(value <= std::numeric_limits<T>::max());
+ assert(static_cast<int64_t>(value) <= static_cast<int64_t>(std::numeric_limits<T>::max()));
return static_cast<T>(value);
}
diff --git a/include/osmium/util/data_file.hpp b/include/osmium/util/data_file.hpp
new file mode 100644
index 0000000..3194988
--- /dev/null
+++ b/include/osmium/util/data_file.hpp
@@ -0,0 +1,192 @@
+#ifndef OSMIUM_UTIL_DATA_FILE_HPP
+#define OSMIUM_UTIL_DATA_FILE_HPP
+
+/*
+
+This file is part of Osmium (http://osmcode.org/libosmium).
+
+Copyright 2013-2015 Jochen Topf <jochen at topf.org> and others (see README).
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <cerrno>
+#include <cstdio>
+#include <string>
+#include <system_error>
+
+#ifdef _WIN32
+# include <io.h>
+# include <windows.h>
+#endif
+
+#include <osmium/util/file.hpp>
+
+namespace osmium {
+
+ namespace util {
+
+ /**
+ * Class wrapper for convenient access to some low-level file
+ * functions.
+ */
+ class DataFile {
+
+ FILE* m_file;
+
+ public:
+
+ /**
+ * Create and open a temporary file. It is removed after opening.
+ *
+ * @throws std::system_error if something went wrong.
+ */
+ DataFile() :
+ m_file(::tmpfile()) {
+ if (!m_file) {
+ throw std::system_error(errno, std::system_category(), "tmpfile failed");
+ }
+ }
+
+ /**
+ * Create and open a temporary file with the specified size. It
+ * is removed after opening.
+ *
+ * @throws std::system_error if something went wrong.
+ */
+ explicit DataFile(size_t size) :
+ DataFile() {
+ grow(size);
+ }
+
+ /**
+ * Create and open a named file.
+ *
+ * @param filename the name of the file
+ * @param writable should the file be writable?
+ * @throws std::system_error if something went wrong.
+ */
+ DataFile(const char* filename, bool writable) :
+ m_file(::fopen(filename, writable ? "wb+" : "rb" )) {
+ if (!m_file) {
+ throw std::system_error(errno, std::system_category(), "fopen failed");
+ }
+ }
+
+ /**
+ * Create and open a named file.
+ *
+ * @param filename the name of the file
+ * @param writable should the file be writable?
+ * @throws std::system_error if something went wrong.
+ */
+ DataFile(const std::string& filename, bool writable) :
+ DataFile(filename.c_str(), writable) {
+ }
+
+ /**
+ * In boolean context the DataFile class returns true if the file
+ * is open.
+ */
+ operator bool() const noexcept {
+ return m_file != nullptr;
+ }
+
+ /**
+ * Close the file.
+ *
+ * Does nothing if the file is already closed.
+ *
+ * @throws std::system_error if file could not be closed
+ */
+ void close() {
+ if (m_file) {
+ if (::fclose(m_file) != 0) {
+ throw std::system_error(errno, std::system_category(), "fclose failed");
+ }
+ m_file = nullptr;
+ }
+ }
+
+ ~DataFile() noexcept {
+ try {
+ close();
+ } catch (std::system_error&) {
+ // ignore
+ }
+ }
+
+ /**
+ * Get file descriptor of underlying file.
+ *
+ * @throws std::runtime_errro if file is not open
+ * @throws std::system_error if fileno(3) call failed
+ */
+ int fd() const {
+ if (!m_file) {
+ throw std::runtime_error("no open file");
+ }
+
+ int fd = ::fileno(m_file);
+
+ if (fd == -1) {
+ throw std::system_error(errno, std::system_category(), "fileno failed");
+ }
+
+ return fd;
+ }
+
+ /**
+ * Ask the operating system for the size of this file.
+ *
+ * @throws std::system_error if fstat(2) call failed
+ */
+ size_t size() const {
+ return osmium::util::file_size(fd());
+ }
+
+ /**
+ * Grow file to given size.
+ *
+ * If the file is large enough already, nothing is done.
+ * The file is never shrunk.
+ *
+ * @throws std::system_error if ftruncate(2) call failed
+ */
+ void grow(size_t new_size) const {
+ if (size() < new_size) {
+ osmium::util::resize_file(fd(), new_size);
+ }
+ }
+
+ }; // class DataFile
+
+ } // namespace util
+
+} // namespace osmium
+
+
+#endif // OSMIUM_UTIL_DATA_FILE_HPP
diff --git a/include/osmium/index/detail/mmap_vector_anon.hpp b/include/osmium/util/delta.hpp
similarity index 58%
copy from include/osmium/index/detail/mmap_vector_anon.hpp
copy to include/osmium/util/delta.hpp
index 0ea4f9d..dd733ce 100644
--- a/include/osmium/index/detail/mmap_vector_anon.hpp
+++ b/include/osmium/util/delta.hpp
@@ -1,5 +1,5 @@
-#ifndef OSMIUM_INDEX_DETAIL_MMAP_VECTOR_ANON_HPP
-#define OSMIUM_INDEX_DETAIL_MMAP_VECTOR_ANON_HPP
+#ifndef OSMIUM_UTIL_DELTA_HPP
+#define OSMIUM_UTIL_DELTA_HPP
/*
@@ -33,46 +33,65 @@ DEALINGS IN THE SOFTWARE.
*/
-#ifdef __linux__
+#include <utility>
-#include <cstddef>
+namespace osmium {
-#include <osmium/index/detail/typed_mmap.hpp>
-#include <osmium/index/detail/mmap_vector_base.hpp>
+ namespace util {
-namespace osmium {
+ /**
+ * Helper class for delta encoding.
+ */
+ template <typename T>
+ class DeltaEncode {
+
+ T m_value;
+
+ public:
+
+ DeltaEncode() :
+ m_value(0) {
+ }
+
+ void clear() {
+ m_value = 0;
+ }
+
+ T update(T new_value) {
+ using std::swap;
+ swap(m_value, new_value);
+ return m_value - new_value;
+ }
- namespace detail {
+ }; // class DeltaEncode
/**
- * This class looks and behaves like STL vector, but uses mmap internally.
+ * Helper class for delta decoding.
*/
template <typename T>
- class mmap_vector_anon : public mmap_vector_base<T, mmap_vector_anon> {
+ class DeltaDecode {
+
+ T m_value;
public:
- mmap_vector_anon() :
- mmap_vector_base<T, osmium::detail::mmap_vector_anon>(
- -1,
- osmium::detail::mmap_vector_size_increment,
- 0,
- osmium::detail::typed_mmap<T>::map(osmium::detail::mmap_vector_size_increment)) {
+ DeltaDecode() :
+ m_value(0) {
+ }
+
+ void clear() {
+ m_value = 0;
}
- void reserve(size_t new_capacity) {
- if (new_capacity > this->capacity()) {
- this->data(osmium::detail::typed_mmap<T>::remap(this->data(), this->capacity(), new_capacity));
- this->m_capacity = new_capacity;
- }
+ T update(T delta) {
+ m_value += delta;
+ return m_value;
}
- }; // class mmap_vector_anon
+ }; // class DeltaDecode
- } // namespace detail
+ } // namespace util
} // namespace osmium
-#endif // __linux__
-
-#endif // OSMIUM_INDEX_DETAIL_MMAP_VECTOR_ANON_HPP
+#endif // OSMIUM_UTIL_DELTA_HPP
diff --git a/include/osmium/util/file.hpp b/include/osmium/util/file.hpp
new file mode 100644
index 0000000..afc595b
--- /dev/null
+++ b/include/osmium/util/file.hpp
@@ -0,0 +1,118 @@
+#ifndef OSMIUM_UTIL_FILE_HPP
+#define OSMIUM_UTIL_FILE_HPP
+
+/*
+
+This file is part of Osmium (http://osmcode.org/libosmium).
+
+Copyright 2013-2015 Jochen Topf <jochen at topf.org> and others (see README).
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <cerrno>
+#include <cstdio>
+#include <system_error>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifdef _WIN32
+# include <io.h>
+# include <windows.h>
+#endif
+
+#ifndef _MSC_VER
+# include <unistd.h>
+#else
+// https://msdn.microsoft.com/en-us/library/whx354w1.aspx
+# define ftruncate _chsize_s
+#endif
+
+namespace osmium {
+
+ namespace util {
+
+ /**
+ * Get file size.
+ * This is a small wrapper around a system call.
+ *
+ * @param fd File descriptor
+ * @returns file size
+ * @throws std::system_error If system call failed
+ */
+ inline size_t file_size(int fd) {
+#ifdef _MSC_VER
+ // Windows implementation
+ // https://msdn.microsoft.com/en-us/library/dfbc2kec.aspx
+ auto size = ::_filelengthi64(fd);
+ if (size == -1L) {
+ throw std::system_error(errno, std::system_category(), "_filelengthi64 failed");
+ }
+ return size_t(size);
+#else
+ // Unix implementation
+ struct stat s;
+ if (::fstat(fd, &s) != 0) {
+ throw std::system_error(errno, std::system_category(), "fstat failed");
+ }
+ return size_t(s.st_size);
+#endif
+ }
+
+ /**
+ * Resize file.
+ * Small wrapper around ftruncate(2) system call.
+ *
+ * @param fd File descriptor
+ * @param new_size New size
+ * @throws std::system_error If ftruncate(2) call failed
+ */
+ inline void resize_file(int fd, size_t new_size) {
+ if (::ftruncate(fd, new_size) != 0) {
+ throw std::system_error(errno, std::system_category(), "ftruncate failed");
+ }
+ }
+
+ /**
+ * Get the page size for this system.
+ */
+ inline size_t get_pagesize() {
+#ifdef _WIN32
+ // Windows implementation
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ return si.dwPageSize;
+#else
+ // Unix implementation
+ return ::sysconf(_SC_PAGESIZE);
+#endif
+ }
+
+ } // namespace util
+
+} // namespace osmium
+
+#endif // OSMIUM_UTIL_FILE_HPP
diff --git a/include/osmium/util/memory_mapping.hpp b/include/osmium/util/memory_mapping.hpp
new file mode 100644
index 0000000..3880000
--- /dev/null
+++ b/include/osmium/util/memory_mapping.hpp
@@ -0,0 +1,723 @@
+#ifndef OSMIUM_UTIL_MEMORY_MAPPING_HPP
+#define OSMIUM_UTIL_MEMORY_MAPPING_HPP
+
+/*
+
+This file is part of Osmium (http://osmcode.org/libosmium).
+
+Copyright 2013-2015 Jochen Topf <jochen at topf.org> and others (see README).
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <cassert>
+#include <cerrno>
+#include <stdexcept>
+#include <system_error>
+
+#include <osmium/util/file.hpp>
+
+#ifndef _WIN32
+# include <sys/mman.h>
+#else
+# include <io.h>
+# include <windows.h>
+# include <sys/types.h>
+#endif
+
+namespace osmium {
+
+ namespace util {
+
+ /**
+ * Class for wrapping memory mapping system calls.
+ *
+ * Usage for anonymous mapping:
+ * @code
+ * MemoryMapping mapping(1024); // create anonymous mapping with size
+ * auto ptr = mapping.get_addr<char*>(); // get pointer to memory
+ * mapping.unmap(); // release mapping by calling unmap() (or at end of scope)
+ * @endcode
+ *
+ * Or for file-backed mapping:
+ * @code
+ * int fd = ::open(...);
+ * {
+ * MemoryMapping mapping(1024, true, fd, offset);
+ * // use mapping
+ * }
+ * ::close(fd);
+ * @endcode
+ *
+ * If the file backing a file-backed mapping is not large enough, it
+ * will be resized. This works, of course, only for writable files,
+ * so for read-only files you have to make sure they are large enough
+ * for any mapping you want.
+ *
+ * If you ask for a zero-sized mapping, a mapping of the systems page
+ * size will be created instead. For file-backed mapping this will only
+ * work if the file is writable.
+ *
+ * There are different implementations for Unix and Windows systems.
+ * On Unix systems this wraps the mmap(), munmap(), and the mremap()
+ * system calls. On Windows it wraps the CreateFileMapping(),
+ * CloseHandle(), MapViewOfFile(), and UnmapViewOfFile() functions.
+ */
+ class MemoryMapping {
+
+ /// The size of the mapping
+ size_t m_size;
+
+ /// Offset into the file
+ off_t m_offset;
+
+ /// File handle we got the mapping from
+ int m_fd;
+
+ /// Is the memory writable?
+ bool m_writable;
+
+#ifdef _WIN32
+ HANDLE m_handle;
+#endif
+
+ /// The address where the memory is mapped
+ void* m_addr;
+
+ bool is_valid() const noexcept;
+
+ void make_invalid() noexcept;
+
+#ifdef _WIN32
+ typedef DWORD flag_type;
+#else
+ typedef int flag_type;
+#endif
+
+ flag_type get_protection() const noexcept;
+
+ flag_type get_flags() const noexcept;
+
+ // A zero-sized mapping is not allowed by the operating system.
+ // So if the user asks for a mapping of size 0, we map a full
+ // page instead. This way we don't have a special case in the rest
+ // of the code.
+ static size_t initial_size(size_t size) {
+ if (size == 0) {
+ return osmium::util::get_pagesize();
+ }
+ return size;
+ }
+
+#ifdef _WIN32
+ HANDLE get_handle() const noexcept;
+ HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept;
+ void* osmium::util::MemoryMapping::map_view_of_file() const noexcept;
+#endif
+
+ int resize_fd(int fd) {
+ // Anonymous mapping doesn't need resizing.
+ if (fd == -1) {
+ return -1;
+ }
+
+ // Make sure the file backing this mapping is large enough.
+ if (osmium::util::file_size(fd) < m_size + m_offset) {
+ osmium::util::resize_file(fd, m_size + m_offset);
+ }
+ return fd;
+ }
+
+ public:
+
+ /**
+ * Create memory mapping of given size.
+ *
+ * If fd is not set (or fd == -1), an anonymous mapping will be
+ * created, otherwise a mapping based on the file descriptor will
+ * be created.
+ *
+ * @pre size > 0 or writable==true
+ *
+ * @param size Size of the mapping in bytes
+ * @param writable Should the mapping be writable?
+ * @param fd Open file descriptor of a file we want to map
+ * @param offset Offset into the file where the mapping should start
+ * @throws std::system_error if the mapping fails
+ */
+ MemoryMapping(size_t size, bool writable=true, int fd=-1, off_t offset=0);
+
+ /// You can not copy construct a MemoryMapping.
+ MemoryMapping(const MemoryMapping&) = delete;
+
+ /// You can not copy a MemoryMapping.
+ MemoryMapping& operator=(const MemoryMapping&) = delete;
+
+ /**
+ * Move construct a mapping from another one. The other mapping
+ * will be marked as invalid.
+ */
+ MemoryMapping(MemoryMapping&& other);
+
+ /**
+ * Move a mapping. The other mapping will be marked as invalid.
+ */
+ MemoryMapping& operator=(MemoryMapping&& other);
+
+ /**
+ * Releases the mapping by calling unmap(). Will never throw.
+ * Call unmap() instead if you want to be notified of any error.
+ */
+ ~MemoryMapping() noexcept {
+ try {
+ unmap();
+ } catch (std::system_error&) {
+ // ignore
+ }
+ }
+
+ /**
+ * Unmap a mapping. If the mapping is not valid, it will do
+ * nothing.
+ *
+ * @throws std::system_error if the unmapping fails
+ */
+ void unmap();
+
+ /**
+ * Resize a mapping to the given new size.
+ *
+ * On Linux systems this will use the mremap() function. On other
+ * systems it will unmap and remap the memory. This can only be
+ * done for file-based mappings, not anonymous mappings!
+ *
+ * @param new_size Number of bytes to resize to
+ * @throws std::system_error if the remapping fails
+ */
+ void resize(size_t new_size);
+
+ /**
+ * In a boolean context a MemoryMapping is true when it is a valid
+ * existing mapping.
+ */
+ operator bool() const noexcept {
+ return is_valid();
+ }
+
+ /**
+ * The number of bytes mapped. This is the same size you created
+ * the mapping with. The actual mapping will probably be larger
+ * because the system will round it to the page size.
+ */
+ size_t size() const noexcept {
+ return m_size;
+ }
+
+ /**
+ * The file descriptor this mapping was created from.
+ *
+ * @returns file descriptor, -1 for anonymous mappings
+ */
+ int fd() const noexcept {
+ return m_fd;
+ }
+
+ /**
+ * Was this mapping created as a writable mapping?
+ */
+ bool writable() const noexcept {
+ return m_writable;
+ }
+
+ /**
+ * Get the address of the mapping as any pointer type you like.
+ *
+ * @throws std::runtime_error if the mapping is invalid
+ */
+ template <typename T = void>
+ T* get_addr() const {
+ if (is_valid()) {
+ return reinterpret_cast<T*>(m_addr);
+ }
+ throw std::runtime_error("invalid memory mapping");
+ }
+
+ }; // class MemoryMapping
+
+ /**
+ * Anonymous memory mapping.
+ *
+ * Usage for anonymous mapping:
+ * @code
+ * AnonymousMemoryMapping mapping(1024); // create anonymous mapping with size
+ * auto ptr = mapping.get_addr<char*>(); // get pointer to memory
+ * mapping.unmap(); // release mapping by calling unmap() (or at end of scope)
+ * @endcode
+ */
+ class AnonymousMemoryMapping : public MemoryMapping {
+
+ public:
+
+ AnonymousMemoryMapping(size_t size) :
+ MemoryMapping(size) {
+ }
+
+#ifndef __linux__
+ /**
+ * On systems other than Linux anonymous mappings can not be
+ * resized!
+ */
+ void resize(size_t) = delete;
+#endif
+
+ }; // class AnonymousMemoryMapping
+
+ /**
+ * A thin wrapper around the MemoryMapping class used when all the
+ * data in the mapped memory is of the same type. Instead of thinking
+ * about the number of bytes mapped, this counts sizes in the number
+ * of objects of that type.
+ *
+ * Note that no effort is made to actually initialize the objects in
+ * this memory. This has to be done by the caller!
+ */
+ template <typename T>
+ class TypedMemoryMapping {
+
+ MemoryMapping m_mapping;
+
+ public:
+
+ /**
+ * Create anonymous memory mapping of given size.
+ *
+ * @param size Number of objects of type T to be mapped
+ * @throws std::system_error if the mapping fails
+ */
+ TypedMemoryMapping(size_t size) :
+ m_mapping(sizeof(T) * size) {
+ }
+
+ /**
+ * Create file-backed memory mapping of given size. The file must
+ * contain at least `sizeof(T) * size` bytes!
+ *
+ * @param size Number of objects of type T to be mapped
+ * @param writable Should the mapping be writable?
+ * @param fd Open file descriptor of a file we want to map
+ * @param offset Offset into the file where the mapping should start
+ * @throws std::system_error if the mapping fails
+ */
+ TypedMemoryMapping(size_t size, bool writable, int fd, off_t offset = 0) :
+ m_mapping(sizeof(T) * size, writable, fd, sizeof(T) * offset) {
+ }
+
+ /// You can not copy construct a TypedMemoryMapping.
+ TypedMemoryMapping(const TypedMemoryMapping&) = delete;
+
+ /// You can not copy a MemoryMapping.
+ TypedMemoryMapping& operator=(const TypedMemoryMapping&) = delete;
+
+ /**
+ * Move construct a mapping from another one. The other mapping
+ * will be marked as invalid.
+ */
+ TypedMemoryMapping(TypedMemoryMapping&& other) = default;
+
+ /**
+ * Move a mapping. The other mapping will be marked as invalid.
+ */
+ TypedMemoryMapping& operator=(TypedMemoryMapping&& other) = default;
+
+ /**
+ * Releases the mapping by calling unmap(). Will never throw.
+ * Call unmap() instead if you want to be notified of any error.
+ */
+ ~TypedMemoryMapping() = default;
+
+ /**
+ * Unmap a mapping. If the mapping is not valid, it will do
+ * nothing.
+ *
+ * @throws std::system_error if the unmapping fails
+ */
+ void unmap() {
+ m_mapping.unmap();
+ }
+
+ /**
+ * Resize a mapping to the given new size.
+ *
+ * On Linux systems this will use the mremap() function. On other
+ * systems it will unmap and remap the memory. This can only be
+ * done for file-based mappings, not anonymous mappings!
+ *
+ * @param new_size Number of objects of type T to resize to
+ * @throws std::system_error if the remapping fails
+ */
+ void resize(size_t new_size) {
+ m_mapping.resize(sizeof(T) * new_size);
+ }
+
+ /**
+ * In a boolean context a TypedMemoryMapping is true when it is
+ * a valid existing mapping.
+ */
+ operator bool() const noexcept {
+ return !!m_mapping;
+ }
+
+ /**
+ * The number of objects of class T mapped. This is the same size
+ * you created the mapping with. The actual mapping will probably
+ * be larger because the system will round it to the page size.
+ */
+ size_t size() const noexcept {
+ assert(m_mapping.size() % sizeof(T) == 0);
+ return m_mapping.size() / sizeof(T);
+ }
+
+ /**
+ * The file descriptor this mapping was created from.
+ *
+ * @returns file descriptor, -1 for anonymous mappings
+ */
+ int fd() const noexcept {
+ return m_mapping.fd();
+ }
+
+ /**
+ * Was this mapping created as a writable mapping?
+ */
+ bool writable() const noexcept {
+ return m_mapping.writable();
+ }
+
+ /**
+ * Get the address of the beginning of the mapping.
+ *
+ * @throws std::runtime_error if the mapping is invalid
+ */
+ T* begin() {
+ return m_mapping.get_addr<T>();
+ }
+
+ /**
+ * Get the address one past the end of the mapping.
+ *
+ * @throws std::runtime_error if the mapping is invalid
+ */
+ T* end() {
+ return m_mapping.get_addr<T>() + size();
+ }
+
+ const T* cbegin() const {
+ return m_mapping.get_addr<T>();
+ }
+
+ const T* cend() const {
+ return m_mapping.get_addr<T>() + size();
+ }
+
+ const T* begin() const {
+ return m_mapping.get_addr<T>();
+ }
+
+ const T* end() const {
+ return m_mapping.get_addr<T>() + size();
+ }
+
+ }; // class TypedMemoryMapping
+
+ template <typename T>
+ class AnonymousTypedMemoryMapping : public TypedMemoryMapping<T> {
+
+ public:
+
+ AnonymousTypedMemoryMapping(size_t size) :
+ TypedMemoryMapping<T>(size) {
+ }
+
+#ifndef __linux__
+ /**
+ * On systems other than Linux anonymous mappings can not be
+ * resized!
+ */
+ void resize(size_t) = delete;
+#endif
+
+ }; // class AnonymousTypedMemoryMapping
+
+ } // namespace util
+
+} // namespace osmium
+
+#ifndef _WIN32
+
+// =========== Unix implementation =============
+
+// MAP_FAILED is often a macro containing an old style cast
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+
+inline bool osmium::util::MemoryMapping::is_valid() const noexcept {
+ return m_addr != MAP_FAILED;
+}
+
+inline void osmium::util::MemoryMapping::make_invalid() noexcept {
+ m_addr = MAP_FAILED;
+}
+
+#pragma GCC diagnostic pop
+
+// for BSD systems
+#ifndef MAP_ANONYMOUS
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+inline int osmium::util::MemoryMapping::get_protection() const noexcept {
+ if (m_writable) {
+ return PROT_READ | PROT_WRITE;
+ }
+ return PROT_READ;
+}
+
+inline int osmium::util::MemoryMapping::get_flags() const noexcept {
+ if (m_fd == -1) {
+ return MAP_PRIVATE | MAP_ANONYMOUS;
+ }
+ return MAP_SHARED;
+}
+
+inline osmium::util::MemoryMapping::MemoryMapping(size_t size, bool writable, int fd, off_t offset) :
+ m_size(initial_size(size)),
+ m_offset(offset),
+ m_fd(resize_fd(fd)),
+ m_writable(writable),
+ m_addr(::mmap(nullptr, m_size, get_protection(), get_flags(), m_fd, m_offset)) {
+ assert(writable || fd != -1);
+ if (!is_valid()) {
+ throw std::system_error(errno, std::system_category(), "mmap failed");
+ }
+}
+
+inline osmium::util::MemoryMapping::MemoryMapping(MemoryMapping&& other) :
+ m_size(other.m_size),
+ m_offset(other.m_offset),
+ m_fd(other.m_fd),
+ m_writable(other.m_writable),
+ m_addr(other.m_addr) {
+ other.make_invalid();
+}
+
+inline osmium::util::MemoryMapping& osmium::util::MemoryMapping::operator=(osmium::util::MemoryMapping&& other) {
+ unmap();
+ m_size = other.m_size;
+ m_offset = other.m_offset;
+ m_fd = other.m_fd;
+ m_writable = other.m_writable;
+ m_addr = other.m_addr;
+ other.make_invalid();
+ return *this;
+}
+
+inline void osmium::util::MemoryMapping::unmap() {
+ if (is_valid()) {
+ if (::munmap(m_addr, m_size) != 0) {
+ throw std::system_error(errno, std::system_category(), "munmap failed");
+ }
+ make_invalid();
+ }
+}
+
+inline void osmium::util::MemoryMapping::resize(size_t new_size) {
+ assert(new_size > 0 && "can not resize to zero size");
+ if (m_fd == -1) { // anonymous mapping
+#ifdef __linux__
+ m_addr = ::mremap(m_addr, m_size, new_size, MREMAP_MAYMOVE);
+ if (!is_valid()) {
+ throw std::system_error(errno, std::system_category(), "mremap failed");
+ }
+ m_size = new_size;
+#else
+ assert(false && "can't resize anonymous mappings on non-linux systems");
+#endif
+ } else { // file-based mapping
+ unmap();
+ m_size = new_size;
+ resize_fd(m_fd);
+ m_addr = ::mmap(nullptr, new_size, get_protection(), get_flags(), m_fd, m_offset);
+ if (!is_valid()) {
+ throw std::system_error(errno, std::system_category(), "mmap (remap) failed");
+ }
+ }
+}
+
+#else
+
+// =========== Windows implementation =============
+
+/* References:
+ * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
+ * CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
+ * MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
+ * UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
+ */
+
+namespace osmium {
+
+ namespace util {
+
+ inline DWORD dword_hi(uint64_t x) {
+ return static_cast<DWORD>(x >> 32);
+ }
+
+ inline DWORD dword_lo(uint64_t x) {
+ return static_cast<DWORD>(x & 0xffffffff);
+ }
+
+ } // namespace util
+
+} // namespace osmium
+
+inline DWORD osmium::util::MemoryMapping::get_protection() const noexcept {
+ if (m_writable) {
+ return PAGE_READWRITE;
+ }
+ return PAGE_READONLY;
+}
+
+inline DWORD osmium::util::MemoryMapping::get_flags() const noexcept {
+ if (m_fd == -1) {
+ return FILE_MAP_WRITE | FILE_MAP_COPY;
+ }
+ if (m_writable) {
+ return FILE_MAP_WRITE;
+ }
+ return FILE_MAP_READ;
+}
+
+inline HANDLE osmium::util::MemoryMapping::get_handle() const noexcept {
+ if (m_fd == -1) {
+ return INVALID_HANDLE_VALUE;
+ }
+ return reinterpret_cast<HANDLE>(_get_osfhandle(m_fd));
+}
+
+inline HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept {
+ return CreateFileMapping(get_handle(), nullptr, get_protection(), osmium::util::dword_hi(static_cast<uint64_t>(m_size) + m_offset), osmium::util::dword_lo(static_cast<uint64_t>(m_size) + m_offset), nullptr);
+}
+
+inline void* osmium::util::MemoryMapping::map_view_of_file() const noexcept {
+ return MapViewOfFile(m_handle, get_flags(), osmium::util::dword_hi(m_offset), osmium::util::dword_lo(m_offset), m_size);
+}
+
+inline bool osmium::util::MemoryMapping::is_valid() const noexcept {
+ return m_addr != nullptr;
+}
+
+inline void osmium::util::MemoryMapping::make_invalid() noexcept {
+ m_addr = nullptr;
+}
+
+inline osmium::util::MemoryMapping::MemoryMapping(size_t size, bool writable, int fd, off_t offset) :
+ m_size(initial_size(size)),
+ m_offset(offset),
+ m_fd(resize_fd(fd)),
+ m_writable(writable),
+ m_handle(create_file_mapping()),
+ m_addr(nullptr) {
+
+ if (!m_handle) {
+ throw std::system_error(GetLastError(), std::system_category(), "CreateFileMapping failed");
+ }
+
+ m_addr = map_view_of_file();
+ if (!is_valid()) {
+ throw std::system_error(GetLastError(), std::system_category(), "MapViewOfFile failed");
+ }
+}
+
+inline osmium::util::MemoryMapping::MemoryMapping(MemoryMapping&& other) :
+ m_size(other.m_size),
+ m_offset(other.m_offset),
+ m_fd(other.m_fd),
+ m_writable(other.m_writable),
+ m_handle(std::move(other.m_handle)),
+ m_addr(other.m_addr) {
+ other.make_invalid();
+ other.m_handle = nullptr;
+}
+
+inline osmium::util::MemoryMapping& osmium::util::MemoryMapping::operator=(osmium::util::MemoryMapping&& other) {
+ unmap();
+ m_size = other.m_size;
+ m_offset = other.m_offset;
+ m_fd = other.m_fd;
+ m_writable = other.m_writable;
+ m_handle = std::move(other.m_handle);
+ m_addr = other.m_addr;
+ other.make_invalid();
+ other.m_handle = nullptr;
+ return *this;
+}
+
+inline void osmium::util::MemoryMapping::unmap() {
+ if (is_valid()) {
+ if (! UnmapViewOfFile(m_addr)) {
+ throw std::system_error(GetLastError(), std::system_category(), "UnmapViewOfFile failed");
+ }
+ make_invalid();
+ }
+
+ if (m_handle) {
+ if (! CloseHandle(m_handle)) {
+ throw std::system_error(GetLastError(), std::system_category(), "CloseHandle failed");
+ }
+ m_handle = nullptr;
+ }
+}
+
+inline void osmium::util::MemoryMapping::resize(size_t new_size) {
+ unmap();
+
+ m_size = new_size;
+ resize_fd(m_fd);
+
+ m_handle = create_file_mapping();
+ if (!m_handle) {
+ throw std::system_error(GetLastError(), std::system_category(), "CreateFileMapping failed");
+ }
+
+ m_addr = map_view_of_file();
+ if (!is_valid()) {
+ throw std::system_error(GetLastError(), std::system_category(), "MapViewOfFile failed");
+ }
+}
+
+#endif
+
+#endif // OSMIUM_UTIL_MEMORY_MAPPING_HPP
diff --git a/include/osmium/util/minmax.hpp b/include/osmium/util/minmax.hpp
new file mode 100644
index 0000000..05bd39b
--- /dev/null
+++ b/include/osmium/util/minmax.hpp
@@ -0,0 +1,123 @@
+#ifndef OSMIUM_UTIL_MINMAX_HPP
+#define OSMIUM_UTIL_MINMAX_HPP
+
+/*
+
+This file is part of Osmium (http://osmcode.org/libosmium).
+
+Copyright 2013-2015 Jochen Topf <jochen at topf.org> and others (see README).
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <functional>
+#include <limits>
+
+namespace osmium {
+
+ template <typename T>
+ inline T min_op_start_value() {
+ return std::numeric_limits<T>::max();
+ }
+
+ /**
+ * Class for calculating the minimum of a bunch of values.
+ * Works with any numeric type.
+ *
+ * Usage:
+ *
+ * min_op<int> x;
+ * x.update(27);
+ * x.update(12);
+ * auto min = x.get(); // 12
+ */
+ template <typename T>
+ class min_op {
+
+ T m_value;
+
+ public:
+
+ explicit min_op(T start_value = min_op_start_value<T>()) :
+ m_value(start_value) {
+ }
+
+ void update(T value) noexcept {
+ if (value < m_value) {
+ m_value = value;
+ }
+ }
+
+ T operator()() const noexcept {
+ return m_value;
+ }
+
+ };
+
+ template <typename T>
+ inline T max_op_start_value() {
+ return std::numeric_limits<T>::min();
+ }
+
+ /**
+ * Class for calculating the maximum of a bunch of values.
+ * Works with any numeric type.
+ *
+ * Usage:
+ *
+ * max_op<int> x;
+ * x.update(27);
+ * x.update(12);
+ * auto max = x.get(); // 27
+ */
+ template <typename T>
+ class max_op {
+
+ T m_value;
+
+ public:
+
+ explicit max_op(T start_value = max_op_start_value<T>()) :
+ m_value(start_value) {
+ }
+
+ void update(T value) noexcept {
+ if (value > m_value) {
+ m_value = value;
+ }
+ }
+
+ T operator()() const noexcept {
+ return m_value;
+ }
+
+ };
+
+
+
+} // namespace osmium
+
+#endif // OSMIUM_UTIL_MINMAX_HPP
diff --git a/include/osmium/util/string.hpp b/include/osmium/util/string.hpp
index 54eb361..55bfc6c 100644
--- a/include/osmium/util/string.hpp
+++ b/include/osmium/util/string.hpp
@@ -43,21 +43,55 @@ namespace osmium {
* Split string on the separator character.
*
* @param str The string to be split.
- * @param sep The separastor character.
+ * @param sep The separator character.
+ * @param compact Set this to true to remove empty strings from result
* @returns Vector with the parts of the string split up.
*/
- inline std::vector<std::string> split_string(const std::string& str, const char sep) {
+ inline std::vector<std::string> split_string(const std::string& str, const char sep, bool compact = false) {
std::vector<std::string> tokens;
if (!str.empty()) {
size_t pos = 0;
size_t nextpos = str.find_first_of(sep);
while (nextpos != std::string::npos) {
- tokens.push_back(str.substr(pos, nextpos-pos));
+ if (!compact || (nextpos - pos != 0)) {
+ tokens.push_back(str.substr(pos, nextpos-pos));
+ }
pos = nextpos + 1;
nextpos = str.find_first_of(sep, pos);
}
- tokens.push_back(str.substr(pos));
+ if (!compact || pos != str.size()) {
+ tokens.push_back(str.substr(pos));
+ }
+ }
+
+ return tokens;
+ }
+
+ /**
+ * Split string on the separator character(s).
+ *
+ * @param str The string to be split.
+ * @param sep The separator character(s).
+ * @param compact Set this to true to remove empty strings from result
+ * @returns Vector with the parts of the string split up.
+ */
+ inline std::vector<std::string> split_string(const std::string& str, const char* sep, bool compact = false) {
+ std::vector<std::string> tokens;
+
+ if (!str.empty()) {
+ size_t pos = 0;
+ size_t nextpos = str.find_first_of(sep);
+ while (nextpos != std::string::npos) {
+ if (!compact || (nextpos - pos != 0)) {
+ tokens.push_back(str.substr(pos, nextpos-pos));
+ }
+ pos = nextpos + 1;
+ nextpos = str.find_first_of(sep, pos);
+ }
+ if (!compact || pos != str.size()) {
+ tokens.push_back(str.substr(pos));
+ }
}
return tokens;
diff --git a/include/osmium/util/verbose_output.hpp b/include/osmium/util/verbose_output.hpp
index 178781e..249d67f 100644
--- a/include/osmium/util/verbose_output.hpp
+++ b/include/osmium/util/verbose_output.hpp
@@ -87,7 +87,7 @@ namespace osmium {
public:
- explicit VerboseOutput(bool verbose=false) noexcept :
+ explicit VerboseOutput(bool verbose = false) noexcept :
m_start(time(NULL)),
m_verbose(verbose),
m_newline(true) {
diff --git a/scripts/travis_install.sh b/scripts/travis_install.sh
new file mode 100755
index 0000000..528e860
--- /dev/null
+++ b/scripts/travis_install.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# travis_install.sh
+#
+
+if [ "$TRAVIS_OS_NAME" = "linux" ]; then
+
+ # install dependencies
+ sudo apt-get install --yes make libgdal-dev
+
+elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
+
+ brew install protobuf osm-pbf google-sparsehash || true
+
+ # workaround for gdal homebrew problem
+ brew remove gdal
+ brew install gdal
+
+fi
+
+cd ..
+git clone --quiet --depth 1 https://github.com/osmcode/osm-testdata.git
+git clone --quiet --depth 1 https://github.com/scrosby/OSM-binary.git
+cd OSM-binary/src
+make
+
diff --git a/scripts/travis_script.sh b/scripts/travis_script.sh
new file mode 100755
index 0000000..c0f511e
--- /dev/null
+++ b/scripts/travis_script.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# travis_script.sh
+#
+
+mkdir build
+cd build
+
+# GCC ignores the pragmas in the code that disable the "return-type" warning
+# selectively, so use this workaround.
+if [ "${CXX}" = "g++" ]; then
+ WORKAROUND="-DCMAKE_CXX_FLAGS=-Wno-return-type"
+else
+ WORKAROUND=""
+fi
+
+if [ "${CXX}" = "g++" ]; then
+ CXX=g++-4.8
+ CC=gcc-4.8
+fi
+
+cmake -LA \
+ -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
+ -DOSMPBF_INCLUDE_DIR=${TRAVIS_BUILD_DIR}/../OSM-binary/include \
+ -DOSMPBF_LIBRARY=${TRAVIS_BUILD_DIR}/../OSM-binary/src/libosmpbf.a \
+ ${WORKAROUND} \
+ ..
+
+make VERBOSE=1
+ctest --output-on-failure
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 334fe31..02e2433 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -8,6 +8,7 @@
message(STATUS "Configuring unit tests")
+include(CMakeParseArguments)
include_directories(include)
add_library(testlib STATIC test_main.cpp)
@@ -19,40 +20,62 @@ set(ALL_TESTS "")
#
# Define function for adding tests
#
-# Call with parameters:
-# TGROUP - test group (directory)
-# TNAME - name of test
-# ARGV2 - flag to enable test (optional)
-# ARGV3 - libraries to add (optional)
+# add_unit_tests(group name [ENABLE_IF bool] [LIBS libs] [LABELS labels])
+#
+# group - test group (directory)
+# name - name of test
+# bool - boolean variable telling whether the test should be run (optional)
+# libs - lib or libs that should be used when compiling test (optional)
+# labels - additional labels this test should get (optional)
#
#-----------------------------------------------------------------------------
-function(add_unit_test TGROUP TNAME)
- set(ALL_TESTS "${ALL_TESTS};${TGROUP}/${TNAME}" PARENT_SCOPE)
- if((${ARGC} EQUAL 2) OR (${ARGV2}))
+function(add_unit_test _tgroup _tname)
+ set(_testid "${_tgroup}_${_tname}")
+ set(_tpath "${_tgroup}/${_tname}")
+
+ set(ALL_TESTS "${ALL_TESTS};${_tpath}" PARENT_SCOPE)
+
+ cmake_parse_arguments(_param "" "ENABLE_IF" "LIBS;LABELS" ${ARGN})
+
+ if(Osmium_DEBUG)
+ message("${_testid} ENABLE_IF=[${_param_ENABLE_IF}] LIBS=[${_param_LIBS}] LABELS=[${_param_LABELS}]")
+ endif()
+
+ if((NOT(DEFINED _param_ENABLE_IF)) OR (_param_ENABLE_IF))
if(Osmium_DEBUG)
- message("Adding test ${TGROUP}/${TNAME}")
+ message("Adding test: ${_tpath}")
endif()
- set(TESTNAME "${TGROUP}_${TNAME}")
- add_executable(${TESTNAME} t/${TGROUP}/${TNAME}.cpp)
- target_link_libraries(${TESTNAME} testlib)
- if((${ARGV2}) AND (DEFINED ARGV3))
+ add_executable(${_testid} t/${_tpath}.cpp)
+ target_link_libraries(${_testid} testlib)
+
+ if(DEFINED _param_LIBS)
if(Osmium_DEBUG)
- message(" Adding libs ${ARGV3}")
+ message(" Adding libs: ${_param_LIBS}")
endif()
- target_link_libraries(${TESTNAME} ${ARGV3})
+ target_link_libraries(${_testid} ${_param_LIBS})
endif()
- add_test(NAME ${TESTNAME}
+
+ add_test(NAME ${_testid}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND ${TESTNAME}
+ COMMAND ${_testid}
)
- set_tests_properties(${TESTNAME} PROPERTIES
- LABELS "unit;fast;${TGROUP}"
+
+ set(_labels "unit;fast;${_tgroup}")
+ if(DEFINED _param_LABELS)
+ if(Osmium_DEBUG)
+ message(" Adding labels: ${_param_LABELS}")
+ endif()
+ set(_labels "${_labels};${_param_LABELS}")
+ endif()
+
+ set_tests_properties(${_testid} PROPERTIES
+ LABELS "${_labels}"
ENVIRONMENT "OSMIUM_TEST_DATA_DIR=${CMAKE_CURRENT_SOURCE_DIR}"
)
else()
- message("Skipped test ${TGROUP}/${TNAME} because a dependency was not found")
+ message("Skipped test ${_tpath} because a dependency was not found")
set(OSMIUM_SKIPPED_TESTS
- "${OSMIUM_SKIPPED_TESTS} ${TGROUP}/${TNAME}"
+ "${OSMIUM_SKIPPED_TESTS} ${_tpath}"
CACHE STRING "Tests that were skipped because of missing dependecies")
endif()
endfunction()
@@ -74,6 +97,7 @@ add_unit_test(basic test_node_ref)
add_unit_test(basic test_object_comparisons)
add_unit_test(basic test_relation)
add_unit_test(basic test_timestamp)
+add_unit_test(basic test_types_from_string)
add_unit_test(basic test_way)
add_unit_test(buffer test_buffer_node)
@@ -85,34 +109,40 @@ else()
set(GEOS_AND_PROJ_FOUND FALSE)
endif()
add_unit_test(geom test_factory_with_projection
- ${GEOS_AND_PROJ_FOUND}
- "${GEOS_LIBRARY};${PROJ_LIBRARY}")
+ ENABLE_IF ${GEOS_AND_PROJ_FOUND}
+ LIBS ${GEOS_LIBRARY} ${PROJ_LIBRARY})
+add_unit_test(geom test_exception)
add_unit_test(geom test_geojson)
-add_unit_test(geom test_geos ${GEOS_FOUND} ${GEOS_LIBRARY})
-add_unit_test(geom test_geos_wkb ${GEOS_FOUND} ${GEOS_LIBRARY})
+add_unit_test(geom test_geos ENABLE_IF ${GEOS_FOUND} LIBS ${GEOS_LIBRARY})
+add_unit_test(geom test_geos_wkb ENABLE_IF ${GEOS_FOUND} LIBS ${GEOS_LIBRARY})
add_unit_test(geom test_mercator)
-add_unit_test(geom test_ogr ${GDAL_FOUND} ${GDAL_LIBRARY})
-add_unit_test(geom test_projection ${PROJ_FOUND} ${PROJ_LIBRARY})
+add_unit_test(geom test_ogr ENABLE_IF ${GDAL_FOUND} LIBS ${GDAL_LIBRARY})
+add_unit_test(geom test_projection ENABLE_IF ${PROJ_FOUND} LIBS ${PROJ_LIBRARY})
+add_unit_test(geom test_tile)
add_unit_test(geom test_wkb)
add_unit_test(geom test_wkt)
-add_unit_test(index test_id_to_location ${SPARSEHASH_FOUND})
-add_unit_test(index test_typed_mmap)
+add_unit_test(index test_id_to_location ENABLE_IF ${SPARSEHASH_FOUND})
-add_unit_test(io test_bzip2 ${BZIP2_FOUND} ${BZIP2_LIBRARIES})
+add_unit_test(io test_bzip2 ENABLE_IF ${BZIP2_FOUND} LIBS ${BZIP2_LIBRARIES})
add_unit_test(io test_file_formats)
-add_unit_test(io test_reader TRUE "${OSMIUM_XML_LIBRARIES}")
-add_unit_test(io test_output_iterator ${Threads_FOUND} ${CMAKE_THREAD_LIBS_INIT})
+add_unit_test(io test_reader LIBS "${OSMIUM_XML_LIBRARIES}")
+add_unit_test(io test_output_iterator ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT})
add_unit_test(tags test_filter)
add_unit_test(tags test_operators)
add_unit_test(tags test_tag_list)
-add_unit_test(thread test_pool ${Threads_FOUND} ${CMAKE_THREAD_LIBS_INIT})
+add_unit_test(thread test_pool ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT})
add_unit_test(util test_cast_with_assert)
+add_unit_test(util test_data_file)
+add_unit_test(util test_delta)
add_unit_test(util test_double)
+add_unit_test(util test_file)
+add_unit_test(util test_memory_mapping)
+add_unit_test(util test_minmax)
add_unit_test(util test_options)
add_unit_test(util test_string)
diff --git a/test/data-tests/testdata-xml.cpp b/test/data-tests/testdata-xml.cpp
index 1969171..1f846ef 100644
--- a/test/data-tests/testdata-xml.cpp
+++ b/test/data-tests/testdata-xml.cpp
@@ -286,12 +286,13 @@ TEST_CASE("Reading OSM XML 121") {
}
SECTION("Using Reader") {
- REQUIRE_THROWS_AS({
+ // can throw osmium::gzip_error or osmium::xml_error
+ REQUIRE_THROWS({
osmium::io::Reader reader(filename("121-truncated_gzip_file", "osm.gz"));
osmium::io::Header header = reader.header();
osmium::memory::Buffer buffer = reader.read();
reader.close();
- }, osmium::gzip_error);
+ });
}
}
@@ -339,6 +340,8 @@ TEST_CASE("Reading OSM XML 140") {
REQUIRE(!strcmp(uc, t["unicode_xml"]));
+// workaround for missing support for u8 string literals on Windows
+#if !defined(_MSC_VER)
switch (count) {
case 1:
REQUIRE(!strcmp(uc, u8"a"));
@@ -358,6 +361,7 @@ TEST_CASE("Reading OSM XML 140") {
default:
REQUIRE(false); // should not be here
}
+#endif
}
REQUIRE(count == 5);
}
diff --git a/test/t/area/test_area_id.cpp b/test/t/area/test_area_id.cpp
index 45bf87c..fbd8d78 100644
--- a/test/t/area/test_area_id.cpp
+++ b/test/t/area/test_area_id.cpp
@@ -4,22 +4,22 @@
TEST_CASE("area_id") {
-SECTION("object_id_to_area_id_conversion") {
- REQUIRE( 46 == osmium::object_id_to_area_id( 23, osmium::item_type::way));
- REQUIRE( 47 == osmium::object_id_to_area_id( 23, osmium::item_type::relation));
- REQUIRE( 0 == osmium::object_id_to_area_id( 0, osmium::item_type::way));
- REQUIRE( 1 == osmium::object_id_to_area_id( 0, osmium::item_type::relation));
- REQUIRE(-24 == osmium::object_id_to_area_id(-12, osmium::item_type::way));
- REQUIRE(-25 == osmium::object_id_to_area_id(-12, osmium::item_type::relation));
-}
+ SECTION("object_id_to_area_id_conversion") {
+ REQUIRE( 46 == osmium::object_id_to_area_id( 23, osmium::item_type::way));
+ REQUIRE( 47 == osmium::object_id_to_area_id( 23, osmium::item_type::relation));
+ REQUIRE( 0 == osmium::object_id_to_area_id( 0, osmium::item_type::way));
+ REQUIRE( 1 == osmium::object_id_to_area_id( 0, osmium::item_type::relation));
+ REQUIRE(-24 == osmium::object_id_to_area_id(-12, osmium::item_type::way));
+ REQUIRE(-25 == osmium::object_id_to_area_id(-12, osmium::item_type::relation));
+ }
-SECTION("area_id_to_object_id_conversion") {
- REQUIRE( 23 == osmium::area_id_to_object_id( 46));
- REQUIRE( 23 == osmium::area_id_to_object_id( 47));
- REQUIRE( 0 == osmium::area_id_to_object_id( 0));
- REQUIRE( 0 == osmium::area_id_to_object_id( 1));
- REQUIRE(-12 == osmium::area_id_to_object_id(-24));
- REQUIRE(-12 == osmium::area_id_to_object_id(-25));
-}
+ SECTION("area_id_to_object_id_conversion") {
+ REQUIRE( 23 == osmium::area_id_to_object_id( 46));
+ REQUIRE( 23 == osmium::area_id_to_object_id( 47));
+ REQUIRE( 0 == osmium::area_id_to_object_id( 0));
+ REQUIRE( 0 == osmium::area_id_to_object_id( 1));
+ REQUIRE(-12 == osmium::area_id_to_object_id(-24));
+ REQUIRE(-12 == osmium::area_id_to_object_id(-25));
+ }
}
diff --git a/test/t/area/test_node_ref_segment.cpp b/test/t/area/test_node_ref_segment.cpp
index fd67e6c..3097687 100644
--- a/test/t/area/test_node_ref_segment.cpp
+++ b/test/t/area/test_node_ref_segment.cpp
@@ -6,110 +6,110 @@ using osmium::area::detail::NodeRefSegment;
TEST_CASE("NodeRefSegmentClass") {
-SECTION("instantiation_with_default_parameters") {
- NodeRefSegment s;
- REQUIRE(s.first().ref() == 0);
- REQUIRE(s.first().location() == osmium::Location());
- REQUIRE(s.second().ref() == 0);
- REQUIRE(s.second().location() == osmium::Location());
-}
-
-SECTION("instantiation") {
- osmium::NodeRef nr1(1, { 1.2, 3.4 });
- osmium::NodeRef nr2(2, { 1.4, 3.1 });
- osmium::NodeRef nr3(3, { 1.2, 3.6 });
- osmium::NodeRef nr4(4, { 1.2, 3.7 });
-
- NodeRefSegment s1(nr1, nr2, nullptr, nullptr);
- REQUIRE(s1.first().ref() == 1);
- REQUIRE(s1.second().ref() == 2);
-
- NodeRefSegment s2(nr2, nr3, nullptr, nullptr);
- REQUIRE(s2.first().ref() == 3);
- REQUIRE(s2.second().ref() == 2);
-
- NodeRefSegment s3(nr3, nr4, nullptr, nullptr);
- REQUIRE(s3.first().ref() == 3);
- REQUIRE(s3.second().ref() == 4);
-}
-
-SECTION("intersection") {
- NodeRefSegment s1({ 1, {0.0, 0.0}}, { 2, {2.0, 2.0}}, nullptr, nullptr);
- NodeRefSegment s2({ 3, {0.0, 2.0}}, { 4, {2.0, 0.0}}, nullptr, nullptr);
- NodeRefSegment s3({ 5, {2.0, 0.0}}, { 6, {4.0, 2.0}}, nullptr, nullptr);
- NodeRefSegment s4({ 7, {1.0, 0.0}}, { 8, {3.0, 2.0}}, nullptr, nullptr);
- NodeRefSegment s5({ 9, {0.0, 4.0}}, {10, {4.0, 0.0}}, nullptr, nullptr);
- NodeRefSegment s6({11, {0.0, 0.0}}, {12, {1.0, 1.0}}, nullptr, nullptr);
- NodeRefSegment s7({13, {1.0, 1.0}}, {14, {3.0, 3.0}}, nullptr, nullptr);
-
- REQUIRE(calculate_intersection(s1, s2) == osmium::Location(1.0, 1.0));
- REQUIRE(calculate_intersection(s1, s3) == osmium::Location());
- REQUIRE(calculate_intersection(s2, s3) == osmium::Location());
- REQUIRE(calculate_intersection(s1, s4) == osmium::Location());
- REQUIRE(calculate_intersection(s1, s5) == osmium::Location(2.0, 2.0));
- REQUIRE(calculate_intersection(s1, s1) == osmium::Location());
- REQUIRE(calculate_intersection(s1, s6) == osmium::Location());
- REQUIRE(calculate_intersection(s1, s7) == osmium::Location());
-}
-
-SECTION("to_left_of") {
- osmium::Location loc { 2.0, 2.0 };
-
- REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {0.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {4.0, 0.0}}, {1, {4.0, 4.0}}, nullptr, nullptr).to_left_of(loc) == false);
- REQUIRE(NodeRefSegment({0, {1.0, 0.0}}, {1, {1.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
-
- REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {1.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {2.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {3.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {4.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {4.0, 3.0}}, nullptr, nullptr).to_left_of(loc) == false);
-
- REQUIRE(NodeRefSegment({0, {1.0, 3.0}}, {1, {2.0, 0.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {1.0, 3.0}}, {1, {3.0, 1.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {1.0, 3.0}}, {1, {3.0, 2.0}}, nullptr, nullptr).to_left_of(loc) == false);
-
- REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {2.0, 2.0}}, nullptr, nullptr).to_left_of(loc) == false);
-
- REQUIRE(NodeRefSegment({0, {2.0, 0.0}}, {1, {2.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {2.0, 0.0}}, {1, {2.0, 2.0}}, nullptr, nullptr).to_left_of(loc) == false);
- REQUIRE(NodeRefSegment({0, {2.0, 2.0}}, {1, {2.0, 4.0}}, nullptr, nullptr).to_left_of(loc) == false);
-
- REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {0.0, 1.0}}, nullptr, nullptr).to_left_of(loc) == false);
- REQUIRE(NodeRefSegment({0, {1.0, 0.0}}, {1, {0.0, 1.0}}, nullptr, nullptr).to_left_of(loc) == false);
-
- REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {1.0, 3.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {2.0, 0.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {3.0, 4.0}}, nullptr, nullptr).to_left_of(loc) == false);
-
- REQUIRE(NodeRefSegment({0, {1.0, 0.0}}, {1, {1.0, 2.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {1.0, 2.0}}, nullptr, nullptr).to_left_of(loc) == false);
- REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {1.0, 4.0}}, nullptr, nullptr).to_left_of(loc) == false);
-
- REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {0.0, 2.0}}, nullptr, nullptr).to_left_of(loc));
- REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {4.0, 4.0}}, nullptr, nullptr).to_left_of(loc) == false);
-
- REQUIRE(NodeRefSegment({0, {0.0, 1.0}}, {1, {2.0, 2.0}}, nullptr, nullptr).to_left_of(loc) == false);
- REQUIRE(NodeRefSegment({0, {2.0, 2.0}}, {1, {4.0, 0.0}}, nullptr, nullptr).to_left_of(loc) == false);
-}
-
-SECTION("ordering") {
- osmium::NodeRef node_ref1(1, { 1.0, 3.0 });
- osmium::NodeRef node_ref2(2, { 1.4, 2.9 });
- osmium::NodeRef node_ref3(3, { 1.2, 3.0 });
- osmium::NodeRef node_ref4(4, { 1.2, 3.3 });
-
- REQUIRE(node_ref1 < node_ref2);
- REQUIRE(node_ref2 < node_ref3);
- REQUIRE(node_ref1 < node_ref3);
- REQUIRE(node_ref1 >= node_ref1);
-
- REQUIRE( osmium::location_less()(node_ref1, node_ref2));
- REQUIRE(!osmium::location_less()(node_ref2, node_ref3));
- REQUIRE( osmium::location_less()(node_ref1, node_ref3));
- REQUIRE( osmium::location_less()(node_ref3, node_ref4));
- REQUIRE(!osmium::location_less()(node_ref1, node_ref1));
-}
+ SECTION("instantiation_with_default_parameters") {
+ NodeRefSegment s;
+ REQUIRE(s.first().ref() == 0);
+ REQUIRE(s.first().location() == osmium::Location());
+ REQUIRE(s.second().ref() == 0);
+ REQUIRE(s.second().location() == osmium::Location());
+ }
+
+ SECTION("instantiation") {
+ osmium::NodeRef nr1(1, { 1.2, 3.4 });
+ osmium::NodeRef nr2(2, { 1.4, 3.1 });
+ osmium::NodeRef nr3(3, { 1.2, 3.6 });
+ osmium::NodeRef nr4(4, { 1.2, 3.7 });
+
+ NodeRefSegment s1(nr1, nr2, nullptr, nullptr);
+ REQUIRE(s1.first().ref() == 1);
+ REQUIRE(s1.second().ref() == 2);
+
+ NodeRefSegment s2(nr2, nr3, nullptr, nullptr);
+ REQUIRE(s2.first().ref() == 3);
+ REQUIRE(s2.second().ref() == 2);
+
+ NodeRefSegment s3(nr3, nr4, nullptr, nullptr);
+ REQUIRE(s3.first().ref() == 3);
+ REQUIRE(s3.second().ref() == 4);
+ }
+
+ SECTION("intersection") {
+ NodeRefSegment s1({ 1, {0.0, 0.0}}, { 2, {2.0, 2.0}}, nullptr, nullptr);
+ NodeRefSegment s2({ 3, {0.0, 2.0}}, { 4, {2.0, 0.0}}, nullptr, nullptr);
+ NodeRefSegment s3({ 5, {2.0, 0.0}}, { 6, {4.0, 2.0}}, nullptr, nullptr);
+ NodeRefSegment s4({ 7, {1.0, 0.0}}, { 8, {3.0, 2.0}}, nullptr, nullptr);
+ NodeRefSegment s5({ 9, {0.0, 4.0}}, {10, {4.0, 0.0}}, nullptr, nullptr);
+ NodeRefSegment s6({11, {0.0, 0.0}}, {12, {1.0, 1.0}}, nullptr, nullptr);
+ NodeRefSegment s7({13, {1.0, 1.0}}, {14, {3.0, 3.0}}, nullptr, nullptr);
+
+ REQUIRE(calculate_intersection(s1, s2) == osmium::Location(1.0, 1.0));
+ REQUIRE(calculate_intersection(s1, s3) == osmium::Location());
+ REQUIRE(calculate_intersection(s2, s3) == osmium::Location());
+ REQUIRE(calculate_intersection(s1, s4) == osmium::Location());
+ REQUIRE(calculate_intersection(s1, s5) == osmium::Location(2.0, 2.0));
+ REQUIRE(calculate_intersection(s1, s1) == osmium::Location());
+ REQUIRE(calculate_intersection(s1, s6) == osmium::Location());
+ REQUIRE(calculate_intersection(s1, s7) == osmium::Location());
+ }
+
+ SECTION("to_left_of") {
+ osmium::Location loc { 2.0, 2.0 };
+
+ REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {0.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {4.0, 0.0}}, {1, {4.0, 4.0}}, nullptr, nullptr).to_left_of(loc) == false);
+ REQUIRE(NodeRefSegment({0, {1.0, 0.0}}, {1, {1.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
+
+ REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {1.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {2.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {3.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {4.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {4.0, 3.0}}, nullptr, nullptr).to_left_of(loc) == false);
+
+ REQUIRE(NodeRefSegment({0, {1.0, 3.0}}, {1, {2.0, 0.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {1.0, 3.0}}, {1, {3.0, 1.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {1.0, 3.0}}, {1, {3.0, 2.0}}, nullptr, nullptr).to_left_of(loc) == false);
+
+ REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {2.0, 2.0}}, nullptr, nullptr).to_left_of(loc) == false);
+
+ REQUIRE(NodeRefSegment({0, {2.0, 0.0}}, {1, {2.0, 4.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {2.0, 0.0}}, {1, {2.0, 2.0}}, nullptr, nullptr).to_left_of(loc) == false);
+ REQUIRE(NodeRefSegment({0, {2.0, 2.0}}, {1, {2.0, 4.0}}, nullptr, nullptr).to_left_of(loc) == false);
+
+ REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {0.0, 1.0}}, nullptr, nullptr).to_left_of(loc) == false);
+ REQUIRE(NodeRefSegment({0, {1.0, 0.0}}, {1, {0.0, 1.0}}, nullptr, nullptr).to_left_of(loc) == false);
+
+ REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {1.0, 3.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {2.0, 0.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {3.0, 4.0}}, nullptr, nullptr).to_left_of(loc) == false);
+
+ REQUIRE(NodeRefSegment({0, {1.0, 0.0}}, {1, {1.0, 2.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {1.0, 2.0}}, nullptr, nullptr).to_left_of(loc) == false);
+ REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {1.0, 4.0}}, nullptr, nullptr).to_left_of(loc) == false);
+
+ REQUIRE(NodeRefSegment({0, {0.0, 0.0}}, {1, {0.0, 2.0}}, nullptr, nullptr).to_left_of(loc));
+ REQUIRE(NodeRefSegment({0, {0.0, 2.0}}, {1, {4.0, 4.0}}, nullptr, nullptr).to_left_of(loc) == false);
+
+ REQUIRE(NodeRefSegment({0, {0.0, 1.0}}, {1, {2.0, 2.0}}, nullptr, nullptr).to_left_of(loc) == false);
+ REQUIRE(NodeRefSegment({0, {2.0, 2.0}}, {1, {4.0, 0.0}}, nullptr, nullptr).to_left_of(loc) == false);
+ }
+
+ SECTION("ordering") {
+ osmium::NodeRef node_ref1(1, { 1.0, 3.0 });
+ osmium::NodeRef node_ref2(2, { 1.4, 2.9 });
+ osmium::NodeRef node_ref3(3, { 1.2, 3.0 });
+ osmium::NodeRef node_ref4(4, { 1.2, 3.3 });
+
+ REQUIRE(node_ref1 < node_ref2);
+ REQUIRE(node_ref2 < node_ref3);
+ REQUIRE(node_ref1 < node_ref3);
+ REQUIRE(node_ref1 >= node_ref1);
+
+ REQUIRE( osmium::location_less()(node_ref1, node_ref2));
+ REQUIRE(!osmium::location_less()(node_ref2, node_ref3));
+ REQUIRE( osmium::location_less()(node_ref1, node_ref3));
+ REQUIRE( osmium::location_less()(node_ref3, node_ref4));
+ REQUIRE(!osmium::location_less()(node_ref1, node_ref1));
+ }
}
diff --git a/test/t/basic/test_box.cpp b/test/t/basic/test_box.cpp
index 6ebf95c..8182fbf 100644
--- a/test/t/basic/test_box.cpp
+++ b/test/t/basic/test_box.cpp
@@ -7,85 +7,85 @@
TEST_CASE("Box") {
-SECTION("instantiation") {
- osmium::Box b;
- REQUIRE(!b);
- REQUIRE(!b.bottom_left());
- REQUIRE(!b.top_right());
- REQUIRE_THROWS_AS(b.size(), osmium::invalid_location);
-}
-
-SECTION("instantiation_and_extend_with_undefined") {
- osmium::Box b;
- REQUIRE(!b);
- b.extend(osmium::Location());
- REQUIRE(!b.bottom_left());
- REQUIRE(!b.top_right());
-}
-
-SECTION("instantiation_and_extend") {
- osmium::Box b;
- osmium::Location loc1 { 1.2, 3.4 };
- b.extend(loc1);
- REQUIRE(!!b);
- REQUIRE(!!b.bottom_left());
- REQUIRE(!!b.top_right());
- REQUIRE(b.contains(loc1));
-
- osmium::Location loc2 { 3.4, 4.5 };
- osmium::Location loc3 { 5.6, 7.8 };
-
- b.extend(loc2);
- b.extend(loc3);
- REQUIRE(b.bottom_left() == osmium::Location(1.2, 3.4));
- REQUIRE(b.top_right() == osmium::Location(5.6, 7.8));
-
- // extend with undefined doesn't change anything
- b.extend(osmium::Location());
- REQUIRE(b.bottom_left() == osmium::Location(1.2, 3.4));
- REQUIRE(b.top_right() == osmium::Location(5.6, 7.8));
-
- REQUIRE(b.contains(loc1));
- REQUIRE(b.contains(loc2));
- REQUIRE(b.contains(loc3));
-}
-
-SECTION("output_defined") {
- osmium::Box b;
- b.extend(osmium::Location(1.2, 3.4));
- b.extend(osmium::Location(5.6, 7.8));
- std::stringstream out;
- out << b;
- REQUIRE(out.str() == "(1.2,3.4,5.6,7.8)");
- REQUIRE(b.size() == Approx(19.36).epsilon(0.000001));
-}
-
-SECTION("output_undefined") {
- osmium::Box b;
- std::stringstream out;
- out << b;
- REQUIRE(out.str() == "(undefined)");
-}
-
-SECTION("box_inside_box") {
- osmium::Box outer;
- outer.extend(osmium::Location(1, 1));
- outer.extend(osmium::Location(10, 10));
-
- osmium::Box inner;
- inner.extend(osmium::Location(2, 2));
- inner.extend(osmium::Location(4, 4));
-
- osmium::Box overlap;
- overlap.extend(osmium::Location(3, 3));
- overlap.extend(osmium::Location(5, 5));
-
- REQUIRE( osmium::geom::contains(inner, outer));
- REQUIRE(!osmium::geom::contains(outer, inner));
-
- REQUIRE(!osmium::geom::contains(overlap, inner));
- REQUIRE(!osmium::geom::contains(inner, overlap));
-}
+ SECTION("instantiation") {
+ osmium::Box b;
+ REQUIRE(!b);
+ REQUIRE(!b.bottom_left());
+ REQUIRE(!b.top_right());
+ REQUIRE_THROWS_AS(b.size(), osmium::invalid_location);
+ }
+
+ SECTION("instantiation_and_extend_with_undefined") {
+ osmium::Box b;
+ REQUIRE(!b);
+ b.extend(osmium::Location());
+ REQUIRE(!b.bottom_left());
+ REQUIRE(!b.top_right());
+ }
+
+ SECTION("instantiation_and_extend") {
+ osmium::Box b;
+ osmium::Location loc1 { 1.2, 3.4 };
+ b.extend(loc1);
+ REQUIRE(!!b);
+ REQUIRE(!!b.bottom_left());
+ REQUIRE(!!b.top_right());
+ REQUIRE(b.contains(loc1));
+
+ osmium::Location loc2 { 3.4, 4.5 };
+ osmium::Location loc3 { 5.6, 7.8 };
+
+ b.extend(loc2);
+ b.extend(loc3);
+ REQUIRE(b.bottom_left() == osmium::Location(1.2, 3.4));
+ REQUIRE(b.top_right() == osmium::Location(5.6, 7.8));
+
+ // extend with undefined doesn't change anything
+ b.extend(osmium::Location());
+ REQUIRE(b.bottom_left() == osmium::Location(1.2, 3.4));
+ REQUIRE(b.top_right() == osmium::Location(5.6, 7.8));
+
+ REQUIRE(b.contains(loc1));
+ REQUIRE(b.contains(loc2));
+ REQUIRE(b.contains(loc3));
+ }
+
+ SECTION("output_defined") {
+ osmium::Box b;
+ b.extend(osmium::Location(1.2, 3.4));
+ b.extend(osmium::Location(5.6, 7.8));
+ std::stringstream out;
+ out << b;
+ REQUIRE(out.str() == "(1.2,3.4,5.6,7.8)");
+ REQUIRE(b.size() == Approx(19.36).epsilon(0.000001));
+ }
+
+ SECTION("output_undefined") {
+ osmium::Box b;
+ std::stringstream out;
+ out << b;
+ REQUIRE(out.str() == "(undefined)");
+ }
+
+ SECTION("box_inside_box") {
+ osmium::Box outer;
+ outer.extend(osmium::Location(1, 1));
+ outer.extend(osmium::Location(10, 10));
+
+ osmium::Box inner;
+ inner.extend(osmium::Location(2, 2));
+ inner.extend(osmium::Location(4, 4));
+
+ osmium::Box overlap;
+ overlap.extend(osmium::Location(3, 3));
+ overlap.extend(osmium::Location(5, 5));
+
+ REQUIRE( osmium::geom::contains(inner, outer));
+ REQUIRE(!osmium::geom::contains(outer, inner));
+
+ REQUIRE(!osmium::geom::contains(overlap, inner));
+ REQUIRE(!osmium::geom::contains(inner, overlap));
+ }
}
diff --git a/test/t/basic/test_entity_bits.cpp b/test/t/basic/test_entity_bits.cpp
index a200f48..f15068b 100644
--- a/test/t/basic/test_entity_bits.cpp
+++ b/test/t/basic/test_entity_bits.cpp
@@ -4,28 +4,28 @@
TEST_CASE("entity_bits") {
-SECTION("can_be_set_and_checked") {
- osmium::osm_entity_bits::type entities = osmium::osm_entity_bits::node | osmium::osm_entity_bits::way;
- REQUIRE(entities == (osmium::osm_entity_bits::node | osmium::osm_entity_bits::way));
+ SECTION("can_be_set_and_checked") {
+ osmium::osm_entity_bits::type entities = osmium::osm_entity_bits::node | osmium::osm_entity_bits::way;
+ REQUIRE(entities == (osmium::osm_entity_bits::node | osmium::osm_entity_bits::way));
- entities |= osmium::osm_entity_bits::relation;
- REQUIRE((entities & osmium::osm_entity_bits::object));
+ entities |= osmium::osm_entity_bits::relation;
+ REQUIRE((entities & osmium::osm_entity_bits::object));
- entities |= osmium::osm_entity_bits::area;
- REQUIRE(entities == osmium::osm_entity_bits::object);
+ entities |= osmium::osm_entity_bits::area;
+ REQUIRE(entities == osmium::osm_entity_bits::object);
- REQUIRE(! (entities & osmium::osm_entity_bits::changeset));
+ REQUIRE(! (entities & osmium::osm_entity_bits::changeset));
- entities &= osmium::osm_entity_bits::node;
- REQUIRE((entities & osmium::osm_entity_bits::node));
- REQUIRE(! (entities & osmium::osm_entity_bits::way));
- REQUIRE(entities == osmium::osm_entity_bits::node);
+ entities &= osmium::osm_entity_bits::node;
+ REQUIRE((entities & osmium::osm_entity_bits::node));
+ REQUIRE(! (entities & osmium::osm_entity_bits::way));
+ REQUIRE(entities == osmium::osm_entity_bits::node);
- REQUIRE(osmium::osm_entity_bits::node == osmium::osm_entity_bits::from_item_type(osmium::item_type::node));
- REQUIRE(osmium::osm_entity_bits::way == osmium::osm_entity_bits::from_item_type(osmium::item_type::way));
- REQUIRE(osmium::osm_entity_bits::relation == osmium::osm_entity_bits::from_item_type(osmium::item_type::relation));
- REQUIRE(osmium::osm_entity_bits::changeset == osmium::osm_entity_bits::from_item_type(osmium::item_type::changeset));
- REQUIRE(osmium::osm_entity_bits::area == osmium::osm_entity_bits::from_item_type(osmium::item_type::area));
-}
+ REQUIRE(osmium::osm_entity_bits::node == osmium::osm_entity_bits::from_item_type(osmium::item_type::node));
+ REQUIRE(osmium::osm_entity_bits::way == osmium::osm_entity_bits::from_item_type(osmium::item_type::way));
+ REQUIRE(osmium::osm_entity_bits::relation == osmium::osm_entity_bits::from_item_type(osmium::item_type::relation));
+ REQUIRE(osmium::osm_entity_bits::changeset == osmium::osm_entity_bits::from_item_type(osmium::item_type::changeset));
+ REQUIRE(osmium::osm_entity_bits::area == osmium::osm_entity_bits::from_item_type(osmium::item_type::area));
+ }
}
diff --git a/test/t/basic/test_location.cpp b/test/t/basic/test_location.cpp
index 25545a4..3fd8d15 100644
--- a/test/t/basic/test_location.cpp
+++ b/test/t/basic/test_location.cpp
@@ -10,145 +10,145 @@ TEST_CASE("Location") {
// fails on MSVC and doesn't really matter
// static_assert(std::is_literal_type<osmium::Location>::value, "osmium::Location not literal type");
-SECTION("instantiation_with_default_parameters") {
- osmium::Location loc;
- REQUIRE(!loc);
- REQUIRE_THROWS_AS(loc.lon(), osmium::invalid_location);
- REQUIRE_THROWS_AS(loc.lat(), osmium::invalid_location);
-}
-
-SECTION("instantiation_with_double_parameters") {
- osmium::Location loc1(1.2, 4.5);
- REQUIRE(!!loc1);
- REQUIRE(12000000 == loc1.x());
- REQUIRE(45000000 == loc1.y());
- REQUIRE(1.2 == loc1.lon());
- REQUIRE(4.5 == loc1.lat());
-
- osmium::Location loc2(loc1);
- REQUIRE(4.5 == loc2.lat());
-
- osmium::Location loc3 = loc1;
- REQUIRE(4.5 == loc3.lat());
-}
-
-SECTION("instantiation_with_double_parameters_constructor_with_universal_initializer") {
- osmium::Location loc { 2.2, 3.3 };
- REQUIRE(2.2 == loc.lon());
- REQUIRE(3.3 == loc.lat());
-}
-
-SECTION("instantiation_with_double_parameters_constructor_with_initializer_list") {
- osmium::Location loc({ 4.4, 5.5 });
- REQUIRE(4.4 == loc.lon());
- REQUIRE(5.5 == loc.lat());
-}
-
-SECTION("instantiation_with_double_parameters_operator_equal") {
- osmium::Location loc = { 5.5, 6.6 };
- REQUIRE(5.5 == loc.lon());
- REQUIRE(6.6 == loc.lat());
-}
-
-SECTION("equality") {
- osmium::Location loc1(1.2, 4.5);
- osmium::Location loc2(1.2, 4.5);
- osmium::Location loc3(1.5, 1.5);
- REQUIRE(loc1 == loc2);
- REQUIRE(loc1 != loc3);
-}
-
-SECTION("order") {
- REQUIRE(osmium::Location(-1.2, 10.0) < osmium::Location(1.2, 10.0));
- REQUIRE(osmium::Location(1.2, 10.0) > osmium::Location(-1.2, 10.0));
-
- REQUIRE(osmium::Location(10.2, 20.0) < osmium::Location(11.2, 20.2));
- REQUIRE(osmium::Location(10.2, 20.2) < osmium::Location(11.2, 20.0));
- REQUIRE(osmium::Location(11.2, 20.2) > osmium::Location(10.2, 20.0));
-}
-
-SECTION("validity") {
- REQUIRE(osmium::Location(0.0, 0.0).valid());
- REQUIRE(osmium::Location(1.2, 4.5).valid());
- REQUIRE(osmium::Location(-1.2, 4.5).valid());
- REQUIRE(osmium::Location(-180.0, -90.0).valid());
- REQUIRE(osmium::Location(180.0, -90.0).valid());
- REQUIRE(osmium::Location(-180.0, 90.0).valid());
- REQUIRE(osmium::Location(180.0, 90.0).valid());
-
- REQUIRE(!osmium::Location(200.0, 4.5).valid());
- REQUIRE(!osmium::Location(-1.2, -100.0).valid());
- REQUIRE(!osmium::Location(-180.0, 90.005).valid());
-}
-
-
-SECTION("output_to_iterator_comma_separator") {
- char buffer[100];
- osmium::Location loc(-3.2, 47.3);
- *loc.as_string(buffer, ',') = 0;
- REQUIRE(std::string("-3.2,47.3") == buffer);
-}
-
-SECTION("output_to_iterator_space_separator") {
- char buffer[100];
- osmium::Location loc(0.0, 7.0);
- *loc.as_string(buffer, ' ') = 0;
- REQUIRE(std::string("0 7") == buffer);
-}
-
-SECTION("output_to_iterator_check_precision") {
- char buffer[100];
- osmium::Location loc(-179.9999999, -90.0);
- *loc.as_string(buffer, ' ') = 0;
- REQUIRE(std::string("-179.9999999 -90") == buffer);
-}
-
-SECTION("output_to_iterator_undefined_location") {
- char buffer[100];
- osmium::Location loc;
- REQUIRE_THROWS_AS(loc.as_string(buffer, ','), osmium::invalid_location);
-}
-
-SECTION("output_to_string_comman_separator") {
- std::string s;
- osmium::Location loc(-3.2, 47.3);
- loc.as_string(std::back_inserter(s), ',');
- REQUIRE(s == "-3.2,47.3");
-}
-
-SECTION("output_to_string_space_separator") {
- std::string s;
- osmium::Location loc(0.0, 7.0);
- loc.as_string(std::back_inserter(s), ' ');
- REQUIRE(s == "0 7");
-}
-
-SECTION("output_to_string_check_precision") {
- std::string s;
- osmium::Location loc(-179.9999999, -90.0);
- loc.as_string(std::back_inserter(s), ' ');
- REQUIRE(s == "-179.9999999 -90");
-}
-
-SECTION("output_to_string_undefined_location") {
- std::string s;
- osmium::Location loc;
- REQUIRE_THROWS_AS(loc.as_string(std::back_inserter(s), ','), osmium::invalid_location);
-}
-
-SECTION("output_defined") {
- osmium::Location p(-3.2, 47.3);
- std::stringstream out;
- out << p;
- REQUIRE(out.str() == "(-3.2,47.3)");
-}
-
-SECTION("output_undefined") {
- osmium::Location p;
- std::stringstream out;
- out << p;
- REQUIRE(out.str() == "(undefined,undefined)");
-}
+ SECTION("instantiation_with_default_parameters") {
+ osmium::Location loc;
+ REQUIRE(!loc);
+ REQUIRE_THROWS_AS(loc.lon(), osmium::invalid_location);
+ REQUIRE_THROWS_AS(loc.lat(), osmium::invalid_location);
+ }
+
+ SECTION("instantiation_with_double_parameters") {
+ osmium::Location loc1(1.2, 4.5);
+ REQUIRE(!!loc1);
+ REQUIRE(12000000 == loc1.x());
+ REQUIRE(45000000 == loc1.y());
+ REQUIRE(1.2 == loc1.lon());
+ REQUIRE(4.5 == loc1.lat());
+
+ osmium::Location loc2(loc1);
+ REQUIRE(4.5 == loc2.lat());
+
+ osmium::Location loc3 = loc1;
+ REQUIRE(4.5 == loc3.lat());
+ }
+
+ SECTION("instantiation_with_double_parameters_constructor_with_universal_initializer") {
+ osmium::Location loc { 2.2, 3.3 };
+ REQUIRE(2.2 == loc.lon());
+ REQUIRE(3.3 == loc.lat());
+ }
+
+ SECTION("instantiation_with_double_parameters_constructor_with_initializer_list") {
+ osmium::Location loc({ 4.4, 5.5 });
+ REQUIRE(4.4 == loc.lon());
+ REQUIRE(5.5 == loc.lat());
+ }
+
+ SECTION("instantiation_with_double_parameters_operator_equal") {
+ osmium::Location loc = { 5.5, 6.6 };
+ REQUIRE(5.5 == loc.lon());
+ REQUIRE(6.6 == loc.lat());
+ }
+
+ SECTION("equality") {
+ osmium::Location loc1(1.2, 4.5);
+ osmium::Location loc2(1.2, 4.5);
+ osmium::Location loc3(1.5, 1.5);
+ REQUIRE(loc1 == loc2);
+ REQUIRE(loc1 != loc3);
+ }
+
+ SECTION("order") {
+ REQUIRE(osmium::Location(-1.2, 10.0) < osmium::Location(1.2, 10.0));
+ REQUIRE(osmium::Location(1.2, 10.0) > osmium::Location(-1.2, 10.0));
+
+ REQUIRE(osmium::Location(10.2, 20.0) < osmium::Location(11.2, 20.2));
+ REQUIRE(osmium::Location(10.2, 20.2) < osmium::Location(11.2, 20.0));
+ REQUIRE(osmium::Location(11.2, 20.2) > osmium::Location(10.2, 20.0));
+ }
+
+ SECTION("validity") {
+ REQUIRE(osmium::Location(0.0, 0.0).valid());
+ REQUIRE(osmium::Location(1.2, 4.5).valid());
+ REQUIRE(osmium::Location(-1.2, 4.5).valid());
+ REQUIRE(osmium::Location(-180.0, -90.0).valid());
+ REQUIRE(osmium::Location(180.0, -90.0).valid());
+ REQUIRE(osmium::Location(-180.0, 90.0).valid());
+ REQUIRE(osmium::Location(180.0, 90.0).valid());
+
+ REQUIRE(!osmium::Location(200.0, 4.5).valid());
+ REQUIRE(!osmium::Location(-1.2, -100.0).valid());
+ REQUIRE(!osmium::Location(-180.0, 90.005).valid());
+ }
+
+
+ SECTION("output_to_iterator_comma_separator") {
+ char buffer[100];
+ osmium::Location loc(-3.2, 47.3);
+ *loc.as_string(buffer, ',') = 0;
+ REQUIRE(std::string("-3.2,47.3") == buffer);
+ }
+
+ SECTION("output_to_iterator_space_separator") {
+ char buffer[100];
+ osmium::Location loc(0.0, 7.0);
+ *loc.as_string(buffer, ' ') = 0;
+ REQUIRE(std::string("0 7") == buffer);
+ }
+
+ SECTION("output_to_iterator_check_precision") {
+ char buffer[100];
+ osmium::Location loc(-179.9999999, -90.0);
+ *loc.as_string(buffer, ' ') = 0;
+ REQUIRE(std::string("-179.9999999 -90") == buffer);
+ }
+
+ SECTION("output_to_iterator_undefined_location") {
+ char buffer[100];
+ osmium::Location loc;
+ REQUIRE_THROWS_AS(loc.as_string(buffer, ','), osmium::invalid_location);
+ }
+
+ SECTION("output_to_string_comman_separator") {
+ std::string s;
+ osmium::Location loc(-3.2, 47.3);
+ loc.as_string(std::back_inserter(s), ',');
+ REQUIRE(s == "-3.2,47.3");
+ }
+
+ SECTION("output_to_string_space_separator") {
+ std::string s;
+ osmium::Location loc(0.0, 7.0);
+ loc.as_string(std::back_inserter(s), ' ');
+ REQUIRE(s == "0 7");
+ }
+
+ SECTION("output_to_string_check_precision") {
+ std::string s;
+ osmium::Location loc(-179.9999999, -90.0);
+ loc.as_string(std::back_inserter(s), ' ');
+ REQUIRE(s == "-179.9999999 -90");
+ }
+
+ SECTION("output_to_string_undefined_location") {
+ std::string s;
+ osmium::Location loc;
+ REQUIRE_THROWS_AS(loc.as_string(std::back_inserter(s), ','), osmium::invalid_location);
+ }
+
+ SECTION("output_defined") {
+ osmium::Location p(-3.2, 47.3);
+ std::stringstream out;
+ out << p;
+ REQUIRE(out.str() == "(-3.2,47.3)");
+ }
+
+ SECTION("output_undefined") {
+ osmium::Location p;
+ std::stringstream out;
+ out << p;
+ REQUIRE(out.str() == "(undefined,undefined)");
+ }
}
diff --git a/test/t/basic/test_node_ref.cpp b/test/t/basic/test_node_ref.cpp
index 5c7b670..ac7ccbf 100644
--- a/test/t/basic/test_node_ref.cpp
+++ b/test/t/basic/test_node_ref.cpp
@@ -4,54 +4,54 @@
TEST_CASE("NodeRef") {
-SECTION("instantiation_with_default_parameters") {
- osmium::NodeRef node_ref;
- REQUIRE(node_ref.ref() == 0);
+ SECTION("instantiation_with_default_parameters") {
+ osmium::NodeRef node_ref;
+ REQUIRE(node_ref.ref() == 0);
// REQUIRE(!node_ref.has_location());
-}
-
-SECTION("instantiation_with_id") {
- osmium::NodeRef node_ref(7);
- REQUIRE(node_ref.ref() == 7);
-}
-
-SECTION("equality") {
- osmium::NodeRef node_ref1(7, { 1.2, 3.4 });
- osmium::NodeRef node_ref2(7, { 1.4, 3.1 });
- osmium::NodeRef node_ref3(9, { 1.2, 3.4 });
- REQUIRE(node_ref1 == node_ref2);
- REQUIRE(node_ref1 != node_ref3);
- REQUIRE(!osmium::location_equal()(node_ref1, node_ref2));
- REQUIRE(!osmium::location_equal()(node_ref2, node_ref3));
- REQUIRE(osmium::location_equal()(node_ref1, node_ref3));
-}
-
-SECTION("set_location") {
- osmium::NodeRef node_ref(7);
- REQUIRE(!node_ref.location().valid());
- REQUIRE(node_ref.location() == osmium::Location());
- node_ref.set_location(osmium::Location(13.5, -7.2));
- REQUIRE(node_ref.location().lon() == 13.5);
- REQUIRE(node_ref.location().valid());
-}
-
-SECTION("ordering") {
- osmium::NodeRef node_ref1(1, { 1.0, 3.0 });
- osmium::NodeRef node_ref2(2, { 1.4, 2.9 });
- osmium::NodeRef node_ref3(3, { 1.2, 3.0 });
- osmium::NodeRef node_ref4(4, { 1.2, 3.3 });
-
- REQUIRE(node_ref1 < node_ref2);
- REQUIRE(node_ref2 < node_ref3);
- REQUIRE(node_ref1 < node_ref3);
- REQUIRE(node_ref1 >= node_ref1);
-
- REQUIRE(osmium::location_less()(node_ref1, node_ref2));
- REQUIRE(!osmium::location_less()(node_ref2, node_ref3));
- REQUIRE(osmium::location_less()(node_ref1, node_ref3));
- REQUIRE(osmium::location_less()(node_ref3, node_ref4));
- REQUIRE(!osmium::location_less()(node_ref1, node_ref1));
-}
+ }
+
+ SECTION("instantiation_with_id") {
+ osmium::NodeRef node_ref(7);
+ REQUIRE(node_ref.ref() == 7);
+ }
+
+ SECTION("equality") {
+ osmium::NodeRef node_ref1(7, { 1.2, 3.4 });
+ osmium::NodeRef node_ref2(7, { 1.4, 3.1 });
+ osmium::NodeRef node_ref3(9, { 1.2, 3.4 });
+ REQUIRE(node_ref1 == node_ref2);
+ REQUIRE(node_ref1 != node_ref3);
+ REQUIRE(!osmium::location_equal()(node_ref1, node_ref2));
+ REQUIRE(!osmium::location_equal()(node_ref2, node_ref3));
+ REQUIRE(osmium::location_equal()(node_ref1, node_ref3));
+ }
+
+ SECTION("set_location") {
+ osmium::NodeRef node_ref(7);
+ REQUIRE(!node_ref.location().valid());
+ REQUIRE(node_ref.location() == osmium::Location());
+ node_ref.set_location(osmium::Location(13.5, -7.2));
+ REQUIRE(node_ref.location().lon() == 13.5);
+ REQUIRE(node_ref.location().valid());
+ }
+
+ SECTION("ordering") {
+ osmium::NodeRef node_ref1(1, { 1.0, 3.0 });
+ osmium::NodeRef node_ref2(2, { 1.4, 2.9 });
+ osmium::NodeRef node_ref3(3, { 1.2, 3.0 });
+ osmium::NodeRef node_ref4(4, { 1.2, 3.3 });
+
+ REQUIRE(node_ref1 < node_ref2);
+ REQUIRE(node_ref2 < node_ref3);
+ REQUIRE(node_ref1 < node_ref3);
+ REQUIRE(node_ref1 >= node_ref1);
+
+ REQUIRE(osmium::location_less()(node_ref1, node_ref2));
+ REQUIRE(!osmium::location_less()(node_ref2, node_ref3));
+ REQUIRE(osmium::location_less()(node_ref1, node_ref3));
+ REQUIRE(osmium::location_less()(node_ref3, node_ref4));
+ REQUIRE(!osmium::location_less()(node_ref1, node_ref1));
+ }
}
diff --git a/test/t/basic/test_object_comparisons.cpp b/test/t/basic/test_object_comparisons.cpp
index ffffbcc..2bfdcad 100644
--- a/test/t/basic/test_object_comparisons.cpp
+++ b/test/t/basic/test_object_comparisons.cpp
@@ -6,142 +6,142 @@
TEST_CASE("Object_Comparisons") {
-SECTION("order") {
- osmium::memory::Buffer buffer(10 * 1000);
-
- {
- // add node 1
- osmium::builder::NodeBuilder node_builder(buffer);
- node_builder.add_user("testuser");
- buffer.commit();
+ SECTION("order") {
+ osmium::memory::Buffer buffer(10 * 1000);
+
+ {
+ // add node 1
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser");
+ buffer.commit();
+ }
+
+ {
+ // add node 2
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser");
+ buffer.commit();
+ }
+
+ auto it = buffer.begin();
+ osmium::Node& node1 = static_cast<osmium::Node&>(*it);
+ osmium::Node& node2 = static_cast<osmium::Node&>(*(++it));
+
+ node1.set_id(10);
+ node1.set_version(1);
+ node2.set_id(15);
+ node2.set_version(2);
+ REQUIRE(true == (node1 < node2));
+ REQUIRE(false == (node1 > node2));
+ node1.set_id(20);
+ node1.set_version(1);
+ node2.set_id(20);
+ node2.set_version(2);
+ REQUIRE(true == (node1 < node2));
+ REQUIRE(false == (node1 > node2));
+ node1.set_id(-10);
+ node1.set_version(2);
+ node2.set_id(-15);
+ node2.set_version(1);
+ REQUIRE(true == (node1 < node2));
+ REQUIRE(false == (node1 > node2));
}
- {
- // add node 2
- osmium::builder::NodeBuilder node_builder(buffer);
- node_builder.add_user("testuser");
- buffer.commit();
+ SECTION("order_types") {
+ osmium::memory::Buffer buffer(10 * 1000);
+
+ {
+ // add node 1
+ osmium::builder::NodeBuilder node_builder(buffer);
+ osmium::Node& node = node_builder.object();
+ REQUIRE(osmium::item_type::node == node.type());
+
+ node.set_id(3);
+ node.set_version(3);
+ node_builder.add_user("testuser");
+
+ buffer.commit();
+ }
+
+ {
+ // add node 2
+ osmium::builder::NodeBuilder node_builder(buffer);
+ osmium::Node& node = node_builder.object();
+ REQUIRE(osmium::item_type::node == node.type());
+
+ node.set_id(3);
+ node.set_version(4);
+ node_builder.add_user("testuser");
+
+ buffer.commit();
+ }
+
+ {
+ // add node 3
+ osmium::builder::NodeBuilder node_builder(buffer);
+ osmium::Node& node = node_builder.object();
+ REQUIRE(osmium::item_type::node == node.type());
+
+ node.set_id(3);
+ node.set_version(4);
+ node_builder.add_user("testuser");
+
+ buffer.commit();
+ }
+
+ {
+ // add way
+ osmium::builder::WayBuilder way_builder(buffer);
+ osmium::Way& way = way_builder.object();
+ REQUIRE(osmium::item_type::way == way.type());
+
+ way.set_id(2);
+ way.set_version(2);
+ way_builder.add_user("testuser");
+
+ buffer.commit();
+ }
+
+ {
+ // add relation
+ osmium::builder::RelationBuilder relation_builder(buffer);
+ osmium::Relation& relation = relation_builder.object();
+ REQUIRE(osmium::item_type::relation == relation.type());
+
+ relation.set_id(1);
+ relation.set_version(1);
+ relation_builder.add_user("testuser");
+
+ buffer.commit();
+ }
+
+ auto it = buffer.begin();
+ const osmium::Node& node1 = static_cast<const osmium::Node&>(*it);
+ const osmium::Node& node2 = static_cast<const osmium::Node&>(*(++it));
+ const osmium::Node& node3 = static_cast<const osmium::Node&>(*(++it));
+ const osmium::Way& way = static_cast<const osmium::Way&>(*(++it));
+ const osmium::Relation& relation = static_cast<const osmium::Relation&>(*(++it));
+
+ REQUIRE(true == (node1 < node2));
+ REQUIRE(true == (node2 < way));
+ REQUIRE(false == (node2 > way));
+ REQUIRE(true == (way < relation));
+ REQUIRE(true == (node1 < relation));
+
+ REQUIRE(true == osmium::object_order_type_id_version()(node1, node2));
+ REQUIRE(true == osmium::object_order_type_id_reverse_version()(node2, node1));
+ REQUIRE(true == osmium::object_order_type_id_version()(node1, way));
+ REQUIRE(true == osmium::object_order_type_id_reverse_version()(node1, way));
+
+ REQUIRE(false == osmium::object_equal_type_id_version()(node1, node2));
+ REQUIRE(true == osmium::object_equal_type_id_version()(node2, node3));
+
+ REQUIRE(true == osmium::object_equal_type_id()(node1, node2));
+ REQUIRE(true == osmium::object_equal_type_id()(node2, node3));
+
+ REQUIRE(false == osmium::object_equal_type_id_version()(node1, way));
+ REQUIRE(false == osmium::object_equal_type_id_version()(node1, relation));
+ REQUIRE(false == osmium::object_equal_type_id()(node1, relation));
}
- auto it = buffer.begin();
- osmium::Node& node1 = static_cast<osmium::Node&>(*it);
- osmium::Node& node2 = static_cast<osmium::Node&>(*(++it));
-
- node1.set_id(10);
- node1.set_version(1);
- node2.set_id(15);
- node2.set_version(2);
- REQUIRE(true == (node1 < node2));
- REQUIRE(false == (node1 > node2));
- node1.set_id(20);
- node1.set_version(1);
- node2.set_id(20);
- node2.set_version(2);
- REQUIRE(true == (node1 < node2));
- REQUIRE(false == (node1 > node2));
- node1.set_id(-10);
- node1.set_version(2);
- node2.set_id(-15);
- node2.set_version(1);
- REQUIRE(true == (node1 < node2));
- REQUIRE(false == (node1 > node2));
-}
-
-SECTION("order_types") {
- osmium::memory::Buffer buffer(10 * 1000);
-
- {
- // add node 1
- osmium::builder::NodeBuilder node_builder(buffer);
- osmium::Node& node = node_builder.object();
- REQUIRE(osmium::item_type::node == node.type());
-
- node.set_id(3);
- node.set_version(3);
- node_builder.add_user("testuser");
-
- buffer.commit();
- }
-
- {
- // add node 2
- osmium::builder::NodeBuilder node_builder(buffer);
- osmium::Node& node = node_builder.object();
- REQUIRE(osmium::item_type::node == node.type());
-
- node.set_id(3);
- node.set_version(4);
- node_builder.add_user("testuser");
-
- buffer.commit();
- }
-
- {
- // add node 3
- osmium::builder::NodeBuilder node_builder(buffer);
- osmium::Node& node = node_builder.object();
- REQUIRE(osmium::item_type::node == node.type());
-
- node.set_id(3);
- node.set_version(4);
- node_builder.add_user("testuser");
-
- buffer.commit();
- }
-
- {
- // add way
- osmium::builder::WayBuilder way_builder(buffer);
- osmium::Way& way = way_builder.object();
- REQUIRE(osmium::item_type::way == way.type());
-
- way.set_id(2);
- way.set_version(2);
- way_builder.add_user("testuser");
-
- buffer.commit();
- }
-
- {
- // add relation
- osmium::builder::RelationBuilder relation_builder(buffer);
- osmium::Relation& relation = relation_builder.object();
- REQUIRE(osmium::item_type::relation == relation.type());
-
- relation.set_id(1);
- relation.set_version(1);
- relation_builder.add_user("testuser");
-
- buffer.commit();
- }
-
- auto it = buffer.begin();
- const osmium::Node& node1 = static_cast<const osmium::Node&>(*it);
- const osmium::Node& node2 = static_cast<const osmium::Node&>(*(++it));
- const osmium::Node& node3 = static_cast<const osmium::Node&>(*(++it));
- const osmium::Way& way = static_cast<const osmium::Way&>(*(++it));
- const osmium::Relation& relation = static_cast<const osmium::Relation&>(*(++it));
-
- REQUIRE(true == (node1 < node2));
- REQUIRE(true == (node2 < way));
- REQUIRE(false == (node2 > way));
- REQUIRE(true == (way < relation));
- REQUIRE(true == (node1 < relation));
-
- REQUIRE(true == osmium::object_order_type_id_version()(node1, node2));
- REQUIRE(true == osmium::object_order_type_id_reverse_version()(node2, node1));
- REQUIRE(true == osmium::object_order_type_id_version()(node1, way));
- REQUIRE(true == osmium::object_order_type_id_reverse_version()(node1, way));
-
- REQUIRE(false == osmium::object_equal_type_id_version()(node1, node2));
- REQUIRE(true == osmium::object_equal_type_id_version()(node2, node3));
-
- REQUIRE(true == osmium::object_equal_type_id()(node1, node2));
- REQUIRE(true == osmium::object_equal_type_id()(node2, node3));
-
- REQUIRE(false == osmium::object_equal_type_id_version()(node1, way));
- REQUIRE(false == osmium::object_equal_type_id_version()(node1, relation));
- REQUIRE(false == osmium::object_equal_type_id()(node1, relation));
-}
-
}
diff --git a/test/t/basic/test_timestamp.cpp b/test/t/basic/test_timestamp.cpp
index 453b94b..f015730 100644
--- a/test/t/basic/test_timestamp.cpp
+++ b/test/t/basic/test_timestamp.cpp
@@ -6,40 +6,57 @@
TEST_CASE("Timestamp") {
-SECTION("can be default initialized to invalid value") {
- osmium::Timestamp t;
- REQUIRE(0 == t);
- REQUIRE("" == t.to_iso());
-}
-
-SECTION("invalid value is zero") {
- osmium::Timestamp t(static_cast<time_t>(0));
- REQUIRE(0 == t);
- REQUIRE("" == t.to_iso());
-}
-
-SECTION("can be initialized from time_t") {
- osmium::Timestamp t(static_cast<time_t>(1));
- REQUIRE(1 == t);
- REQUIRE("1970-01-01T00:00:01Z" == t.to_iso());
-}
-
-SECTION("can be initialized from string") {
- osmium::Timestamp t("2000-01-01T00:00:00Z");
- REQUIRE("2000-01-01T00:00:00Z" == t.to_iso());
-}
-
-SECTION("can be compared") {
- osmium::Timestamp t1(10);
- osmium::Timestamp t2(50);
- REQUIRE(t1 < t2);
-}
-
-SECTION("can be written to stream") {
- std::stringstream ss;
- osmium::Timestamp t(1);
- ss << t;
- REQUIRE("1970-01-01T00:00:01Z" == ss.str());
-}
+ SECTION("can be default initialized to invalid value") {
+ osmium::Timestamp t;
+ REQUIRE(0 == t);
+ REQUIRE("" == t.to_iso());
+ }
+
+ SECTION("invalid value is zero") {
+ osmium::Timestamp t(static_cast<time_t>(0));
+ REQUIRE(0 == t);
+ REQUIRE("" == t.to_iso());
+ }
+
+ SECTION("can be initialized from time_t") {
+ osmium::Timestamp t(static_cast<time_t>(1));
+ REQUIRE(1 == t);
+ REQUIRE("1970-01-01T00:00:01Z" == t.to_iso());
+ }
+
+ SECTION("can be initialized from string") {
+ osmium::Timestamp t("2000-01-01T00:00:00Z");
+ REQUIRE("2000-01-01T00:00:00Z" == t.to_iso());
+ }
+
+ SECTION("throws if initialized from bad string") {
+ REQUIRE_THROWS_AS(osmium::Timestamp("x"), std::invalid_argument);
+ }
+
+ SECTION("can be implicitly cast to time_t") {
+ osmium::Timestamp t(4242);
+ time_t x = t;
+ REQUIRE(x == 4242);
+ }
+
+ SECTION("uint32_t can be initialized from Timestamp") {
+ osmium::Timestamp t(4242);
+ uint32_t x { t };
+
+ REQUIRE(x == 4242);
+ }
+
+ SECTION("can be compared") {
+ osmium::Timestamp t1(10);
+ osmium::Timestamp t2(50);
+ REQUIRE(t1 < t2);
+ }
+
+ SECTION("can be written to stream") {
+ std::stringstream ss;
+ osmium::Timestamp t(1);
+ ss << t;
+ REQUIRE("1970-01-01T00:00:01Z" == ss.str());
+ }
}
diff --git a/test/t/basic/test_types_from_string.cpp b/test/t/basic/test_types_from_string.cpp
new file mode 100644
index 0000000..2481ae8
--- /dev/null
+++ b/test/t/basic/test_types_from_string.cpp
@@ -0,0 +1,90 @@
+#include "catch.hpp"
+
+#include <osmium/osm/types.hpp>
+#include <osmium/osm/types_from_string.hpp>
+
+TEST_CASE("set ID from string") {
+ REQUIRE(osmium::string_to_object_id("0") == 0);
+ REQUIRE(osmium::string_to_object_id("17") == 17);
+ REQUIRE(osmium::string_to_object_id("-17") == -17);
+ REQUIRE(osmium::string_to_object_id("01") == 1);
+
+ REQUIRE_THROWS_AS(osmium::string_to_object_id(""), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id(" "), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id(" 22"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id("x"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id("0x1"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id("12a"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id("12345678901234567890"), std::range_error);
+}
+
+TEST_CASE("set type and ID from string") {
+ auto n17 = osmium::string_to_object_id("n17", osmium::osm_entity_bits::nwr);
+ REQUIRE(n17.first == osmium::item_type::node);
+ REQUIRE(n17.second == 17);
+
+ auto w42 = osmium::string_to_object_id("w42", osmium::osm_entity_bits::nwr);
+ REQUIRE(w42.first == osmium::item_type::way);
+ REQUIRE(w42.second == 42);
+
+ auto r_2 = osmium::string_to_object_id("r-2", osmium::osm_entity_bits::nwr);
+ REQUIRE(r_2.first == osmium::item_type::relation);
+ REQUIRE(r_2.second == -2);
+
+ auto x3 = osmium::string_to_object_id("3", osmium::osm_entity_bits::nwr);
+ REQUIRE(x3.first == osmium::item_type::undefined);
+ REQUIRE(x3.second == 3);
+
+ REQUIRE_THROWS_AS(osmium::string_to_object_id("", osmium::osm_entity_bits::nwr), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id("n", osmium::osm_entity_bits::nwr), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id("x3", osmium::osm_entity_bits::nwr), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id("nx3", osmium::osm_entity_bits::nwr), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id("n3", osmium::osm_entity_bits::way), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_id("n3a", osmium::osm_entity_bits::nwr), std::range_error);
+}
+
+TEST_CASE("set object version from string") {
+ REQUIRE(osmium::string_to_object_version("0") == 0);
+ REQUIRE(osmium::string_to_object_version("1") == 1);
+
+ REQUIRE_THROWS_AS(osmium::string_to_object_version("-1"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_version(""), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_version(" "), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_version(" 22"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_object_version("x"), std::range_error);
+}
+
+TEST_CASE("set changeset id from string") {
+ REQUIRE(osmium::string_to_changeset_id("0") == 0);
+ REQUIRE(osmium::string_to_changeset_id("1") == 1);
+
+ REQUIRE_THROWS_AS(osmium::string_to_changeset_id("-1"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_changeset_id(""), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_changeset_id(" "), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_changeset_id(" 22"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_changeset_id("x"), std::range_error);
+}
+
+TEST_CASE("set user id from string") {
+ REQUIRE(osmium::string_to_user_id("0") == 0);
+ REQUIRE(osmium::string_to_user_id("1") == 1);
+ REQUIRE(osmium::string_to_user_id("-1") == -1);
+
+ REQUIRE_THROWS_AS(osmium::string_to_user_id("-2"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_user_id(""), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_user_id(" "), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_user_id(" 22"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_user_id("x"), std::range_error);
+}
+
+TEST_CASE("set num changes from string") {
+ REQUIRE(osmium::string_to_num_changes("0") == 0);
+ REQUIRE(osmium::string_to_num_changes("1") == 1);
+
+ REQUIRE_THROWS_AS(osmium::string_to_num_changes("-1"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_num_changes(""), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_num_changes(" "), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_num_changes(" 22"), std::range_error);
+ REQUIRE_THROWS_AS(osmium::string_to_num_changes("x"), std::range_error);
+}
+
diff --git a/test/t/buffer/test_buffer_node.cpp b/test/t/buffer/test_buffer_node.cpp
index aabe6cb..9bc8f70 100644
--- a/test/t/buffer/test_buffer_node.cpp
+++ b/test/t/buffer/test_buffer_node.cpp
@@ -58,78 +58,78 @@ void check_node_2(osmium::Node& node) {
TEST_CASE("Buffer_Node") {
-SECTION("buffer_node") {
- constexpr size_t buffer_size = 10000;
- unsigned char data[buffer_size];
+ SECTION("buffer_node") {
+ constexpr size_t buffer_size = 10000;
+ unsigned char data[buffer_size];
- osmium::memory::Buffer buffer(data, buffer_size, 0);
+ osmium::memory::Buffer buffer(data, buffer_size, 0);
- {
- // add node 1
- osmium::builder::NodeBuilder node_builder(buffer);
- osmium::Node& node = node_builder.object();
- REQUIRE(osmium::item_type::node == node.type());
-
- node.set_id(1);
- node.set_version(3);
- node.set_visible(true);
- node.set_changeset(333);
- node.set_uid(21);
- node.set_timestamp(123);
- node.set_location(osmium::Location(3.5, 4.7));
-
- node_builder.add_user("testuser");
-
- buffer.commit();
- }
-
- {
- // add node 2
- osmium::builder::NodeBuilder node_builder(buffer);
- osmium::Node& node = node_builder.object();
- REQUIRE(osmium::item_type::node == node.type());
-
- node.set_id(2);
- node.set_version(3);
- node.set_visible(true);
- node.set_changeset(333);
- node.set_uid(21);
- node.set_timestamp(123);
- node.set_location(osmium::Location(3.5, 4.7));
-
- node_builder.add_user("testuser");
+ {
+ // add node 1
+ osmium::builder::NodeBuilder node_builder(buffer);
+ osmium::Node& node = node_builder.object();
+ REQUIRE(osmium::item_type::node == node.type());
+
+ node.set_id(1);
+ node.set_version(3);
+ node.set_visible(true);
+ node.set_changeset(333);
+ node.set_uid(21);
+ node.set_timestamp(123);
+ node.set_location(osmium::Location(3.5, 4.7));
+
+ node_builder.add_user("testuser");
+
+ buffer.commit();
+ }
{
- osmium::builder::TagListBuilder tag_builder(buffer, &node_builder);
- tag_builder.add_tag("amenity", "bank");
- tag_builder.add_tag("name", "OSM Savings");
+ // add node 2
+ osmium::builder::NodeBuilder node_builder(buffer);
+ osmium::Node& node = node_builder.object();
+ REQUIRE(osmium::item_type::node == node.type());
+
+ node.set_id(2);
+ node.set_version(3);
+ node.set_visible(true);
+ node.set_changeset(333);
+ node.set_uid(21);
+ node.set_timestamp(123);
+ node.set_location(osmium::Location(3.5, 4.7));
+
+ node_builder.add_user("testuser");
+
+ {
+ osmium::builder::TagListBuilder tag_builder(buffer, &node_builder);
+ tag_builder.add_tag("amenity", "bank");
+ tag_builder.add_tag("name", "OSM Savings");
+ }
+
+ buffer.commit();
}
- buffer.commit();
- }
+ REQUIRE(2 == std::distance(buffer.begin(), buffer.end()));
+ int item_no = 0;
+ for (osmium::memory::Item& item : buffer) {
+ REQUIRE(osmium::item_type::node == item.type());
- REQUIRE(2 == std::distance(buffer.begin(), buffer.end()));
- int item_no = 0;
- for (osmium::memory::Item& item : buffer) {
- REQUIRE(osmium::item_type::node == item.type());
+ osmium::Node& node = static_cast<osmium::Node&>(item);
- osmium::Node& node = static_cast<osmium::Node&>(item);
+ switch (item_no) {
+ case 0:
+ check_node_1(node);
+ break;
+ case 1:
+ check_node_2(node);
+ break;
+ default:
+ break;
+ }
- switch (item_no) {
- case 0:
- check_node_1(node);
- break;
- case 1:
- check_node_2(node);
- break;
- default:
- break;
- }
+ ++item_no;
- ++item_no;
+ }
}
}
-
-}
diff --git a/test/t/buffer/test_buffer_purge.cpp b/test/t/buffer/test_buffer_purge.cpp
index 10cdfe7..a72db1b 100644
--- a/test/t/buffer/test_buffer_purge.cpp
+++ b/test/t/buffer/test_buffer_purge.cpp
@@ -108,7 +108,7 @@ TEST_CASE("Purge data from buffer") {
node_builder.object().set_removed(true);
}
buffer.commit();
- size_t size2 = buffer.committed() - size1;
+
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2);
CallbackClass callback;
@@ -127,20 +127,20 @@ TEST_CASE("Purge data from buffer") {
node_builder.add_user("testuser_longer_name");
}
buffer.commit();
- size_t size1 = buffer.committed();
+
{
osmium::builder::NodeBuilder node_builder(buffer);
node_builder.add_user("testuser");
node_builder.object().set_removed(true);
}
buffer.commit();
- size_t size2 = buffer.committed() - size1;
+
{
osmium::builder::NodeBuilder node_builder(buffer);
node_builder.add_user("sn");
}
buffer.commit();
- size_t size3 = buffer.committed() - (size1 + size2);
+
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 3);
CallbackClass callback;
@@ -159,21 +159,21 @@ TEST_CASE("Purge data from buffer") {
node_builder.object().set_removed(true);
}
buffer.commit();
- size_t size1 = buffer.committed();
+
{
osmium::builder::NodeBuilder node_builder(buffer);
node_builder.add_user("testuser");
node_builder.object().set_removed(true);
}
buffer.commit();
- size_t size2 = buffer.committed() - size1;
+
{
osmium::builder::NodeBuilder node_builder(buffer);
node_builder.add_user("sn");
node_builder.object().set_removed(true);
}
buffer.commit();
- size_t size3 = buffer.committed() - (size1 + size2);
+
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 3);
CallbackClass callback;
diff --git a/test/t/geom/test_exception.cpp b/test/t/geom/test_exception.cpp
new file mode 100644
index 0000000..fe95043
--- /dev/null
+++ b/test/t/geom/test_exception.cpp
@@ -0,0 +1,16 @@
+#include "catch.hpp"
+
+#include <string>
+
+#include <osmium/geom/factory.hpp>
+
+TEST_CASE("Geometry exception") {
+
+ SECTION("geometry_error") {
+ osmium::geometry_error e("some error message", "node", 17);
+ REQUIRE(e.id() == 17);
+ REQUIRE(std::string(e.what()) == "some error message (node_id=17)");
+ }
+
+}
+
diff --git a/test/t/geom/test_factory_with_projection.cpp b/test/t/geom/test_factory_with_projection.cpp
index 9bc8c06..42fc864 100644
--- a/test/t/geom/test_factory_with_projection.cpp
+++ b/test/t/geom/test_factory_with_projection.cpp
@@ -10,32 +10,32 @@
TEST_CASE("Projection") {
-SECTION("point_mercator") {
- osmium::geom::WKTFactory<osmium::geom::MercatorProjection> factory(2);
+ SECTION("point_mercator") {
+ osmium::geom::WKTFactory<osmium::geom::MercatorProjection> factory(2);
- std::string wkt {factory.create_point(osmium::Location(3.2, 4.2))};
- REQUIRE(std::string{"POINT(356222.37 467961.14)"} == wkt);
-}
+ std::string wkt {factory.create_point(osmium::Location(3.2, 4.2))};
+ REQUIRE(std::string {"POINT(356222.37 467961.14)"} == wkt);
+ }
-SECTION("point_epsg_3857") {
- osmium::geom::WKTFactory<osmium::geom::Projection> factory(osmium::geom::Projection(3857), 2);
+ SECTION("point_epsg_3857") {
+ osmium::geom::WKTFactory<osmium::geom::Projection> factory(osmium::geom::Projection(3857), 2);
- std::string wkt {factory.create_point(osmium::Location(3.2, 4.2))};
- REQUIRE(std::string{"POINT(356222.37 467961.14)"} == wkt);
-}
+ std::string wkt {factory.create_point(osmium::Location(3.2, 4.2))};
+ REQUIRE(std::string {"POINT(356222.37 467961.14)"} == wkt);
+ }
-SECTION("wkb_with_parameter") {
- osmium::geom::WKBFactory<osmium::geom::Projection> wkb_factory(osmium::geom::Projection(3857), osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
- osmium::geom::GEOSFactory<osmium::geom::Projection> geos_factory(osmium::geom::Projection(3857));
+ SECTION("wkb_with_parameter") {
+ osmium::geom::WKBFactory<osmium::geom::Projection> wkb_factory(osmium::geom::Projection(3857), osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
+ osmium::geom::GEOSFactory<osmium::geom::Projection> geos_factory(osmium::geom::Projection(3857));
- std::string wkb = wkb_factory.create_point(osmium::Location(3.2, 4.2));
- std::unique_ptr<geos::geom::Point> geos_point = geos_factory.create_point(osmium::Location(3.2, 4.2));
- REQUIRE(geos_to_wkb(geos_point.get()) == wkb);
-}
+ std::string wkb = wkb_factory.create_point(osmium::Location(3.2, 4.2));
+ std::unique_ptr<geos::geom::Point> geos_point = geos_factory.create_point(osmium::Location(3.2, 4.2));
+ REQUIRE(geos_to_wkb(geos_point.get()) == wkb);
+ }
-SECTION("cleanup") {
- // trying to make valgrind happy, but there is still a memory leak in proj library
- pj_deallocate_grids();
-}
+ SECTION("cleanup") {
+ // trying to make valgrind happy, but there is still a memory leak in proj library
+ pj_deallocate_grids();
+ }
}
diff --git a/test/t/geom/test_mercator.cpp b/test/t/geom/test_mercator.cpp
index a6ce2ee..cc16e55 100644
--- a/test/t/geom/test_mercator.cpp
+++ b/test/t/geom/test_mercator.cpp
@@ -4,34 +4,34 @@
TEST_CASE("Mercator") {
-SECTION("mercator_projection") {
- osmium::geom::MercatorProjection projection;
- REQUIRE(3857 == projection.epsg());
- REQUIRE("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs" == projection.proj_string());
-}
-
-SECTION("low_level_mercator_functions") {
- osmium::geom::Coordinates c1(17.839, -3.249);
- osmium::geom::Coordinates r1 = osmium::geom::mercator_to_lonlat(osmium::geom::lonlat_to_mercator(c1));
- REQUIRE(r1.x == Approx(c1.x).epsilon(0.000001));
- REQUIRE(r1.y == Approx(c1.y).epsilon(0.000001));
-
- osmium::geom::Coordinates c2(-89.2, 15.915);
- osmium::geom::Coordinates r2 = osmium::geom::mercator_to_lonlat(osmium::geom::lonlat_to_mercator(c2));
- REQUIRE(r2.x == Approx(c2.x).epsilon(0.000001));
- REQUIRE(r2.y == Approx(c2.y).epsilon(0.000001));
-
- osmium::geom::Coordinates c3(180.0, 85.0);
- osmium::geom::Coordinates r3 = osmium::geom::mercator_to_lonlat(osmium::geom::lonlat_to_mercator(c3));
- REQUIRE(r3.x == Approx(c3.x).epsilon(0.000001));
- REQUIRE(r3.y == Approx(c3.y).epsilon(0.000001));
-}
-
-SECTION("mercator_bounds") {
- osmium::Location mmax(180.0, osmium::geom::MERCATOR_MAX_LAT);
- osmium::geom::Coordinates c = osmium::geom::lonlat_to_mercator(mmax);
- REQUIRE(c.x == Approx(c.y).epsilon(0.001));
- REQUIRE(osmium::geom::detail::y_to_lat(osmium::geom::detail::lon_to_x(180.0)) == Approx(osmium::geom::MERCATOR_MAX_LAT).epsilon(0.0000001));
-}
+ SECTION("mercator_projection") {
+ osmium::geom::MercatorProjection projection;
+ REQUIRE(3857 == projection.epsg());
+ REQUIRE("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs" == projection.proj_string());
+ }
+
+ SECTION("low_level_mercator_functions") {
+ osmium::geom::Coordinates c1(17.839, -3.249);
+ osmium::geom::Coordinates r1 = osmium::geom::mercator_to_lonlat(osmium::geom::lonlat_to_mercator(c1));
+ REQUIRE(r1.x == Approx(c1.x).epsilon(0.000001));
+ REQUIRE(r1.y == Approx(c1.y).epsilon(0.000001));
+
+ osmium::geom::Coordinates c2(-89.2, 15.915);
+ osmium::geom::Coordinates r2 = osmium::geom::mercator_to_lonlat(osmium::geom::lonlat_to_mercator(c2));
+ REQUIRE(r2.x == Approx(c2.x).epsilon(0.000001));
+ REQUIRE(r2.y == Approx(c2.y).epsilon(0.000001));
+
+ osmium::geom::Coordinates c3(180.0, 85.0);
+ osmium::geom::Coordinates r3 = osmium::geom::mercator_to_lonlat(osmium::geom::lonlat_to_mercator(c3));
+ REQUIRE(r3.x == Approx(c3.x).epsilon(0.000001));
+ REQUIRE(r3.y == Approx(c3.y).epsilon(0.000001));
+ }
+
+ SECTION("mercator_bounds") {
+ osmium::Location mmax(180.0, osmium::geom::MERCATOR_MAX_LAT);
+ osmium::geom::Coordinates c = osmium::geom::lonlat_to_mercator(mmax);
+ REQUIRE(c.x == Approx(c.y).epsilon(0.001));
+ REQUIRE(osmium::geom::detail::y_to_lat(osmium::geom::detail::lon_to_x(180.0)) == Approx(osmium::geom::MERCATOR_MAX_LAT).epsilon(0.0000001));
+ }
}
diff --git a/test/t/geom/test_projection.cpp b/test/t/geom/test_projection.cpp
index 2257d7f..5885410 100644
--- a/test/t/geom/test_projection.cpp
+++ b/test/t/geom/test_projection.cpp
@@ -1,5 +1,7 @@
#include "catch.hpp"
+#include <random>
+
#include <osmium/geom/factory.hpp>
#include <osmium/geom/mercator_projection.hpp>
#include <osmium/geom/projection.hpp>
@@ -128,4 +130,20 @@ SECTION("compare_mercators") {
}
}
+SECTION("compare_mercators") {
+ osmium::geom::MercatorProjection projection_merc;
+ osmium::geom::Projection projection_3857(3857);
+
+ std::random_device rd;
+ std::mt19937 gen(rd());
+ std::uniform_real_distribution<> dis_x(-180.0, 180.0);
+ std::uniform_real_distribution<> dis_y(-90.0, 90.0);
+
+ for (int n = 0; n < 100000; ++n) {
+ const osmium::Location loc(dis_x(gen), dis_y(gen));
+ REQUIRE(projection_merc(loc).x == Approx(projection_3857(loc).x).epsilon(0.1));
+ REQUIRE(projection_merc(loc).y == Approx(projection_3857(loc).y).epsilon(0.1));
+ }
+}
+
}
diff --git a/test/t/geom/test_tile.cpp b/test/t/geom/test_tile.cpp
new file mode 100644
index 0000000..e80cb96
--- /dev/null
+++ b/test/t/geom/test_tile.cpp
@@ -0,0 +1,93 @@
+#include "catch.hpp"
+
+#include <sstream>
+
+#include <osmium/geom/tile.hpp>
+
+#include "helper.hpp"
+
+#include "test_tile_data.hpp"
+
+TEST_CASE("Tile") {
+
+ SECTION("x0.0 y0.0 zoom 0") {
+ osmium::Location l(0.0, 0.0);
+
+ osmium::geom::Tile t(0, l);
+
+ REQUIRE(t.x == 0);
+ REQUIRE(t.y == 0);
+ REQUIRE(t.z == 0);
+ }
+
+ SECTION("x180.0 y90.0 zoom 0") {
+ osmium::Location l(180.0, 90.0);
+
+ osmium::geom::Tile t(0, l);
+
+ REQUIRE(t.x == 0);
+ REQUIRE(t.y == 0);
+ REQUIRE(t.z == 0);
+ }
+
+ SECTION("x180.0 y90.0 zoom 4") {
+ osmium::Location l(180.0, 90.0);
+
+ osmium::geom::Tile t(4, l);
+
+ REQUIRE(t.x == (1 << 4) - 1);
+ REQUIRE(t.y == 0);
+ REQUIRE(t.z == 4);
+ }
+
+ SECTION("x0.0 y0.0 zoom 4") {
+ osmium::Location l(0.0, 0.0);
+
+ osmium::geom::Tile t(4, l);
+
+ auto n = 1 << (4-1);
+ REQUIRE(t.x == n);
+ REQUIRE(t.y == n);
+ REQUIRE(t.z == 4);
+ }
+
+ SECTION("equality") {
+ osmium::geom::Tile a(4, 3, 4);
+ osmium::geom::Tile b(4, 3, 4);
+ osmium::geom::Tile c(4, 4, 3);
+ REQUIRE(a == b);
+ REQUIRE(a != c);
+ REQUIRE(b != c);
+ }
+
+ SECTION("order") {
+ osmium::geom::Tile a(2, 3, 4);
+ osmium::geom::Tile b(4, 3, 4);
+ osmium::geom::Tile c(4, 4, 3);
+ osmium::geom::Tile d(4, 4, 2);
+ REQUIRE(a < b);
+ REQUIRE(a < c);
+ REQUIRE(b < c);
+ REQUIRE(d < c);
+ }
+
+ SECTION("tilelist") {
+ std::istringstream input_data(s);
+ while (input_data) {
+ double lon, lat;
+ uint32_t x, y, zoom;
+ input_data >> lon;
+ input_data >> lat;
+ input_data >> x;
+ input_data >> y;
+ input_data >> zoom;
+
+ osmium::Location l(lon, lat);
+ osmium::geom::Tile t(zoom, l);
+ REQUIRE(t.x == x);
+ REQUIRE(t.y == y);
+ }
+ }
+
+}
+
diff --git a/test/t/geom/test_tile_data.hpp b/test/t/geom/test_tile_data.hpp
new file mode 100644
index 0000000..e5c0953
--- /dev/null
+++ b/test/t/geom/test_tile_data.hpp
@@ -0,0 +1,475 @@
+
+std::string s = R"(127.4864358 16.8380041 223904 118630 18
+163.1103174 39.4760232 121 48 7
+-4.1372725 -22.5105386 31 36 6
+98.7193066 -36.2312406 1 1 1
+63.5773661 -13.47636 21 17 5
+-88.4518148 37.9805485 260 395 10
+-14.5903133 -28.2989812 3763 4767 13
+-13.4971239 -34.4080035 14 19 5
+-169.156223 -64.0900356 3 93 7
+27.1473191 -4.1993125 4713 4191 13
+-160.9733129 54.3684314 13 81 8
+129.0194139 14.2576156 439 235 9
+-69.5085993 -56.8253221 10057 22700 15
+-77.8387486 18.1961517 1162 1837 12
+-76.2695325 -18.2494296 147 282 9
+-91.594905 7.6698071 1 3 3
+-116.7926741 -20.6060813 179 571 10
+109.0552776 -1.9947569 52620 33131 16
+-156.1846426 -79.3817554 33 449 9
+-95.3403755 -27.8978407 1 4 3
+-55.1827573 -73.2293796 44 103 7
+-108.5207885 -48.0099293 50 167 8
+23.7540108 -15.3395164 9273 8898 14
+-155.6662842 -68.3295899 0 0 0
+75.8139119 30.9914252 363 209 9
+-135.8034544 64.7242469 0 1 2
+-48.743352 70.9392876 23 13 6
+-38.6968026 7.7867812 0 0 0
+-18.5234838 11.8557704 29395 30594 16
+-152.5632568 19.4069834 78 455 10
+-63.2089431 -80.5909713 0 0 0
+-94.1255611 -81.2028822 244 930 10
+175.0862205 -33.0865142 3 2 2
+-179.6241926 -37.0256609 1 625 10
+135.6783824 -38.6011643 459739 323170 19
+-139.6407533 -83.2495209 0 7 3
+-14.1336447 -56.5465949 58 88 7
+-30.7414568 -32.9543731 26 38 6
+10.3306861 73.2444693 1082 399 11
+-84.8379263 29.2363222 16 26 6
+-94.0685822 -39.5503996 7821 20309 15
+-86.5944356 -41.7491891 265 642 10
+11.9182172 -80.5613703 34937 58784 16
+91.8773752 -32.1741317 0 0 0
+126.2879157 20.5759564 1742 904 11
+-160.7743029 -47.3192128 27999 340565 19
+-4.2449045 -50.3288332 31 42 6
+-66.6857158 61.4380757 10 9 5
+169.7372317 -74.3365704 3 3 2
+87.4815328 75.6218888 95 21 7
+60.3544927 28.3165267 0 0 0
+-48.9614619 -59.3292497 2 5 3
+-123.2935018 -59.5454886 80 362 9
+-31.5909316 -14.8985476 13 17 5
+58.1862173 59.0957666 2710 1209 12
+-72.8881665 -2.2648849 1218 2073 12
+-33.7267461 8.6006817 106512 124785 18
+175.723181 46.4929742 7 2 3
+-127.1963326 76.0328786 0 0 0
+-161.7444367 -26.7634497 13293 151310 18
+-163.976298 -8.1169845 91 1070 11
+63.7757109 5.6049418 2 1 2
+12.7012434 22.1157713 70160 57276 17
+19.5832849 -25.0284049 1135 1171 11
+-22.6619642 54.8831276 111 81 8
+78.7736907 24.0919863 5888 3530 13
+121.9003045 -64.6256685 107 94 7
+-64.8766793 61.6655916 81 71 8
+113.0498445 -70.0016518 416 397 9
+-51.5116259 68.1532424 46781 31217 17
+-89.9005747 87.9523248 512 0 11
+59.2536822 -75.1520493 10 13 4
+17.375372 74.9259262 287448 93371 19
+75.6426945 8.4808632 186153 124873 18
+144.89589 75.1647661 14786 2875 14
+174.4350898 -29.268169 258091 153376 18
+-91.8773113 50.6182166 0 0 0
+5.3822308 45.1391794 134991 94156 18
+43.0978373 -10.0764237 324909 276895 19
+55.6682917 -40.9015342 21451 20470 15
+-37.584032 52.253723 6 5 4
+131.0141997 29.0271798 28309 13621 15
+69.8830721 -86.8548645 363918 524287 19
+-107.7917548 -76.9626654 26290 110787 17
+-57.1736642 49.9345991 2 2 3
+165.5170226 -84.9735363 982 1021 10
+-139.7208984 -73.8754873 1 12 4
+-154.5959463 -10.596718 4 33 6
+-106.4164918 36.5042686 3348 6405 14
+-92.9688259 -11.2262505 0 2 2
+138.2722283 8.1109779 7 3 3
+123.1389319 -40.3505677 862 637 10
+-171.4780435 24.9112482 0 13 5
+89.3668763 -63.1809434 392293 381781 19
+-79.6906176 -13.376312 9130 17612 15
+133.1329522 -28.9032634 445 298 9
+115.0369496 70.6965823 6 1 3
+-74.8926697 -78.9770185 2391 7144 13
+51.9175766 73.0184277 164 50 8
+178.1319784 43.7111421 509 186 9
+162.4098389 61.1595443 0 0 0
+7.6241126 -75.6182944 2 3 2
+172.8902767 28.5068027 125 53 7
+156.4030739 -76.7309238 478 431 9
+-131.3963189 62.2039684 1 2 3
+34.6057088 -36.2933264 2441 2491 12
+-3.3896413 -48.2734347 15 20 5
+83.528842 -48.219886 2998 2675 12
+16.6000512 -31.6322244 17894 19421 15
+-18.2425749 21.0749052 14 14 5
+35.6035336 46.9916228 78498 46105 17
+-109.3453091 -34.2312523 12 38 6
+88.4909962 58.6104749 47 19 6
+-129.7372783 21.7408241 571 1794 12
+25.7269392 -40.1240139 1 1 1
+26.3829579 5.248998 37570 31811 16
+141.1768247 -41.4653038 14617 10269 14
+151.3788752 -38.0160512 241302 161042 18
+-92.7471483 -35.391745 15883 39664 16
+142.5902623 -14.1023743 28 17 5
+179.3461485 -86.7573357 3 3 2
+-40.9746194 61.5689546 790 576 11
+128.6399735 -54.8895009 56186 44772 16
+-141.391583 -63.8272 0 2 2
+-3.5004218 19.3089998 4016 3648 13
+16.138208 -42.7868627 1 1 1
+78.502315 -18.91667 2 2 2
+-44.6311826 -15.7483106 98572 142686 18
+-120.431941 -39.3431529 0 0 0
+-70.4915024 25.4763412 9967 13984 15
+118.0711114 -66.5691073 211 192 8
+-114.945538 38.1764389 0 0 0
+142.991315 -46.3378741 14699 10577 14
+34.2770562 -84.7173756 312063 518834 19
+109.5563415 -85.9138266 105424 131071 17
+-171.8032643 70.1948223 0 3 4
+-90.8434294 89.7252122 126 0 9
+163.5677082 -53.9885419 3 2 2
+128.884016 -63.0732584 112461 95358 17
+116.5348575 -56.1616143 843 705 10
+-171.5770602 37.9225943 11 197 9
+48.1396653 -49.3932234 5191 5392 13
+-157.6786731 15.3895763 32507 239456 19
+15.7385145 -37.1364397 1113 1251 11
+137.5179466 61.2025671 1 0 1
+-70.4767722 42.9798424 19938 24086 16
+27.8867901 43.4642562 9461 5991 14
+68.5677462 -84.9560937 11312 16334 14
+-56.790151 -67.124147 179437 395476 19
+108.850832 43.3493384 26291 11996 15
+-139.0655153 8.2673118 1 7 4
+59.3726661 83.3857699 21788 1515 15
+-158.4718709 -12.2313178 1 17 5
+30.358316 -83.020501 2393 3871 12
+-169.9667863 71.1152107 1 13 6
+-89.9418297 -7.7258969 131156 273429 19
+-16.5050312 47.1843923 116 89 8
+-151.9641886 -36.3579042 5103 39881 16
+169.7406916 60.0950674 62 18 6
+32.6694543 -1.8435981 2 2 2
+97.7880811 77.5295169 50569 9674 16
+87.7554889 -85.6741368 389947 524287 19
+-19.0174909 29.1940122 0 0 1
+-86.6180019 82.6445919 1 0 2
+-50.1997802 -21.1913243 1476 2294 12
+73.8710121 75.2201385 5 1 3
+41.7434624 79.1410045 322937 65770 19
+-122.4312562 -68.4513916 10 48 6
+-54.6116448 -23.1761137 1 2 2
+-35.8774263 -51.5317442 102 170 8
+179.2976644 -76.2729885 127 107 7
+-111.6934402 -85.2696836 1 7 3
+-24.2137947 28.4102025 3 3 3
+-168.0816395 -64.0317696 16 375 9
+43.2514876 6.4266793 2540 1974 12
+25.5877932 49.3486828 4 2 3
+-133.3671657 -25.0795973 8 36 6
+-140.2002274 -37.3713396 452 2507 12
+73.6326557 -21.9898207 360 288 9
+-83.0901448 -69.1893461 2205 6305 13
+-32.83227 -11.1061854 3348 4350 13
+-151.8897244 14.6891958 0 0 0
+-118.1125151 82.3085937 704 288 12
+119.9903922 1.4884267 53 31 6
+-116.9455865 -48.1971821 0 2 2
+111.4279587 -52.6024326 828 688 10
+-78.9207774 28.6183104 147207 218615 19
+45.1367631 24.1416251 40 27 6
+115.0905685 7.2971256 6714 3929 13
+-58.0837371 -55.4033522 43 87 7
+-44.6785779 83.0751777 6158 877 14
+80.2002966 84.3087089 2960 91 12
+-167.3118039 -59.2698371 72 1445 11
+139.9974902 -74.5994693 455 419 9
+-27.5858357 -36.1890547 6936 9960 14
+68.8572424 20.2096749 353 226 9
+-168.7172825 69.1607462 2053 15104 16
+62.1361934 74.6007777 44079 11896 16
+-102.9645124 65.3735325 112191 135144 19
+178.8434887 18.6231394 65325 29316 16
+-138.0494072 -80.3786289 29 228 8
+33.3858934 62.9029909 155382 71699 18
+-1.6915643 74.737228 1 0 2
+18.2680756 6.6441482 1 0 1
+34.0511738 -28.6862516 2 2 2
+-24.0705994 -0.6026568 28386 32877 16
+-176.8765092 -14.3252022 568 35403 16
+154.6553417 -79.7390666 1903 1809 11
+151.6055263 59.552346 14 4 4
+-101.7681729 45.3498263 113933 187876 19
+-52.3703658 -89.8260406 181 511 9
+-85.7937259 16.5632413 2143 3713 13
+114.7030999 6.6846014 104 61 7
+13.6027861 88.6863877 2 0 2
+60.5726928 38.256536 43794 25219 16
+141.0903381 -35.4468007 7306 4959 13
+-38.8182454 -55.2332792 200 350 9
+179.7818018 -79.6600052 523970 462627 19
+-45.2102175 82.7381225 196301 32058 19
+-36.5811826 -35.3991346 0 0 0
+-26.7719575 -75.7014102 223154 435372 19
+77.3451937 -65.4613594 1 1 1
+-37.3286225 38.3250599 51945 50407 17
+70.8235495 35.3870419 365288 206979 19
+99.8381373 -83.4101655 1 1 1
+25.8851923 67.415543 9370 3991 14
+-12.3393758 68.5972027 7 3 4
+-142.9400273 -36.2904852 1 9 4
+110.085689 -50.9514972 422467 348655 19
+121.5093657 53.9939447 54888 21044 16
+151.1307841 -33.0798435 58 38 6
+100.4346499 -57.0129759 6 5 3
+114.0564882 63.4987339 428250 141474 19
+-17.3978586 19.2981593 57 57 7
+-129.101039 -66.3423574 579 3067 12
+117.6639917 14.0568892 433504 241463 19
+97.7014577 69.1261732 202216 60490 18
+-174.7931333 81.4174709 7583 46045 19
+47.205341 -48.8608019 20680 21495 15
+167.416796 -7.5063098 247 133 8
+63.6744589 21.3392888 0 0 0
+-106.0719817 33.8353547 53832 104862 18
+-48.4051268 27.0438152 191648 221209 19
+64.5675545 -27.0683253 5 4 3
+110.7800249 -35.8217841 0 0 0
+164.8954138 81.9558801 31393 2538 15
+-54.4595565 -23.0128432 357 579 10
+43.2542709 67.694011 2540 989 12
+137.6537233 -78.7052092 28913 28450 15
+76.9271563 -60.0777348 0 0 0
+-145.0240216 47.3869213 6367 22947 16
+136.2328853 -73.4534547 3598 3304 12
+48.8047148 74.3001023 81 23 7
+-144.6978756 33.6270048 200 820 11
+64.6723407 -37.196427 21 19 5
+-58.3356482 -19.0812366 22148 36307 16
+19.611535 -31.3013119 0 0 0
+-63.8923439 -25.9560287 1 2 2
+-152.5288047 -30.9747477 0 1 1
+-99.8509683 -69.0258965 7295 25181 15
+-22.9015207 -21.0915082 13 17 5
+161.4402438 61.1430241 15539 4652 14
+-102.9499976 -1.2629414 1 4 3
+-159.7995801 51.1570142 14 85 8
+10.5265485 -86.8526122 67 127 7
+47.1581041 -73.1628608 646 823 10
+2.7577906 -66.3257104 66540 98133 17
+96.9653593 -9.8258675 6 4 3
+-55.4199846 25.3325116 2834 3499 13
+-47.3590106 59.5085133 2 2 3
+179.1441501 22.1324479 7 3 3
+16.2649007 47.8480398 4 2 3
+-27.8373963 -0.3926597 27700 32839 16
+-99.7938802 -48.8013068 912 2685 12
+133.4858024 28.457146 3 1 2
+-174.7621207 -25.8318084 238 9409 14
+106.856378 19.640472 203 113 8
+31.4361995 -80.2488406 76981 116886 17
+148.6539554 -70.0347611 116 99 7
+45.1821773 17.5961595 80 57 7
+-30.3630114 71.3238998 54481 27877 17
+106.547704 44.9731358 6520 2947 13
+-132.8057564 23.3928795 67 221 9
+116.6455816 -10.1097592 52 33 6
+172.5512559 -53.2307289 3 2 2
+-114.2084519 42.834332 2994 6030 14
+91.0172087 87.6025 1 0 1
+-101.666812 -84.7858729 7130 32495 15
+-14.8074931 68.3277393 0 0 0
+140.3354277 -7.8709618 14 8 4
+-130.4961987 -69.4777523 9011 50594 16
+-121.239479 1.0896367 1 3 3
+-141.2241052 3.4495348 56471 257117 19
+42.6041377 -19.1328846 2532 2269 12
+141.3750885 -1.8110503 468036 264781 19
+-26.545021 -30.9641274 218 302 9
+87.6154866 10.1978751 5 3 3
+88.002559 -33.4108714 762 612 10
+170.9910642 -7.1925019 3993 2130 12
+-66.5680487 -88.1144993 165197 524287 19
+-71.5925378 45.720316 0 0 0
+-16.457642 57.1688038 930 625 11
+20.8379624 -11.1485568 35 33 6
+-72.9399538 -16.6504502 1 2 2
+52.8746845 -71.5213577 10598 12927 14
+93.2392918 12.5073156 48 29 6
+-3.7803834 73.7748237 128319 49794 18
+93.5713795 -38.8308882 24 19 5
+87.3474619 -6.9970464 23 16 5
+161.2199467 48.5612779 30 11 5
+87.343969 -31.3153618 47 37 6
+60.5318627 58.0869948 42 19 6
+161.4388458 42.7612385 1 0 1
+14.1262999 -26.2101142 4 4 3
+-135.776346 -21.4248586 503 2297 12
+-100.3980364 82.0236388 1 0 3
+-55.8093833 -87.2455194 0 0 0
+-15.6397352 64.454076 935 540 11
+131.5974423 39.1251372 110 48 7
+56.8045509 27.5658629 168 107 8
+146.3634996 14.9287416 3 1 2
+51.5699041 74.0370231 82 23 7
+29.3100901 33.7208834 152414 104963 18
+19.0622442 1.6781772 141 126 8
+-22.2575472 73.6467471 114864 50126 18
+125.0208495 47.8533914 3470 1426 12
+-92.4804503 29.8409387 995 1691 12
+113.6362202 86.1158625 0 0 0
+113.6203756 28.4267778 26 13 5
+124.472202 25.8347062 13856 6974 14
+79.3654306 -33.7864728 46 38 6
+-121.169233 -66.7642843 2 12 4
+179.5816311 1.0182064 0 0 0
+179.1123794 53.367624 0 0 0
+-25.6611689 32.6575586 14048 13236 15
+92.3370554 58.8306651 12 4 4
+142.2756448 63.6603101 3 1 2
+-162.8914282 -84.54406 6229 129034 17
+-54.0759935 53.1086102 0 0 0
+9.1647045 -39.4876873 34436 40604 16
+59.3708822 -43.9789068 10894 10425 14
+-16.6397572 46.5985252 929 723 11
+-36.1053642 -67.6882841 0 1 1
+-82.5851985 -69.5277766 4 12 4
+117.0059969 -63.2697116 432546 382068 19
+127.9740251 85.5341901 112129 0 17
+-13.9255265 59.7720207 120931 76457 18
+-167.7778382 41.7974194 69 761 11
+-100.1217856 -70.5624949 454 1599 11
+-42.4790343 -2.0016191 25034 33132 16
+-8.0782317 65.9680074 30 16 6
+-37.0481466 -55.2856125 203 350 9
+149.074382 16.7121888 58 28 6
+-53.1010518 -15.8492068 0 0 0
+50.8517919 -30.8366257 42025 38674 16
+-175.0355994 77.1929422 0 4 5
+-33.3221217 72.5636809 6 3 4
+-139.9201802 52.3400823 7296 21546 16
+86.0299659 23.4535286 1513 886 11
+105.6297238 -50.5521342 25998 21733 15
+104.2700533 36.5417507 206999 102450 18
+58.5238253 84.0320186 86843 3912 17
+-121.9177826 65.4393267 1321 2108 13
+-152.689211 57.4112922 39774 159515 19
+94.2583831 80.8625455 6240 801 13
+118.8199874 -37.6116567 53 39 6
+5.787144 7.0599251 4227 3934 13
+152.1682213 11.778732 236 119 8
+37.4503636 64.311498 2474 1084 12
+35.2616139 -59.8196291 38 45 6
+-20.2808572 -26.9983008 29075 37875 16
+-88.8541607 -20.4896703 66370 146320 18
+125.7726709 41.2603793 27 11 5
+-55.4322696 22.1767236 11338 14313 15
+-38.2393439 -56.4681037 6 11 4
+-139.4517643 -81.3621632 3 29 5
+-146.7954207 -74.6050826 6044 53642 16
+161.6654898 -71.7313805 15549 12957 14
+-85.4720514 -73.177675 2 6 3
+-25.7457381 -42.9842376 13 20 5
+-2.0766311 51.0142455 0 0 1
+-82.9179334 1.4865326 8836 16248 15
+140.5661302 61.5056993 28 9 5
+-30.2614099 35.5786378 54518 51659 17
+-49.2072142 -38.6965571 0 1 1
+124.6587534 9.5039576 433 242 9
+-113.4516741 81.4585593 24229 11410 17
+-4.5134723 68.229217 3 1 3
+75.4838529 -44.997406 2906 2622 12
+6.4715239 28.6900832 8486 6828 14
+91.9187555 -24.8192643 6187 4679 13
+-28.2510181 -42.6238777 26 40 6
+-151.1042237 -21.4553189 2630 18384 15
+-149.6272551 0.4235911 1382 8172 14
+-51.9171488 74.630423 0 0 0
+-36.5660117 37.242858 101 99 8
+91.7136677 -30.9077617 772 604 10
+61.6846009 -85.9378164 5 7 3
+11.3772008 69.40183 34839 14980 16
+82.6825938 9.4496443 11954 7759 14
+61.8446231 -40.0114106 2751 2545 12
+-51.6223196 -11.7880324 5 8 4
+113.0309076 -73.4376173 13336 13217 14
+-169.3808275 -72.7209175 0 25 5
+-98.5653414 -80.0893122 231 910 10
+-20.4653707 29.9801495 3 3 3
+78.9156686 2.599349 0 0 0
+76.0635255 -71.0823347 2913 3216 12
+-26.1185551 22.3616029 28013 28589 16
+177.8803853 -56.3662368 4071 2828 12
+-157.7926463 78.4998022 15 34 8
+168.6834344 -34.5535211 7934 4934 13
+-77.208013 -44.0964079 0 1 1
+-56.6162078 28.1240365 10 13 5
+8.6548899 72.178831 137374 53767 18
+-27.9342497 8.2525327 1 1 2
+91.6356971 -13.5230128 6181 4406 13
+-161.9980398 -75.4443511 0 13 4
+46.8556576 -27.1078679 5162 4737 13
+147.2806954 -48.1491071 465 334 9
+-168.2679875 -29.0171568 0 2 2
+10.0251187 -3.144812 8 8 4
+109.0281873 81.9713348 26307 2528 15
+-129.6281276 -36.9614028 73359 320148 19
+7.3831244 -18.3270273 2132 2260 12
+-34.4625217 53.2837646 52988 42524 17
+129.8855275 -26.30807 3525 2358 12
+-69.6374195 -45.7769025 10045 21081 15
+59.9868336 50.3716565 43688 22120 16
+126.4653338 -75.607391 1743 1698 11
+-34.6459616 53.2502443 51 41 7
+152.2415169 -71.7528837 1 1 1
+-83.2126752 32.6685119 35239 52939 17
+178.6388805 70.5727365 31 7 5
+-153.5646223 -81.9491561 2 29 5
+178.2668159 11.8222247 0 0 0
+-27.136902 18.4287365 6 7 4
+-104.7744923 -64.7769211 54777 193540 18
+58.2318889 9.5897974 2710 1938 12
+138.9707487 -65.2734433 14516 12149 14
+-115.29331 -84.3402223 2944 16033 14
+-66.3487123 -81.8340211 20 58 6
+76.1802855 40.4007156 364 193 9
+-77.5026834 -30.653231 145 301 9
+-52.6095007 -79.7155889 11595 28942 15
+-2.5594899 -31.6276806 7 9 4
+-58.6267217 41.4851391 2 2 3
+-0.7245205 -70.7329433 509 801 10
+161.2822996 -79.0311957 124257 114418 17
+144.8720197 80.1059269 14785 1811 14
+159.3764075 -23.5100054 0 0 0
+82.3109493 -7.0673699 95504 68115 17
+94.3931949 63.0474034 97 34 7
+87.4523391 -73.2690527 3043 3297 12
+101.4256455 -0.8267694 12 8 4
+-112.7666152 -82.3670281 12239 61007 16
+-82.0948447 -38.0810449 8 19 5
+113.2906728 -19.193243 104 70 7
+16.953131 78.402684 35 8 6
+-81.7974685 -53.9596787 34 86 7
+69.8051889 58.1416894 181902 78760 18
+-9.2435464 -53.4296594 3 5 3
+30.0415066 11.4884737 4 3 3
+125.2704157 -69.6324197 54 49 6
+-41.2060435 63.8501787 789 548 11
+120.407662 -4.9889504 6835 4209 13
+92.0345558 -8.0809262 24761 17121 15
+127.1061722 83.1311204 6988 428 13
+-178.9414629 64.0086678 770 69897 18
+49.0743035 -4.3000419 10425 8387 14
+-45.109002 -55.1435498 1534 2803 12
+3.2795498 75.95918 32 10 6
+)";
+
diff --git a/test/t/geom/test_wkt.cpp b/test/t/geom/test_wkt.cpp
index ff1417c..5383074 100644
--- a/test/t/geom/test_wkt.cpp
+++ b/test/t/geom/test_wkt.cpp
@@ -74,6 +74,14 @@ SECTION("linestring_with_two_same_locations") {
});
REQUIRE_THROWS_AS(factory.create_linestring(wnl), osmium::geometry_error);
+
+ try {
+ factory.create_linestring(wnl);
+ } catch (osmium::geometry_error& e) {
+ REQUIRE(e.id() == 0);
+ REQUIRE(std::string(e.what()) == "need at least two points for linestring");
+ }
+
REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward), osmium::geometry_error);
{
diff --git a/test/t/index/test_id_to_location.cpp b/test/t/index/test_id_to_location.cpp
index fbb3f6a..4aca238 100644
--- a/test/t/index/test_id_to_location.cpp
+++ b/test/t/index/test_id_to_location.cpp
@@ -58,113 +58,113 @@ void test_func_real(TIndex& index) {
TEST_CASE("IdToLocation") {
-SECTION("Dummy") {
- typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_type;
+ SECTION("Dummy") {
+ typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_type;
- index_type index1;
+ index_type index1;
- REQUIRE(0 == index1.size());
- REQUIRE(0 == index1.used_memory());
+ REQUIRE(0 == index1.size());
+ REQUIRE(0 == index1.used_memory());
- test_func_all<index_type>(index1);
+ test_func_all<index_type>(index1);
- REQUIRE(0 == index1.size());
- REQUIRE(0 == index1.used_memory());
-}
+ REQUIRE(0 == index1.size());
+ REQUIRE(0 == index1.used_memory());
+ }
-SECTION("DenseMemArray") {
- typedef osmium::index::map::DenseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
+ SECTION("DenseMemArray") {
+ typedef osmium::index::map::DenseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
- index_type index1;
- index1.reserve(1000);
- test_func_all<index_type>(index1);
+ index_type index1;
+ index1.reserve(1000);
+ test_func_all<index_type>(index1);
- index_type index2;
- index2.reserve(1000);
- test_func_real<index_type>(index2);
-}
+ index_type index2;
+ index2.reserve(1000);
+ test_func_real<index_type>(index2);
+ }
#ifdef __linux__
-SECTION("DenseMmapArray") {
- typedef osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
+ SECTION("DenseMmapArray") {
+ typedef osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
- index_type index1;
- test_func_all<index_type>(index1);
+ index_type index1;
+ test_func_all<index_type>(index1);
- index_type index2;
- test_func_real<index_type>(index2);
-}
+ index_type index2;
+ test_func_real<index_type>(index2);
+ }
#else
# pragma message("not running 'DenseMapMmap' test case on this machine")
#endif
-SECTION("DenseFileArray") {
- typedef osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
+ SECTION("DenseFileArray") {
+ typedef osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
- index_type index1;
- test_func_all<index_type>(index1);
+ index_type index1;
+ test_func_all<index_type>(index1);
- index_type index2;
- test_func_real<index_type>(index2);
-}
+ index_type index2;
+ test_func_real<index_type>(index2);
+ }
#ifdef OSMIUM_WITH_SPARSEHASH
-SECTION("SparseMemTable") {
- typedef osmium::index::map::SparseMemTable<osmium::unsigned_object_id_type, osmium::Location> index_type;
+ SECTION("SparseMemTable") {
+ typedef osmium::index::map::SparseMemTable<osmium::unsigned_object_id_type, osmium::Location> index_type;
- index_type index1;
- test_func_all<index_type>(index1);
+ index_type index1;
+ test_func_all<index_type>(index1);
- index_type index2;
- test_func_real<index_type>(index2);
-}
+ index_type index2;
+ test_func_real<index_type>(index2);
+ }
#endif
-SECTION("SparseMemMap") {
- typedef osmium::index::map::SparseMemMap<osmium::unsigned_object_id_type, osmium::Location> index_type;
+ SECTION("SparseMemMap") {
+ typedef osmium::index::map::SparseMemMap<osmium::unsigned_object_id_type, osmium::Location> index_type;
- index_type index1;
- test_func_all<index_type>(index1);
+ index_type index1;
+ test_func_all<index_type>(index1);
- index_type index2;
- test_func_real<index_type>(index2);
-}
+ index_type index2;
+ test_func_real<index_type>(index2);
+ }
-SECTION("SparseMemArray") {
- typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
+ SECTION("SparseMemArray") {
+ typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
- index_type index1;
+ index_type index1;
- REQUIRE(0 == index1.size());
- REQUIRE(0 == index1.used_memory());
+ REQUIRE(0 == index1.size());
+ REQUIRE(0 == index1.used_memory());
- test_func_all<index_type>(index1);
+ test_func_all<index_type>(index1);
- REQUIRE(2 == index1.size());
+ REQUIRE(2 == index1.size());
- index_type index2;
- test_func_real<index_type>(index2);
-}
+ index_type index2;
+ test_func_real<index_type>(index2);
+ }
-SECTION("Dynamic map choice") {
- typedef osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location> map_type;
- const auto& map_factory = osmium::index::MapFactory<osmium::unsigned_object_id_type, osmium::Location>::instance();
+ SECTION("Dynamic map choice") {
+ typedef osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location> map_type;
+ const auto& map_factory = osmium::index::MapFactory<osmium::unsigned_object_id_type, osmium::Location>::instance();
- std::vector<std::string> map_type_names = map_factory.map_types();
- REQUIRE(map_type_names.size() >= 5);
+ std::vector<std::string> map_type_names = map_factory.map_types();
+ REQUIRE(map_type_names.size() >= 5);
- for (const auto& map_type_name : map_type_names) {
- std::unique_ptr<map_type> index1 = map_factory.create_map(map_type_name);
- index1->reserve(1000);
- test_func_all<map_type>(*index1);
+ for (const auto& map_type_name : map_type_names) {
+ std::unique_ptr<map_type> index1 = map_factory.create_map(map_type_name);
+ index1->reserve(1000);
+ test_func_all<map_type>(*index1);
- std::unique_ptr<map_type> index2 = map_factory.create_map(map_type_name);
- index2->reserve(1000);
- test_func_real<map_type>(*index2);
+ std::unique_ptr<map_type> index2 = map_factory.create_map(map_type_name);
+ index2->reserve(1000);
+ test_func_real<map_type>(*index2);
+ }
}
-}
}
diff --git a/test/t/index/test_typed_mmap.cpp b/test/t/index/test_typed_mmap.cpp
deleted file mode 100644
index df95dc2..0000000
--- a/test/t/index/test_typed_mmap.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-#include "catch.hpp"
-
-#include <osmium/index/detail/typed_mmap.hpp>
-
-#if defined(_MSC_VER) || (defined(__GNUC__) && defined(_WIN32))
- #include "win_mkstemp.hpp"
-#endif
-
-TEST_CASE("TypedMmap") {
-
-SECTION("Mmap") {
- uint64_t* data = osmium::detail::typed_mmap<uint64_t>::map(10);
-
- data[0] = 4ul;
- data[3] = 9ul;
- data[9] = 25ul;
-
- REQUIRE(4ul == data[0]);
- REQUIRE(9ul == data[3]);
- REQUIRE(25ul == data[9]);
-
- osmium::detail::typed_mmap<uint64_t>::unmap(data, 10);
-}
-
-SECTION("MmapSizeZero") {
- REQUIRE_THROWS_AS(osmium::detail::typed_mmap<uint64_t>::map(0), std::system_error);
-}
-
-SECTION("MmapHugeSize") {
- // this is a horrible hack to only run the test on 64bit machines.
- if (sizeof(size_t) >= 8) {
- REQUIRE_THROWS_AS(osmium::detail::typed_mmap<uint64_t>::map(1ULL << (sizeof(size_t) * 6)), std::system_error);
- }
-}
-
-#ifdef __linux__
-SECTION("Remap") {
- uint64_t* data = osmium::detail::typed_mmap<uint64_t>::map(10);
-
- data[0] = 4ul;
- data[3] = 9ul;
- data[9] = 25ul;
-
- uint64_t* new_data = osmium::detail::typed_mmap<uint64_t>::remap(data, 10, 1000);
-
- REQUIRE(4ul == new_data[0]);
- REQUIRE(9ul == new_data[3]);
- REQUIRE(25ul == new_data[9]);
-}
-#else
-# pragma message("not running 'Remap' test case on this machine")
-#endif
-
-SECTION("FileSize") {
- const int size = 100;
- char filename[] = "test_mmap_file_size_XXXXXX";
- const int fd = mkstemp(filename);
- REQUIRE(fd > 0);
- REQUIRE(0 == osmium::detail::typed_mmap<uint64_t>::file_size(fd));
- REQUIRE(0 == ftruncate(fd, size * sizeof(uint64_t)));
- REQUIRE(size == osmium::detail::typed_mmap<uint64_t>::file_size(fd));
-
- osmium::detail::typed_mmap<uint64_t>::grow_file(size / 2, fd);
- REQUIRE(size == osmium::detail::typed_mmap<uint64_t>::file_size(fd));
-
- osmium::detail::typed_mmap<uint64_t>::grow_file(size, fd);
- REQUIRE(size == osmium::detail::typed_mmap<uint64_t>::file_size(fd));
-
- osmium::detail::typed_mmap<uint64_t>::grow_file(size * 2, fd);
- REQUIRE((size * 2) == osmium::detail::typed_mmap<uint64_t>::file_size(fd));
-
- REQUIRE(0 == close(fd));
- REQUIRE(0 == unlink(filename));
-}
-
-SECTION("GrowAndMap") {
- const int size = 100;
- char filename[] = "test_mmap_grow_and_map_XXXXXX";
- const int fd = mkstemp(filename);
- REQUIRE(fd > 0);
-
- uint64_t* data = osmium::detail::typed_mmap<uint64_t>::grow_and_map(size, fd);
- REQUIRE(size == osmium::detail::typed_mmap<uint64_t>::file_size(fd));
-
- data[0] = 1ul;
- data[1] = 8ul;
- data[99] = 27ul;
-
- REQUIRE(1ul == data[0]);
- REQUIRE(8ul == data[1]);
- REQUIRE(27ul == data[99]);
-
- osmium::detail::typed_mmap<uint64_t>::unmap(data, size);
-
- REQUIRE(0 == close(fd));
- REQUIRE(0 == unlink(filename));
-}
-
-}
diff --git a/test/t/io/test_bzip2.cpp b/test/t/io/test_bzip2.cpp
index e6342e1..5cc30b4 100644
--- a/test/t/io/test_bzip2.cpp
+++ b/test/t/io/test_bzip2.cpp
@@ -9,25 +9,25 @@
TEST_CASE("Bzip2") {
-SECTION("read_compressed_file") {
- std::string input_file = with_data_dir("t/io/data_bzip2.txt.bz2");
-
- int fd = ::open(input_file.c_str(), O_RDONLY);
- REQUIRE(fd > 0);
-
- size_t size = 0;
- std::string all;
- {
- osmium::io::Bzip2Decompressor decomp(fd);
- for (std::string data = decomp.read(); !data.empty(); data = decomp.read()) {
- size += data.size();
- all += data;
+ SECTION("read_compressed_file") {
+ std::string input_file = with_data_dir("t/io/data_bzip2.txt.bz2");
+
+ int fd = ::open(input_file.c_str(), O_RDONLY);
+ REQUIRE(fd > 0);
+
+ size_t size = 0;
+ std::string all;
+ {
+ osmium::io::Bzip2Decompressor decomp(fd);
+ for (std::string data = decomp.read(); !data.empty(); data = decomp.read()) {
+ size += data.size();
+ all += data;
+ }
}
- }
- REQUIRE(9 == size);
- REQUIRE("TESTDATA\n" == all);
-}
+ REQUIRE(9 == size);
+ REQUIRE("TESTDATA\n" == all);
+ }
}
diff --git a/test/t/io/test_file_formats.cpp b/test/t/io/test_file_formats.cpp
index 03f9578..e8785d6 100644
--- a/test/t/io/test_file_formats.cpp
+++ b/test/t/io/test_file_formats.cpp
@@ -6,246 +6,246 @@
TEST_CASE("FileFormats") {
-SECTION("default_file_format") {
- osmium::io::File f;
- REQUIRE(osmium::io::file_format::unknown == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- REQUIRE_THROWS_AS(f.check(), std::runtime_error);
-}
-
-SECTION("stdin_stdout_empty") {
- osmium::io::File f {""};
- REQUIRE(osmium::io::file_format::unknown == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- REQUIRE_THROWS_AS(f.check(), std::runtime_error);
-}
-
-SECTION("stdin_stdout_dash") {
- osmium::io::File f {"-"};
- REQUIRE(osmium::io::file_format::unknown == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- REQUIRE_THROWS_AS(f.check(), std::runtime_error);
-}
-
-SECTION("stdin_stdout_bz2") {
- osmium::io::File f {"-", "osm.bz2"};
- REQUIRE("" == f.filename());
- REQUIRE(osmium::io::file_format::xml == f.format());
- REQUIRE(osmium::io::file_compression::bzip2 == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("detect_file_format_by_suffix_osm") {
- osmium::io::File f {"test.osm"};
- REQUIRE(osmium::io::file_format::xml == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("detect_file_format_by_suffix_pbf") {
- osmium::io::File f {"test.pbf"};
- REQUIRE(osmium::io::file_format::pbf == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("detect_file_format_by_suffix_osm_pbf") {
- osmium::io::File f {"test.osm.pbf"};
- REQUIRE(osmium::io::file_format::pbf == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("detect_file_format_by_suffix_opl") {
- osmium::io::File f {"test.opl"};
- REQUIRE(osmium::io::file_format::opl == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("detect_file_format_by_suffix_osm_opl") {
- osmium::io::File f {"test.osm.opl"};
- REQUIRE(osmium::io::file_format::opl == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("detect_file_format_by_suffix_osm_gz") {
- osmium::io::File f {"test.osm.gz"};
- REQUIRE(osmium::io::file_format::xml == f.format());
- REQUIRE(osmium::io::file_compression::gzip == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("detect_file_format_by_suffix_opl_bz2") {
- osmium::io::File f {"test.osm.opl.bz2"};
- REQUIRE(osmium::io::file_format::opl == f.format());
- REQUIRE(osmium::io::file_compression::bzip2 == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("detect_file_format_by_suffix_osc_gz") {
- osmium::io::File f {"test.osc.gz"};
- REQUIRE(osmium::io::file_format::xml == f.format());
- REQUIRE(osmium::io::file_compression::gzip == f.compression());
- REQUIRE(true == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("detect_file_format_by_suffix_opl_gz") {
- osmium::io::File f {"test.osh.opl.gz"};
- REQUIRE(osmium::io::file_format::opl == f.format());
- REQUIRE(osmium::io::file_compression::gzip == f.compression());
- REQUIRE(true == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("detect_file_format_by_suffix_osh_pbf") {
- osmium::io::File f {"test.osh.pbf"};
- REQUIRE(osmium::io::file_format::pbf == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(true == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("override_file_format_by_suffix_osm") {
- osmium::io::File f {"test", "osm"};
- REQUIRE(osmium::io::file_format::xml == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("override_file_format_by_suffix_pbf") {
- osmium::io::File f {"test", "pbf"};
- REQUIRE(osmium::io::file_format::pbf == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("override_file_format_by_suffix_osm_pbf") {
- osmium::io::File f {"test", "osm.pbf"};
- REQUIRE(osmium::io::file_format::pbf == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("override_file_format_by_suffix_opl") {
- osmium::io::File f {"test", "opl"};
- REQUIRE(osmium::io::file_format::opl == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("override_file_format_by_suffix_osm_opl") {
- osmium::io::File f {"test", "osm.opl"};
- REQUIRE(osmium::io::file_format::opl == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("override_file_format_by_suffix_osm_gz") {
- osmium::io::File f {"test", "osm.gz"};
- REQUIRE(osmium::io::file_format::xml == f.format());
- REQUIRE(osmium::io::file_compression::gzip == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("override_file_format_by_suffix_osm_opl_bz2") {
- osmium::io::File f {"test", "osm.opl.bz2"};
- REQUIRE(osmium::io::file_format::opl == f.format());
- REQUIRE(osmium::io::file_compression::bzip2 == f.compression());
- REQUIRE(false == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("override_file_format_by_suffix_osc_gz") {
- osmium::io::File f {"test", "osc.gz"};
- REQUIRE(osmium::io::file_format::xml == f.format());
- REQUIRE(osmium::io::file_compression::gzip == f.compression());
- REQUIRE(true == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("override_file_format_by_suffix_osh_opl_gz") {
- osmium::io::File f {"test", "osh.opl.gz"};
- REQUIRE(osmium::io::file_format::opl == f.format());
- REQUIRE(osmium::io::file_compression::gzip == f.compression());
- REQUIRE(true == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("override_file_format_by_suffix_osh_pbf") {
- osmium::io::File f {"test", "osh.pbf"};
- REQUIRE(osmium::io::file_format::pbf == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(true == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("format_options_pbf_history") {
- osmium::io::File f {"test", "pbf,history=true"};
- REQUIRE(osmium::io::file_format::pbf == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE(true == f.has_multiple_object_versions());
- f.check();
-}
-
-SECTION("format_options_pbf_foo") {
- osmium::io::File f {"test.osm", "pbf,foo=bar"};
- REQUIRE(osmium::io::file_format::pbf == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE("bar" == f.get("foo"));
- f.check();
-}
-
-SECTION("format_options_xml_abc_something") {
- osmium::io::File f {"test.bla", "xml,abc,some=thing"};
- REQUIRE(osmium::io::file_format::xml == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE("true" == f.get("abc"));
- REQUIRE("thing" == f.get("some"));
- REQUIRE(2 == std::distance(f.begin(), f.end()));
- f.check();
-}
-
-SECTION("unknown_format_foo_bar") {
- osmium::io::File f {"test.foo.bar"};
- REQUIRE(osmium::io::file_format::unknown == f.format());
- REQUIRE(osmium::io::file_compression::none == f.compression());
- REQUIRE_THROWS_AS(f.check(), std::runtime_error);
-}
-
-SECTION("unknown_format_foo") {
- osmium::io::File f {"test", "foo"};
- REQUIRE_THROWS_AS(f.check(), std::runtime_error);
-}
-
-SECTION("unknown_format_osm_foo") {
- osmium::io::File f {"test", "osm.foo"};
- REQUIRE_THROWS_AS(f.check(), std::runtime_error);
-}
-
-SECTION("unknown_format_bla_equals_foo") {
- osmium::io::File f {"test", "bla=foo"};
- REQUIRE_THROWS_AS(f.check(), std::runtime_error);
-}
+ SECTION("default_file_format") {
+ osmium::io::File f;
+ REQUIRE(osmium::io::file_format::unknown == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ REQUIRE_THROWS_AS(f.check(), std::runtime_error);
+ }
+
+ SECTION("stdin_stdout_empty") {
+ osmium::io::File f {""};
+ REQUIRE(osmium::io::file_format::unknown == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ REQUIRE_THROWS_AS(f.check(), std::runtime_error);
+ }
+
+ SECTION("stdin_stdout_dash") {
+ osmium::io::File f {"-"};
+ REQUIRE(osmium::io::file_format::unknown == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ REQUIRE_THROWS_AS(f.check(), std::runtime_error);
+ }
+
+ SECTION("stdin_stdout_bz2") {
+ osmium::io::File f {"-", "osm.bz2"};
+ REQUIRE("" == f.filename());
+ REQUIRE(osmium::io::file_format::xml == f.format());
+ REQUIRE(osmium::io::file_compression::bzip2 == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("detect_file_format_by_suffix_osm") {
+ osmium::io::File f {"test.osm"};
+ REQUIRE(osmium::io::file_format::xml == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("detect_file_format_by_suffix_pbf") {
+ osmium::io::File f {"test.pbf"};
+ REQUIRE(osmium::io::file_format::pbf == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("detect_file_format_by_suffix_osm_pbf") {
+ osmium::io::File f {"test.osm.pbf"};
+ REQUIRE(osmium::io::file_format::pbf == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("detect_file_format_by_suffix_opl") {
+ osmium::io::File f {"test.opl"};
+ REQUIRE(osmium::io::file_format::opl == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("detect_file_format_by_suffix_osm_opl") {
+ osmium::io::File f {"test.osm.opl"};
+ REQUIRE(osmium::io::file_format::opl == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("detect_file_format_by_suffix_osm_gz") {
+ osmium::io::File f {"test.osm.gz"};
+ REQUIRE(osmium::io::file_format::xml == f.format());
+ REQUIRE(osmium::io::file_compression::gzip == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("detect_file_format_by_suffix_opl_bz2") {
+ osmium::io::File f {"test.osm.opl.bz2"};
+ REQUIRE(osmium::io::file_format::opl == f.format());
+ REQUIRE(osmium::io::file_compression::bzip2 == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("detect_file_format_by_suffix_osc_gz") {
+ osmium::io::File f {"test.osc.gz"};
+ REQUIRE(osmium::io::file_format::xml == f.format());
+ REQUIRE(osmium::io::file_compression::gzip == f.compression());
+ REQUIRE(true == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("detect_file_format_by_suffix_opl_gz") {
+ osmium::io::File f {"test.osh.opl.gz"};
+ REQUIRE(osmium::io::file_format::opl == f.format());
+ REQUIRE(osmium::io::file_compression::gzip == f.compression());
+ REQUIRE(true == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("detect_file_format_by_suffix_osh_pbf") {
+ osmium::io::File f {"test.osh.pbf"};
+ REQUIRE(osmium::io::file_format::pbf == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(true == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("override_file_format_by_suffix_osm") {
+ osmium::io::File f {"test", "osm"};
+ REQUIRE(osmium::io::file_format::xml == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("override_file_format_by_suffix_pbf") {
+ osmium::io::File f {"test", "pbf"};
+ REQUIRE(osmium::io::file_format::pbf == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("override_file_format_by_suffix_osm_pbf") {
+ osmium::io::File f {"test", "osm.pbf"};
+ REQUIRE(osmium::io::file_format::pbf == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("override_file_format_by_suffix_opl") {
+ osmium::io::File f {"test", "opl"};
+ REQUIRE(osmium::io::file_format::opl == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("override_file_format_by_suffix_osm_opl") {
+ osmium::io::File f {"test", "osm.opl"};
+ REQUIRE(osmium::io::file_format::opl == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("override_file_format_by_suffix_osm_gz") {
+ osmium::io::File f {"test", "osm.gz"};
+ REQUIRE(osmium::io::file_format::xml == f.format());
+ REQUIRE(osmium::io::file_compression::gzip == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("override_file_format_by_suffix_osm_opl_bz2") {
+ osmium::io::File f {"test", "osm.opl.bz2"};
+ REQUIRE(osmium::io::file_format::opl == f.format());
+ REQUIRE(osmium::io::file_compression::bzip2 == f.compression());
+ REQUIRE(false == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("override_file_format_by_suffix_osc_gz") {
+ osmium::io::File f {"test", "osc.gz"};
+ REQUIRE(osmium::io::file_format::xml == f.format());
+ REQUIRE(osmium::io::file_compression::gzip == f.compression());
+ REQUIRE(true == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("override_file_format_by_suffix_osh_opl_gz") {
+ osmium::io::File f {"test", "osh.opl.gz"};
+ REQUIRE(osmium::io::file_format::opl == f.format());
+ REQUIRE(osmium::io::file_compression::gzip == f.compression());
+ REQUIRE(true == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("override_file_format_by_suffix_osh_pbf") {
+ osmium::io::File f {"test", "osh.pbf"};
+ REQUIRE(osmium::io::file_format::pbf == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(true == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("format_options_pbf_history") {
+ osmium::io::File f {"test", "pbf,history=true"};
+ REQUIRE(osmium::io::file_format::pbf == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE(true == f.has_multiple_object_versions());
+ f.check();
+ }
+
+ SECTION("format_options_pbf_foo") {
+ osmium::io::File f {"test.osm", "pbf,foo=bar"};
+ REQUIRE(osmium::io::file_format::pbf == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE("bar" == f.get("foo"));
+ f.check();
+ }
+
+ SECTION("format_options_xml_abc_something") {
+ osmium::io::File f {"test.bla", "xml,abc,some=thing"};
+ REQUIRE(osmium::io::file_format::xml == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE("true" == f.get("abc"));
+ REQUIRE("thing" == f.get("some"));
+ REQUIRE(2 == std::distance(f.begin(), f.end()));
+ f.check();
+ }
+
+ SECTION("unknown_format_foo_bar") {
+ osmium::io::File f {"test.foo.bar"};
+ REQUIRE(osmium::io::file_format::unknown == f.format());
+ REQUIRE(osmium::io::file_compression::none == f.compression());
+ REQUIRE_THROWS_AS(f.check(), std::runtime_error);
+ }
+
+ SECTION("unknown_format_foo") {
+ osmium::io::File f {"test", "foo"};
+ REQUIRE_THROWS_AS(f.check(), std::runtime_error);
+ }
+
+ SECTION("unknown_format_osm_foo") {
+ osmium::io::File f {"test", "osm.foo"};
+ REQUIRE_THROWS_AS(f.check(), std::runtime_error);
+ }
+
+ SECTION("unknown_format_bla_equals_foo") {
+ osmium::io::File f {"test", "bla=foo"};
+ REQUIRE_THROWS_AS(f.check(), std::runtime_error);
+ }
}
diff --git a/test/t/tags/test_filter.cpp b/test/t/tags/test_filter.cpp
index e65f63d..eefa5b0 100644
--- a/test/t/tags/test_filter.cpp
+++ b/test/t/tags/test_filter.cpp
@@ -25,192 +25,192 @@ void check_filter(const osmium::TagList& tag_list, const TFilter filter, const s
TEST_CASE("Filter") {
-SECTION("KeyFilter_matches_some_tags") {
- osmium::tags::KeyFilter filter(false);
- filter.add(true, "highway").add(true, "railway");
+ SECTION("KeyFilter_matches_some_tags") {
+ osmium::tags::KeyFilter filter(false);
+ filter.add(true, "highway").add(true, "railway");
- osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" }, // match
- { "name", "Main Street" }, // no match
- { "source", "GPS" } // no match
- });
+ osmium::memory::Buffer buffer(10240);
+ const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" }, // match
+ { "name", "Main Street" }, // no match
+ { "source", "GPS" } // no match
+ });
- std::vector<bool> results = { true, false, false };
+ std::vector<bool> results = { true, false, false };
- check_filter(tag_list, filter, results);
-}
+ check_filter(tag_list, filter, results);
+ }
-SECTION("KeyFilter_iterator_filters_tags") {
- osmium::tags::KeyFilter filter(false);
- filter.add(true, "highway").add(true, "source");
-
- osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tl = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" }, // match
- { "name", "Main Street" }, // no match
- { "source", "GPS" } // no match
- });
-
- osmium::tags::KeyFilter::iterator it(filter, tl.begin(), tl.end());
- const osmium::tags::KeyFilter::iterator end(filter, tl.end(), tl.end());
-
- REQUIRE(2 == std::distance(it, end));
-
- REQUIRE(it != end);
- REQUIRE(std::string("highway") == it->key());
- REQUIRE(std::string("primary") == it->value());
- ++it;
- REQUIRE(std::string("source") == it->key());
- REQUIRE(std::string("GPS") == it->value());
- REQUIRE(++it == end);
-}
+ SECTION("KeyFilter_iterator_filters_tags") {
+ osmium::tags::KeyFilter filter(false);
+ filter.add(true, "highway").add(true, "source");
+
+ osmium::memory::Buffer buffer(10240);
+ const osmium::TagList& tl = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" }, // match
+ { "name", "Main Street" }, // no match
+ { "source", "GPS" } // no match
+ });
+
+ osmium::tags::KeyFilter::iterator it(filter, tl.begin(), tl.end());
+ const osmium::tags::KeyFilter::iterator end(filter, tl.end(), tl.end());
+
+ REQUIRE(2 == std::distance(it, end));
+
+ REQUIRE(it != end);
+ REQUIRE(std::string("highway") == it->key());
+ REQUIRE(std::string("primary") == it->value());
+ ++it;
+ REQUIRE(std::string("source") == it->key());
+ REQUIRE(std::string("GPS") == it->value());
+ REQUIRE(++it == end);
+ }
-SECTION("KeyValueFilter_matches_some_tags") {
- osmium::tags::KeyValueFilter filter(false);
+ SECTION("KeyValueFilter_matches_some_tags") {
+ osmium::tags::KeyValueFilter filter(false);
- filter.add(true, "highway", "residential").add(true, "highway", "primary").add(true, "railway");
+ filter.add(true, "highway", "residential").add(true, "highway", "primary").add(true, "railway");
- osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" },
- { "railway", "tram" },
- { "source", "GPS" }
- });
+ osmium::memory::Buffer buffer(10240);
+ const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" },
+ { "railway", "tram" },
+ { "source", "GPS" }
+ });
- std::vector<bool> results = {true, true, false};
+ std::vector<bool> results = {true, true, false};
- check_filter(tag_list, filter, results);
-}
+ check_filter(tag_list, filter, results);
+ }
-SECTION("KeyValueFilter_ordering_matters") {
- osmium::tags::KeyValueFilter filter1(false);
- filter1.add(true, "highway").add(false, "highway", "road");
+ SECTION("KeyValueFilter_ordering_matters") {
+ osmium::tags::KeyValueFilter filter1(false);
+ filter1.add(true, "highway").add(false, "highway", "road");
- osmium::tags::KeyValueFilter filter2(false);
- filter2.add(false, "highway", "road").add(true, "highway");
+ osmium::tags::KeyValueFilter filter2(false);
+ filter2.add(false, "highway", "road").add(true, "highway");
- osmium::memory::Buffer buffer(10240);
+ osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tag_list1 = osmium::builder::build_tag_list(buffer, {
- { "highway", "road" },
- { "name", "Main Street" }
- });
+ const osmium::TagList& tag_list1 = osmium::builder::build_tag_list(buffer, {
+ { "highway", "road" },
+ { "name", "Main Street" }
+ });
- const osmium::TagList& tag_list2 = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" },
- { "name", "Main Street" }
- });
+ const osmium::TagList& tag_list2 = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" },
+ { "name", "Main Street" }
+ });
- check_filter(tag_list1, filter1, {true, false});
- check_filter(tag_list1, filter2, {false, false});
- check_filter(tag_list2, filter2, {true, false});
-}
+ check_filter(tag_list1, filter1, {true, false});
+ check_filter(tag_list1, filter2, {false, false});
+ check_filter(tag_list2, filter2, {true, false});
+ }
-SECTION("KeyValueFilter_matches_against_taglist_with_any") {
- osmium::tags::KeyValueFilter filter(false);
+ SECTION("KeyValueFilter_matches_against_taglist_with_any") {
+ osmium::tags::KeyValueFilter filter(false);
- filter.add(true, "highway", "primary").add(true, "name");
+ filter.add(true, "highway", "primary").add(true, "name");
- osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" },
- { "railway", "tram" },
- { "source", "GPS" }
- });
+ osmium::memory::Buffer buffer(10240);
+ const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" },
+ { "railway", "tram" },
+ { "source", "GPS" }
+ });
- REQUIRE( osmium::tags::match_any_of(tag_list, filter));
- REQUIRE(!osmium::tags::match_all_of(tag_list, filter));
- REQUIRE(!osmium::tags::match_none_of(tag_list, filter));
-}
+ REQUIRE( osmium::tags::match_any_of(tag_list, filter));
+ REQUIRE(!osmium::tags::match_all_of(tag_list, filter));
+ REQUIRE(!osmium::tags::match_none_of(tag_list, filter));
+ }
-SECTION("KeyValueFilter_matches_against_taglist_with_all") {
- osmium::tags::KeyValueFilter filter(false);
+ SECTION("KeyValueFilter_matches_against_taglist_with_all") {
+ osmium::tags::KeyValueFilter filter(false);
- filter.add(true, "highway", "primary").add(true, "name");
+ filter.add(true, "highway", "primary").add(true, "name");
- osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" },
- { "name", "Main Street" }
- });
+ osmium::memory::Buffer buffer(10240);
+ const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" },
+ { "name", "Main Street" }
+ });
- REQUIRE( osmium::tags::match_any_of(tag_list, filter));
- REQUIRE( osmium::tags::match_all_of(tag_list, filter));
- REQUIRE(!osmium::tags::match_none_of(tag_list, filter));
-}
+ REQUIRE( osmium::tags::match_any_of(tag_list, filter));
+ REQUIRE( osmium::tags::match_all_of(tag_list, filter));
+ REQUIRE(!osmium::tags::match_none_of(tag_list, filter));
+ }
-SECTION("KeyValueFilter_matches_against_taglist_with_none") {
- osmium::tags::KeyValueFilter filter(false);
+ SECTION("KeyValueFilter_matches_against_taglist_with_none") {
+ osmium::tags::KeyValueFilter filter(false);
- filter.add(true, "highway", "road").add(true, "source");
+ filter.add(true, "highway", "road").add(true, "source");
- osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" },
- { "name", "Main Street" }
- });
+ osmium::memory::Buffer buffer(10240);
+ const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" },
+ { "name", "Main Street" }
+ });
- REQUIRE(!osmium::tags::match_any_of(tag_list, filter));
- REQUIRE(!osmium::tags::match_all_of(tag_list, filter));
- REQUIRE( osmium::tags::match_none_of(tag_list, filter));
-}
+ REQUIRE(!osmium::tags::match_any_of(tag_list, filter));
+ REQUIRE(!osmium::tags::match_all_of(tag_list, filter));
+ REQUIRE( osmium::tags::match_none_of(tag_list, filter));
+ }
-SECTION("KeyValueFilter_matches_against_taglist_with_any_called_with_rvalue") {
- osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" },
- { "railway", "tram" },
- { "source", "GPS" }
- });
+ SECTION("KeyValueFilter_matches_against_taglist_with_any_called_with_rvalue") {
+ osmium::memory::Buffer buffer(10240);
+ const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" },
+ { "railway", "tram" },
+ { "source", "GPS" }
+ });
- REQUIRE(osmium::tags::match_any_of(tag_list,
- osmium::tags::KeyValueFilter().add(true, "highway", "primary").add(true, "name")));
-}
+ REQUIRE(osmium::tags::match_any_of(tag_list,
+ osmium::tags::KeyValueFilter().add(true, "highway", "primary").add(true, "name")));
+ }
-SECTION("RegexFilter_matches_some_tags") {
- osmium::tags::RegexFilter filter(false);
- filter.add(true, "highway", std::regex(".*_link"));
-
- osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tag_list1 = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary_link" },
- { "source", "GPS" }
- });
- const osmium::TagList& tag_list2 = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" },
- { "source", "GPS" }
- });
-
- check_filter(tag_list1, filter, {true, false});
- check_filter(tag_list2, filter, {false, false});
-}
+ SECTION("RegexFilter_matches_some_tags") {
+ osmium::tags::RegexFilter filter(false);
+ filter.add(true, "highway", std::regex(".*_link"));
+
+ osmium::memory::Buffer buffer(10240);
+ const osmium::TagList& tag_list1 = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary_link" },
+ { "source", "GPS" }
+ });
+ const osmium::TagList& tag_list2 = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" },
+ { "source", "GPS" }
+ });
+
+ check_filter(tag_list1, filter, {true, false});
+ check_filter(tag_list2, filter, {false, false});
+ }
-SECTION("RegexFilter_matches_some_tags_with_lvalue_regex") {
- osmium::tags::RegexFilter filter(false);
- std::regex r(".*straße");
- filter.add(true, "name", r);
+ SECTION("RegexFilter_matches_some_tags_with_lvalue_regex") {
+ osmium::tags::RegexFilter filter(false);
+ std::regex r(".*straße");
+ filter.add(true, "name", r);
- osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" },
- { "name", "Hauptstraße" }
- });
+ osmium::memory::Buffer buffer(10240);
+ const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" },
+ { "name", "Hauptstraße" }
+ });
- check_filter(tag_list, filter, {false, true});
-}
+ check_filter(tag_list, filter, {false, true});
+ }
-SECTION("KeyPrefixFilter_matches_some_tags") {
- osmium::tags::KeyPrefixFilter filter(false);
- filter.add(true, "name:");
+ SECTION("KeyPrefixFilter_matches_some_tags") {
+ osmium::tags::KeyPrefixFilter filter(false);
+ filter.add(true, "name:");
- osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" },
- { "name:de", "Hauptstraße" }
- });
+ osmium::memory::Buffer buffer(10240);
+ const osmium::TagList& tag_list = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" },
+ { "name:de", "Hauptstraße" }
+ });
- check_filter(tag_list, filter, {false, true});
-}
+ check_filter(tag_list, filter, {false, true});
+ }
}
diff --git a/test/t/tags/test_operators.cpp b/test/t/tags/test_operators.cpp
index e2c22a4..33a53c2 100644
--- a/test/t/tags/test_operators.cpp
+++ b/test/t/tags/test_operators.cpp
@@ -8,54 +8,54 @@
TEST_CASE("Operators") {
-SECTION("Equal") {
- osmium::memory::Buffer buffer1(10240);
- {
- osmium::builder::TagListBuilder tl_builder(buffer1);
- tl_builder.add_tag("highway", "primary");
- tl_builder.add_tag("name", "Main Street");
- tl_builder.add_tag("source", "GPS");
+ SECTION("Equal") {
+ osmium::memory::Buffer buffer1(10240);
+ {
+ osmium::builder::TagListBuilder tl_builder(buffer1);
+ tl_builder.add_tag("highway", "primary");
+ tl_builder.add_tag("name", "Main Street");
+ tl_builder.add_tag("source", "GPS");
+ }
+ buffer1.commit();
+
+ osmium::memory::Buffer buffer2(10240);
+ {
+ osmium::builder::TagListBuilder tl_builder(buffer2);
+ tl_builder.add_tag("highway", "primary");
+ }
+ buffer2.commit();
+
+ const osmium::TagList& tl1 = buffer1.get<const osmium::TagList>(0);
+ const osmium::TagList& tl2 = buffer2.get<const osmium::TagList>(0);
+
+ auto tagit1 = tl1.begin();
+ auto tagit2 = tl2.begin();
+ REQUIRE(*tagit1 == *tagit2);
+ ++tagit1;
+ REQUIRE(!(*tagit1 == *tagit2));
}
- buffer1.commit();
- osmium::memory::Buffer buffer2(10240);
- {
- osmium::builder::TagListBuilder tl_builder(buffer2);
- tl_builder.add_tag("highway", "primary");
+ SECTION("Order") {
+ osmium::memory::Buffer buffer(10240);
+ {
+ osmium::builder::TagListBuilder tl_builder(buffer);
+ tl_builder.add_tag("highway", "residential");
+ tl_builder.add_tag("highway", "primary");
+ tl_builder.add_tag("name", "Main Street");
+ tl_builder.add_tag("amenity", "post_box");
+ }
+ buffer.commit();
+
+ const osmium::TagList& tl = buffer.get<const osmium::TagList>(0);
+ const osmium::Tag& t1 = *(tl.begin());
+ const osmium::Tag& t2 = *(std::next(tl.begin(), 1));
+ const osmium::Tag& t3 = *(std::next(tl.begin(), 2));
+ const osmium::Tag& t4 = *(std::next(tl.begin(), 3));
+
+ REQUIRE(t2 < t1);
+ REQUIRE(t1 < t3);
+ REQUIRE(t2 < t3);
+ REQUIRE(t4 < t1);
}
- buffer2.commit();
-
- const osmium::TagList& tl1 = buffer1.get<const osmium::TagList>(0);
- const osmium::TagList& tl2 = buffer2.get<const osmium::TagList>(0);
-
- auto tagit1 = tl1.begin();
- auto tagit2 = tl2.begin();
- REQUIRE(*tagit1 == *tagit2);
- ++tagit1;
- REQUIRE(!(*tagit1 == *tagit2));
-}
-
-SECTION("Order") {
- osmium::memory::Buffer buffer(10240);
- {
- osmium::builder::TagListBuilder tl_builder(buffer);
- tl_builder.add_tag("highway", "residential");
- tl_builder.add_tag("highway", "primary");
- tl_builder.add_tag("name", "Main Street");
- tl_builder.add_tag("amenity", "post_box");
- }
- buffer.commit();
-
- const osmium::TagList& tl = buffer.get<const osmium::TagList>(0);
- const osmium::Tag& t1 = *(tl.begin());
- const osmium::Tag& t2 = *(std::next(tl.begin(), 1));
- const osmium::Tag& t3 = *(std::next(tl.begin(), 2));
- const osmium::Tag& t4 = *(std::next(tl.begin(), 3));
-
- REQUIRE(t2 < t1);
- REQUIRE(t1 < t3);
- REQUIRE(t2 < t3);
- REQUIRE(t4 < t1);
-}
}
diff --git a/test/t/tags/test_tag_list.cpp b/test/t/tags/test_tag_list.cpp
index b25d8ca..c2512d1 100644
--- a/test/t/tags/test_tag_list.cpp
+++ b/test/t/tags/test_tag_list.cpp
@@ -6,71 +6,71 @@
TEST_CASE("tag_list") {
-SECTION("can_be_created_from_initializer_list") {
- osmium::memory::Buffer buffer(10240);
-
- const osmium::TagList& tl = osmium::builder::build_tag_list(buffer, {
- { "highway", "primary" },
- { "name", "Main Street" },
- { "source", "GPS" }
- });
-
- REQUIRE(osmium::item_type::tag_list == tl.type());
- REQUIRE(3 == tl.size());
- REQUIRE(std::string("highway") == tl.begin()->key());
- REQUIRE(std::string("primary") == tl.begin()->value());
-}
-
-SECTION("can_be_created_from_map") {
- osmium::memory::Buffer buffer(10240);
-
- const osmium::TagList& tl = osmium::builder::build_tag_list_from_map(buffer, std::map<const char*, const char*>({
- { "highway", "primary" },
- { "name", "Main Street" }
- }));
-
- REQUIRE(osmium::item_type::tag_list == tl.type());
- REQUIRE(2 == tl.size());
-
- if (std::string("highway") == tl.begin()->key()) {
+ SECTION("can_be_created_from_initializer_list") {
+ osmium::memory::Buffer buffer(10240);
+
+ const osmium::TagList& tl = osmium::builder::build_tag_list(buffer, {
+ { "highway", "primary" },
+ { "name", "Main Street" },
+ { "source", "GPS" }
+ });
+
+ REQUIRE(osmium::item_type::tag_list == tl.type());
+ REQUIRE(3 == tl.size());
+ REQUIRE(std::string("highway") == tl.begin()->key());
REQUIRE(std::string("primary") == tl.begin()->value());
- REQUIRE(std::string("name") == std::next(tl.begin(), 1)->key());
- REQUIRE(std::string("Main Street") == std::next(tl.begin(), 1)->value());
- } else {
- REQUIRE(std::string("highway") == std::next(tl.begin(), 1)->key());
- REQUIRE(std::string("primary") == std::next(tl.begin(), 1)->value());
- REQUIRE(std::string("name") == tl.begin()->key());
- REQUIRE(std::string("Main Street") == tl.begin()->value());
}
-}
-SECTION("can_be_created_with_callback") {
- osmium::memory::Buffer buffer(10240);
+ SECTION("can_be_created_from_map") {
+ osmium::memory::Buffer buffer(10240);
+
+ const osmium::TagList& tl = osmium::builder::build_tag_list_from_map(buffer, std::map<const char*, const char*>({
+ { "highway", "primary" },
+ { "name", "Main Street" }
+ }));
+
+ REQUIRE(osmium::item_type::tag_list == tl.type());
+ REQUIRE(2 == tl.size());
+
+ if (std::string("highway") == tl.begin()->key()) {
+ REQUIRE(std::string("primary") == tl.begin()->value());
+ REQUIRE(std::string("name") == std::next(tl.begin(), 1)->key());
+ REQUIRE(std::string("Main Street") == std::next(tl.begin(), 1)->value());
+ } else {
+ REQUIRE(std::string("highway") == std::next(tl.begin(), 1)->key());
+ REQUIRE(std::string("primary") == std::next(tl.begin(), 1)->value());
+ REQUIRE(std::string("name") == tl.begin()->key());
+ REQUIRE(std::string("Main Street") == tl.begin()->value());
+ }
+ }
- const osmium::TagList& tl = osmium::builder::build_tag_list_from_func(buffer, [](osmium::builder::TagListBuilder& tlb) {
- tlb.add_tag("highway", "primary");
- tlb.add_tag("bridge", "true");
- });
+ SECTION("can_be_created_with_callback") {
+ osmium::memory::Buffer buffer(10240);
- REQUIRE(osmium::item_type::tag_list == tl.type());
- REQUIRE(2 == tl.size());
- REQUIRE(std::string("bridge") == std::next(tl.begin(), 1)->key());
- REQUIRE(std::string("true") == std::next(tl.begin(), 1)->value());
-}
+ const osmium::TagList& tl = osmium::builder::build_tag_list_from_func(buffer, [](osmium::builder::TagListBuilder& tlb) {
+ tlb.add_tag("highway", "primary");
+ tlb.add_tag("bridge", "true");
+ });
+
+ REQUIRE(osmium::item_type::tag_list == tl.type());
+ REQUIRE(2 == tl.size());
+ REQUIRE(std::string("bridge") == std::next(tl.begin(), 1)->key());
+ REQUIRE(std::string("true") == std::next(tl.begin(), 1)->value());
+ }
-SECTION("returns_value_by_key") {
- osmium::memory::Buffer buffer(10240);
+ SECTION("returns_value_by_key") {
+ osmium::memory::Buffer buffer(10240);
- const osmium::TagList& tl = osmium::builder::build_tag_list_from_func(buffer, [](osmium::builder::TagListBuilder& tlb) {
- tlb.add_tag("highway", "primary");
- tlb.add_tag("bridge", "true");
- });
+ const osmium::TagList& tl = osmium::builder::build_tag_list_from_func(buffer, [](osmium::builder::TagListBuilder& tlb) {
+ tlb.add_tag("highway", "primary");
+ tlb.add_tag("bridge", "true");
+ });
- REQUIRE(std::string("primary") == tl.get_value_by_key("highway"));
- REQUIRE(nullptr == tl.get_value_by_key("name"));
- REQUIRE(std::string("foo") == tl.get_value_by_key("name", "foo"));
+ REQUIRE(std::string("primary") == tl.get_value_by_key("highway"));
+ REQUIRE(nullptr == tl.get_value_by_key("name"));
+ REQUIRE(std::string("foo") == tl.get_value_by_key("name", "foo"));
- REQUIRE(std::string("true") == tl["bridge"]);
-}
+ REQUIRE(std::string("true") == tl["bridge"]);
+ }
}
diff --git a/test/t/thread/test_pool.cpp b/test/t/thread/test_pool.cpp
index 4bbf9ee..5fa6bba 100644
--- a/test/t/thread/test_pool.cpp
+++ b/test/t/thread/test_pool.cpp
@@ -36,7 +36,7 @@ TEST_CASE("thread") {
SECTION("can send job to thread pool") {
auto& pool = osmium::thread::Pool::instance();
result = 0;
- auto future = pool.submit(test_job_ok{});
+ auto future = pool.submit(test_job_ok {});
// wait a bit for the other thread to get a chance to run
std::this_thread::sleep_for(std::chrono::milliseconds(1));
@@ -50,7 +50,7 @@ TEST_CASE("thread") {
SECTION("can send job to thread pool") {
auto& pool = osmium::thread::Pool::instance();
- auto future = pool.submit(test_job_with_result{});
+ auto future = pool.submit(test_job_with_result {});
REQUIRE(future.get() == 42);
}
@@ -59,8 +59,7 @@ TEST_CASE("thread") {
auto& pool = osmium::thread::Pool::instance();
result = 0;
- bool got_exception = false;
- auto future = pool.submit(test_job_throw{});
+ auto future = pool.submit(test_job_throw {});
REQUIRE_THROWS_AS(future.get(), std::runtime_error);
}
diff --git a/test/t/util/test_data_file.cpp b/test/t/util/test_data_file.cpp
new file mode 100644
index 0000000..3f432f9
--- /dev/null
+++ b/test/t/util/test_data_file.cpp
@@ -0,0 +1,81 @@
+#include "catch.hpp"
+
+#include <cstring>
+
+#include <osmium/util/data_file.hpp>
+
+TEST_CASE("temporary file") {
+
+ SECTION("create/open") {
+ osmium::util::DataFile file;
+
+ REQUIRE(!!file);
+ int fd = file.fd();
+
+ REQUIRE(fd > 0);
+
+ const char buf[] = "foobar";
+ REQUIRE(::write(fd, buf, sizeof(buf)) == sizeof(buf));
+
+ file.close();
+
+ REQUIRE(!file);
+ }
+
+}
+
+TEST_CASE("named file") {
+
+ SECTION("create/open") {
+ {
+ osmium::util::DataFile file("test.data", true);
+
+ REQUIRE(!!file);
+ int fd = file.fd();
+
+ REQUIRE(fd > 0);
+
+ REQUIRE(file.size() == 0);
+
+ const char buf[] = "foobar";
+ REQUIRE(::write(fd, buf, sizeof(buf) - 1) == sizeof(buf) - 1);
+
+ file.close();
+
+ REQUIRE(!file);
+ }
+ {
+ osmium::util::DataFile file("test.data", false);
+
+ REQUIRE(!!file);
+ int fd = file.fd();
+
+ REQUIRE(fd > 0);
+
+ REQUIRE(file.size() == 6);
+
+ char buf[10];
+ int len = ::read(fd, buf, sizeof(buf));
+
+ REQUIRE(len == 6);
+ REQUIRE(!strncmp(buf, "foobar", 6));
+
+ file.close();
+
+ REQUIRE(!file);
+ REQUIRE(unlink("test.data") == 0);
+ }
+ }
+
+ SECTION("grow file") {
+ osmium::util::DataFile file("test.data", true);
+
+ REQUIRE(!!file);
+
+ REQUIRE(file.size() == 0);
+ file.grow(10);
+ REQUIRE(file.size() == 10);
+ }
+
+}
+
diff --git a/test/t/util/test_delta.cpp b/test/t/util/test_delta.cpp
new file mode 100644
index 0000000..a698204
--- /dev/null
+++ b/test/t/util/test_delta.cpp
@@ -0,0 +1,44 @@
+#include "catch.hpp"
+
+#include <osmium/util/delta.hpp>
+
+TEST_CASE("delta encode") {
+
+ osmium::util::DeltaEncode<int> x;
+
+ SECTION("int") {
+ REQUIRE(x.update(17) == 17);
+ REQUIRE(x.update(10) == -7);
+ }
+
+}
+
+TEST_CASE("delta decode") {
+
+ osmium::util::DeltaDecode<int> x;
+
+ SECTION("int") {
+ REQUIRE(x.update(17) == 17);
+ REQUIRE(x.update(10) == 27);
+ }
+
+}
+
+TEST_CASE("delta encode and decode") {
+
+ std::vector<int> a = { 5, -9, 22, 13, 0, 23 };
+
+ osmium::util::DeltaEncode<int> de;
+ std::vector<int> b;
+ for (int x : a) {
+ b.push_back(de.update(x));
+ }
+
+ osmium::util::DeltaDecode<int> dd;
+ std::vector<int> c;
+ for (int x : b) {
+ c.push_back(dd.update(x));
+ }
+
+}
+
diff --git a/test/t/util/test_double.cpp b/test/t/util/test_double.cpp
index 79e8509..6cc87a0 100644
--- a/test/t/util/test_double.cpp
+++ b/test/t/util/test_double.cpp
@@ -4,30 +4,30 @@
TEST_CASE("Double") {
-SECTION("double2string") {
- std::string s1;
- osmium::util::double2string(s1, 1.123, 7);
- REQUIRE(s1 == "1.123");
-
- std::string s2;
- osmium::util::double2string(s2, 1.000, 7);
- REQUIRE(s2 == "1");
-
- std::string s3;
- osmium::util::double2string(s3, 0.0, 7);
- REQUIRE(s3 == "0");
-
- std::string s4;
- osmium::util::double2string(s4, 0.020, 7);
- REQUIRE(s4 == "0.02");
-
- std::string s5;
- osmium::util::double2string(s5, -0.020, 7);
- REQUIRE(s5 == "-0.02");
-
- std::string s6;
- osmium::util::double2string(s6, -0.0, 7);
- REQUIRE(s6 == "-0");
-}
+ SECTION("double2string") {
+ std::string s1;
+ osmium::util::double2string(s1, 1.123, 7);
+ REQUIRE(s1 == "1.123");
+
+ std::string s2;
+ osmium::util::double2string(s2, 1.000, 7);
+ REQUIRE(s2 == "1");
+
+ std::string s3;
+ osmium::util::double2string(s3, 0.0, 7);
+ REQUIRE(s3 == "0");
+
+ std::string s4;
+ osmium::util::double2string(s4, 0.020, 7);
+ REQUIRE(s4 == "0.02");
+
+ std::string s5;
+ osmium::util::double2string(s5, -0.020, 7);
+ REQUIRE(s5 == "-0.02");
+
+ std::string s6;
+ osmium::util::double2string(s6, -0.0, 7);
+ REQUIRE(s6 == "-0");
+ }
}
diff --git a/test/t/util/test_file.cpp b/test/t/util/test_file.cpp
new file mode 100644
index 0000000..2787261
--- /dev/null
+++ b/test/t/util/test_file.cpp
@@ -0,0 +1,69 @@
+#include "catch.hpp"
+
+#include <osmium/util/file.hpp>
+
+#ifdef _WIN32
+// https://msdn.microsoft.com/en-us/library/ksazx244.aspx
+// https://msdn.microsoft.com/en-us/library/a9yf33zb.aspx
+class DoNothingInvalidParameterHandler {
+
+ static void invalid_parameter_handler(
+ const wchar_t* expression,
+ const wchar_t* function,
+ const wchar_t* file,
+ unsigned int line,
+ uintptr_t pReserved
+ ) {
+ // do nothing
+ }
+
+ _invalid_parameter_handler old_handler;
+
+public:
+
+ DoNothingInvalidParameterHandler() :
+ old_handler(_set_invalid_parameter_handler(invalid_parameter_handler)) {
+ }
+
+ ~DoNothingInvalidParameterHandler() {
+ _set_invalid_parameter_handler(old_handler);
+ }
+
+}; // class InvalidParameterHandler
+#endif
+
+
+TEST_CASE("file_size") {
+
+#ifdef _WIN32
+ DoNothingInvalidParameterHandler handler;
+#endif
+
+ SECTION("illegal fd should throw") {
+ REQUIRE_THROWS_AS(osmium::util::file_size(-1), std::system_error);
+ }
+
+ SECTION("unused fd should throw") {
+ // its unlikely that fd 1000 is open...
+ REQUIRE_THROWS_AS(osmium::util::file_size(1000), std::system_error);
+ }
+
+}
+
+TEST_CASE("resize_file") {
+
+#ifdef _WIN32
+ DoNothingInvalidParameterHandler handler;
+#endif
+
+ SECTION("illegal fd should throw") {
+ REQUIRE_THROWS_AS(osmium::util::resize_file(-1, 10), std::system_error);
+ }
+
+ SECTION("unused fd should throw") {
+ // its unlikely that fd 1000 is open...
+ REQUIRE_THROWS_AS(osmium::util::resize_file(1000, 10), std::system_error);
+ }
+
+}
+
diff --git a/test/t/util/test_memory_mapping.cpp b/test/t/util/test_memory_mapping.cpp
new file mode 100644
index 0000000..7f95405
--- /dev/null
+++ b/test/t/util/test_memory_mapping.cpp
@@ -0,0 +1,393 @@
+#include "catch.hpp"
+
+#include <sys/types.h>
+#include <limits>
+
+#include <osmium/util/file.hpp>
+#include <osmium/util/memory_mapping.hpp>
+
+#if defined(_MSC_VER) || (defined(__GNUC__) && defined(_WIN32))
+#include "win_mkstemp.hpp"
+#endif
+
+static const size_t huge = std::numeric_limits<size_t>::max();
+
+TEST_CASE("anonymous mapping") {
+
+ SECTION("simple memory mapping should work") {
+ osmium::util::MemoryMapping mapping(1000);
+ REQUIRE(mapping.get_addr() != nullptr);
+
+ REQUIRE(mapping.size() >= 1000);
+
+ volatile int* addr = mapping.get_addr<int>();
+
+ REQUIRE(mapping.writable());
+
+ *addr = 42;
+ REQUIRE(*addr == 42);
+
+ REQUIRE(!!mapping);
+ mapping.unmap();
+ REQUIRE(!mapping);
+ mapping.unmap(); // second unmap is okay
+ }
+
+ SECTION("memory mapping of zero length should work") {
+ osmium::util::MemoryMapping mapping(0);
+ REQUIRE(mapping.get_addr() != nullptr);
+
+ REQUIRE(mapping.size() == osmium::util::get_pagesize());
+
+ REQUIRE(!!mapping);
+ mapping.unmap();
+ REQUIRE(!mapping);
+ }
+
+ SECTION("memory mapping a huge area should fail") {
+ REQUIRE_THROWS_AS(osmium::util::MemoryMapping mapping(huge),
+ std::system_error);
+ }
+
+ SECTION("moving a memory mapping should work") {
+ osmium::util::MemoryMapping mapping1(1000);
+ int* addr1 = mapping1.get_addr<int>();
+ *addr1 = 42;
+
+ REQUIRE(!!mapping1);
+ osmium::util::MemoryMapping mapping2(std::move(mapping1));
+ REQUIRE(!!mapping2);
+ REQUIRE(!mapping1);
+ mapping1.unmap();
+
+ int* addr2 = mapping2.get_addr<int>();
+ REQUIRE(*addr2 == 42);
+
+ mapping2.unmap();
+ REQUIRE(!mapping2);
+ }
+
+ SECTION("move assignment should work") {
+ osmium::util::MemoryMapping mapping1(1000);
+ osmium::util::MemoryMapping mapping2(1000);
+
+ REQUIRE(!!mapping1);
+ REQUIRE(!!mapping2);
+
+ int* addr1 = mapping1.get_addr<int>();
+ *addr1 = 42;
+
+ mapping2 = std::move(mapping1);
+ REQUIRE(!!mapping2);
+ REQUIRE(!mapping1);
+
+ int* addr2 = mapping2.get_addr<int>();
+ REQUIRE(*addr2 == 42);
+
+ mapping2.unmap();
+ REQUIRE(!mapping2);
+ }
+
+#ifdef __linux__
+ SECTION("remapping to larger size should work") {
+ osmium::util::MemoryMapping mapping(1000);
+ REQUIRE(mapping.size() >= 1000);
+
+ size_t size1 = mapping.size();
+
+ int* addr1 = mapping.get_addr<int>();
+ *addr1 = 42;
+
+ mapping.resize(8000);
+ REQUIRE(mapping.size() > size1);
+
+ int* addr2 = mapping.get_addr<int>();
+ REQUIRE(*addr2 == 42);
+ }
+
+ SECTION("remapping to smaller size should work") {
+ osmium::util::MemoryMapping mapping(8000);
+ REQUIRE(mapping.size() >= 1000);
+
+ size_t size1 = mapping.size();
+
+ int* addr1 = mapping.get_addr<int>();
+ *addr1 = 42;
+
+ mapping.resize(500);
+ REQUIRE(mapping.size() < size1);
+
+ int* addr2 = mapping.get_addr<int>();
+ REQUIRE(*addr2 == 42);
+ }
+#endif
+
+}
+
+TEST_CASE("file-based mapping") {
+
+ SECTION("writing to a mapped file should work") {
+ char filename[] = "test_mmap_write_XXXXXX";
+ const int fd = mkstemp(filename);
+ REQUIRE(fd > 0);
+
+ osmium::util::resize_file(fd, 100);
+
+ {
+ osmium::util::MemoryMapping mapping(100, true, fd);
+ REQUIRE(mapping.writable());
+
+ REQUIRE(!!mapping);
+ REQUIRE(mapping.size() >= 100);
+
+ *mapping.get_addr<int>() = 1234;
+
+ mapping.unmap();
+ }
+
+ REQUIRE(osmium::util::file_size(fd) == 100);
+
+ {
+ osmium::util::MemoryMapping mapping(100, false, fd);
+ REQUIRE(!mapping.writable());
+
+ REQUIRE(!!mapping);
+ REQUIRE(mapping.size() >= 100);
+ REQUIRE(*mapping.get_addr<int>() == 1234);
+
+ mapping.unmap();
+ }
+
+ REQUIRE(0 == close(fd));
+ REQUIRE(0 == unlink(filename));
+ }
+
+ SECTION("remapping to larger size should work") {
+ char filename[] = "test_mmap_grow_XXXXXX";
+ const int fd = mkstemp(filename);
+ REQUIRE(fd > 0);
+
+ osmium::util::MemoryMapping mapping(100, true, fd);
+ REQUIRE(mapping.size() >= 100);
+ size_t size1 = mapping.size();
+
+ int* addr1 = mapping.get_addr<int>();
+ *addr1 = 42;
+
+ mapping.resize(8000);
+ REQUIRE(mapping.size() >= 8000);
+ REQUIRE(mapping.size() > size1);
+
+ int* addr2 = mapping.get_addr<int>();
+ REQUIRE(*addr2 == 42);
+
+ mapping.unmap();
+
+ REQUIRE(0 == close(fd));
+ REQUIRE(0 == unlink(filename));
+ }
+
+ SECTION("remapping to smaller size should work") {
+ char filename[] = "test_mmap_shrink_XXXXXX";
+ const int fd = mkstemp(filename);
+ REQUIRE(fd > 0);
+
+ {
+ osmium::util::MemoryMapping mapping(8000, true, fd);
+ REQUIRE(mapping.size() >= 8000);
+ size_t size1 = mapping.size();
+
+ int* addr1 = mapping.get_addr<int>();
+ *addr1 = 42;
+
+ mapping.resize(50);
+ REQUIRE(mapping.size() >= 50);
+ REQUIRE(mapping.size() < size1);
+
+ int* addr2 = mapping.get_addr<int>();
+ REQUIRE(*addr2 == 42);
+ }
+
+ REQUIRE(0 == close(fd));
+ REQUIRE(0 == unlink(filename));
+ }
+}
+
+TEST_CASE("typed anonymous mapping") {
+
+ SECTION("simple memory mapping should work") {
+ osmium::util::TypedMemoryMapping<uint32_t> mapping(1000);
+ volatile uint32_t* addr = mapping.begin();
+
+ REQUIRE(mapping.writable());
+
+ *addr = 42;
+ REQUIRE(*addr == 42);
+
+ REQUIRE(!!mapping);
+ mapping.unmap();
+ REQUIRE(!mapping);
+ mapping.unmap(); // second unmap is okay
+ }
+
+ SECTION("memory mapping a huge area should fail") {
+ REQUIRE_THROWS_AS(osmium::util::TypedMemoryMapping<uint32_t> mapping(huge),
+ std::system_error);
+ }
+
+ SECTION("moving a memory mapping should work") {
+ osmium::util::TypedMemoryMapping<uint32_t> mapping1(1000);
+ uint32_t* addr1 = mapping1.begin();
+ *addr1 = 42;
+
+ REQUIRE(!!mapping1);
+ osmium::util::TypedMemoryMapping<uint32_t> mapping2(std::move(mapping1));
+ REQUIRE(!!mapping2);
+ REQUIRE(!mapping1);
+ mapping1.unmap();
+
+ auto addr2 = mapping2.begin();
+ REQUIRE(*addr2 == 42);
+
+ mapping2.unmap();
+ REQUIRE(!mapping2);
+ }
+
+ SECTION("move assignment should work") {
+ osmium::util::TypedMemoryMapping<uint32_t> mapping1(1000);
+ osmium::util::TypedMemoryMapping<uint32_t> mapping2(1000);
+
+ REQUIRE(!!mapping1);
+ REQUIRE(!!mapping2);
+
+ auto addr1 = mapping1.begin();
+ *addr1 = 42;
+
+ mapping2 = std::move(mapping1);
+ REQUIRE(!!mapping2);
+ REQUIRE(!mapping1);
+
+ auto addr2 = mapping2.begin();
+ REQUIRE(*addr2 == 42);
+
+ mapping2.unmap();
+ REQUIRE(!mapping2);
+ }
+
+#ifdef __linux__
+ SECTION("remapping to larger size should work") {
+ osmium::util::TypedMemoryMapping<uint32_t> mapping(1000);
+ REQUIRE(mapping.size() >= 1000);
+
+ auto addr1 = mapping.begin();
+ *addr1 = 42;
+
+ mapping.resize(8000);
+
+ auto addr2 = mapping.begin();
+ REQUIRE(*addr2 == 42);
+ }
+
+ SECTION("remapping to smaller size should work") {
+ osmium::util::TypedMemoryMapping<uint32_t> mapping(8000);
+ REQUIRE(mapping.size() >= 8000);
+
+ auto addr1 = mapping.begin();
+ *addr1 = 42;
+
+ mapping.resize(500);
+
+ auto addr2 = mapping.begin();
+ REQUIRE(*addr2 == 42);
+ }
+#endif
+
+}
+
+TEST_CASE("typed file-based mapping") {
+
+ SECTION("writing to a mapped file should work") {
+ char filename[] = "test_mmap_file_size_XXXXXX";
+ const int fd = mkstemp(filename);
+ REQUIRE(fd > 0);
+
+ osmium::util::resize_file(fd, 100);
+
+ {
+ osmium::util::TypedMemoryMapping<uint32_t> mapping(100, true, fd);
+ REQUIRE(mapping.writable());
+
+ REQUIRE(!!mapping);
+ REQUIRE(mapping.size() >= 100);
+
+ *mapping.begin() = 1234;
+
+ mapping.unmap();
+ }
+
+ {
+ osmium::util::TypedMemoryMapping<uint32_t> mapping(100, false, fd);
+ REQUIRE(!mapping.writable());
+
+ REQUIRE(!!mapping);
+ REQUIRE(mapping.size() >= 100);
+ REQUIRE(*mapping.begin() == 1234);
+
+ mapping.unmap();
+ }
+
+ REQUIRE(0 == close(fd));
+ REQUIRE(0 == unlink(filename));
+ }
+
+}
+
+TEST_CASE("anonymous memory mapping class") {
+
+ SECTION("simple memory mapping should work") {
+ osmium::util::AnonymousMemoryMapping mapping(1000);
+ REQUIRE(mapping.get_addr() != nullptr);
+
+ volatile int* addr = mapping.get_addr<int>();
+
+ REQUIRE(mapping.writable());
+
+ *addr = 42;
+ REQUIRE(*addr == 42);
+
+ REQUIRE(!!mapping);
+ mapping.unmap();
+ REQUIRE(!mapping);
+ mapping.unmap(); // second unmap is okay
+ }
+
+#ifdef __linux__
+ SECTION("remapping to larger size should work") {
+ osmium::util::AnonymousMemoryMapping mapping(1000);
+ REQUIRE(mapping.size() >= 1000);
+
+ int* addr1 = mapping.get_addr<int>();
+ *addr1 = 42;
+
+ mapping.resize(2000);
+
+ int* addr2 = mapping.get_addr<int>();
+ REQUIRE(*addr2 == 42);
+ }
+
+ SECTION("remapping to smaller size should work") {
+ osmium::util::AnonymousMemoryMapping mapping(2000);
+ REQUIRE(mapping.size() >= 2000);
+
+ int* addr1 = mapping.get_addr<int>();
+ *addr1 = 42;
+
+ mapping.resize(500);
+
+ int* addr2 = mapping.get_addr<int>();
+ REQUIRE(*addr2 == 42);
+ }
+#endif
+
+}
+
diff --git a/test/t/util/test_minmax.cpp b/test/t/util/test_minmax.cpp
new file mode 100644
index 0000000..8b40f85
--- /dev/null
+++ b/test/t/util/test_minmax.cpp
@@ -0,0 +1,68 @@
+#include "catch.hpp"
+
+#include <osmium/util/minmax.hpp>
+#include <osmium/osm/timestamp.hpp>
+
+TEST_CASE("minmax numeric") {
+
+ SECTION("min") {
+ osmium::min_op<int> x;
+ REQUIRE(x() == std::numeric_limits<int>::max());
+
+ x.update(17);
+ REQUIRE(x() == 17);
+
+ x.update(10);
+ REQUIRE(x() == 10);
+
+ x.update(22);
+ REQUIRE(x() == 10);
+ }
+
+ SECTION("max") {
+ osmium::max_op<uint32_t> x;
+ REQUIRE(x() == 0);
+
+ x.update(17);
+ REQUIRE(x() == 17);
+
+ x.update(10);
+ REQUIRE(x() == 17);
+
+ x.update(22);
+ REQUIRE(x() == 22);
+ }
+
+}
+
+TEST_CASE("minmax timestamp") {
+
+ SECTION("min") {
+ osmium::min_op<osmium::Timestamp> x;
+
+ x.update(osmium::Timestamp("2010-01-01T00:00:00Z"));
+ REQUIRE(x().to_iso() == "2010-01-01T00:00:00Z");
+
+ x.update(osmium::Timestamp("2015-01-01T00:00:00Z"));
+ REQUIRE(x().to_iso() == "2010-01-01T00:00:00Z");
+
+ x.update(osmium::Timestamp("2000-01-01T00:00:00Z"));
+ REQUIRE(x().to_iso() == "2000-01-01T00:00:00Z");
+ }
+
+ SECTION("max") {
+ osmium::max_op<osmium::Timestamp> x;
+
+ x.update(osmium::Timestamp("2010-01-01T00:00:00Z"));
+ REQUIRE(x().to_iso() == "2010-01-01T00:00:00Z");
+
+ x.update(osmium::Timestamp("2015-01-01T00:00:00Z"));
+ REQUIRE(x().to_iso() == "2015-01-01T00:00:00Z");
+
+ x.update(osmium::Timestamp("2000-01-01T00:00:00Z"));
+ REQUIRE(x().to_iso() == "2015-01-01T00:00:00Z");
+
+ }
+
+}
+
diff --git a/test/t/util/test_options.cpp b/test/t/util/test_options.cpp
index 203b9db..969f201 100644
--- a/test/t/util/test_options.cpp
+++ b/test/t/util/test_options.cpp
@@ -6,43 +6,43 @@
TEST_CASE("Options") {
-SECTION("set_simple") {
- osmium::util::Options o;
- o.set("foo", "bar");
- REQUIRE("bar" == o.get("foo"));
- REQUIRE("" == o.get("empty"));
- REQUIRE("default" == o.get("empty", "default"));
- REQUIRE(!o.is_true("foo"));
- REQUIRE(!o.is_true("empty"));
- REQUIRE(1 == o.size());
-}
-
-SECTION("set_from_bool") {
- osmium::util::Options o;
- o.set("t", true);
- o.set("f", false);
- REQUIRE("true" == o.get("t"));
- REQUIRE("false" == o.get("f"));
- REQUIRE("" == o.get("empty"));
- REQUIRE(o.is_true("t"));
- REQUIRE(!o.is_true("f"));
- REQUIRE(2 == o.size());
-}
-
-SECTION("set_from_single_string_with_equals") {
- osmium::util::Options o;
- o.set("foo=bar");
- REQUIRE("bar" == o.get("foo"));
- REQUIRE(1 == o.size());
-}
-
-SECTION("set_from_single_string_without_equals") {
- osmium::util::Options o;
- o.set("foo");
- REQUIRE("true" == o.get("foo"));
- REQUIRE(o.is_true("foo"));
- REQUIRE(1 == o.size());
-}
+ SECTION("set_simple") {
+ osmium::util::Options o;
+ o.set("foo", "bar");
+ REQUIRE("bar" == o.get("foo"));
+ REQUIRE("" == o.get("empty"));
+ REQUIRE("default" == o.get("empty", "default"));
+ REQUIRE(!o.is_true("foo"));
+ REQUIRE(!o.is_true("empty"));
+ REQUIRE(1 == o.size());
+ }
+
+ SECTION("set_from_bool") {
+ osmium::util::Options o;
+ o.set("t", true);
+ o.set("f", false);
+ REQUIRE("true" == o.get("t"));
+ REQUIRE("false" == o.get("f"));
+ REQUIRE("" == o.get("empty"));
+ REQUIRE(o.is_true("t"));
+ REQUIRE(!o.is_true("f"));
+ REQUIRE(2 == o.size());
+ }
+
+ SECTION("set_from_single_string_with_equals") {
+ osmium::util::Options o;
+ o.set("foo=bar");
+ REQUIRE("bar" == o.get("foo"));
+ REQUIRE(1 == o.size());
+ }
+
+ SECTION("set_from_single_string_without_equals") {
+ osmium::util::Options o;
+ o.set("foo");
+ REQUIRE("true" == o.get("foo"));
+ REQUIRE(o.is_true("foo"));
+ REQUIRE(1 == o.size());
+ }
}
diff --git a/test/t/util/test_string.cpp b/test/t/util/test_string.cpp
index c7b75cf..0960afe 100644
--- a/test/t/util/test_string.cpp
+++ b/test/t/util/test_string.cpp
@@ -4,54 +4,65 @@
TEST_CASE("split_string") {
-SECTION("split_string string") {
- std::string str { "foo,baramba,baz" };
- std::vector<std::string> result = {"foo", "baramba", "baz"};
-
- REQUIRE(result == osmium::split_string(str, ','));
-}
-
-SECTION("split_string string without sep") {
- std::string str { "foo" };
- std::vector<std::string> result = {"foo"};
-
- REQUIRE(result == osmium::split_string(str, ','));
-}
-
-SECTION("split_string string with empty at end") {
- std::string str { "foo,bar," };
- std::vector<std::string> result = {"foo", "bar", ""};
-
- REQUIRE(result == osmium::split_string(str, ','));
-}
-
-SECTION("split_string string with empty in middle") {
- std::string str { "foo,,bar" };
- std::vector<std::string> result = {"foo", "", "bar"};
-
- REQUIRE(result == osmium::split_string(str, ','));
-}
-
-SECTION("split_string string with empty at start") {
- std::string str { ",bar,baz" };
- std::vector<std::string> result = {"", "bar", "baz"};
-
- REQUIRE(result == osmium::split_string(str, ','));
-}
-
-SECTION("split_string sep") {
- std::string str { "," };
- std::vector<std::string> result = {"", ""};
-
- REQUIRE(result == osmium::split_string(str, ','));
-}
-
-SECTION("split_string empty string") {
- std::string str { "" };
- std::vector<std::string> result;
-
- REQUIRE(result == osmium::split_string(str, ','));
-}
+ SECTION("split_string string") {
+ std::string str { "foo,baramba,baz" };
+ std::vector<std::string> result = {"foo", "baramba", "baz"};
+
+ REQUIRE(result == osmium::split_string(str, ','));
+ REQUIRE(result == osmium::split_string(str, ',', true));
+ }
+
+ SECTION("split_string string without sep") {
+ std::string str { "foo" };
+ std::vector<std::string> result = {"foo"};
+
+ REQUIRE(result == osmium::split_string(str, ','));
+ REQUIRE(result == osmium::split_string(str, ',', true));
+ }
+
+ SECTION("split_string string with empty at end") {
+ std::string str { "foo,bar," };
+ std::vector<std::string> result = {"foo", "bar", ""};
+ std::vector<std::string> resultc = {"foo", "bar"};
+
+ REQUIRE(result == osmium::split_string(str, ','));
+ REQUIRE(resultc == osmium::split_string(str, ',', true));
+ }
+
+ SECTION("split_string string with empty in middle") {
+ std::string str { "foo,,bar" };
+ std::vector<std::string> result = {"foo", "", "bar"};
+ std::vector<std::string> resultc = {"foo", "bar"};
+
+ REQUIRE(result == osmium::split_string(str, ','));
+ REQUIRE(resultc == osmium::split_string(str, ',', true));
+ }
+
+ SECTION("split_string string with empty at start") {
+ std::string str { ",bar,baz" };
+ std::vector<std::string> result = {"", "bar", "baz"};
+ std::vector<std::string> resultc = {"bar", "baz"};
+
+ REQUIRE(result == osmium::split_string(str, ','));
+ REQUIRE(resultc == osmium::split_string(str, ',', true));
+ }
+
+ SECTION("split_string sep") {
+ std::string str { "," };
+ std::vector<std::string> result = {"", ""};
+ std::vector<std::string> resultc;
+
+ REQUIRE(result == osmium::split_string(str, ','));
+ REQUIRE(resultc == osmium::split_string(str, ',', true));
+ }
+
+ SECTION("split_string empty string") {
+ std::string str { "" };
+ std::vector<std::string> result;
+
+ REQUIRE(result == osmium::split_string(str, ','));
+ REQUIRE(result == osmium::split_string(str, ',', true));
+ }
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/libosmium.git
More information about the Pkg-grass-devel
mailing list